encode Shift_JIS ;
import Graphics ;
import Graphics3D ;
import GUI ;
import Math ;
void main
( string args
[] ){
hide() ;
TITLE = "多面体影絵(1)" ;
int panelh = 60
, panelw = 0 ;
int winw = 256*2.4
, winh = 256*2.4
, c = 0 ;
int bgcolor
[ ] = Color
( c
, c
, c
) ;
Set3DGraphics
( winw
, winh
, -1000
, -1000
, panelw
, panelh
, bgcolor
) ;
SetLights
() ;
SetCoordinates
() ;
SetElements
() ;
PrepareStage
( panelw
, panelh
) ;
PrepareMovie
() ;
PrintBasicInfo
() ;
WINDOW_POSITION_X = 200 ;
setComponentLocation( MAIN_WINDOW
, WINDOW_POSITION_X
, 0
) ;
while ( KEEP_LOOP
){
if ( KEEP_MOTION
) {
ForwardMotion
() ; // アニメーション
if ( INCREASE_T
) {
T += STEP ;
if ( T > END_T
) {
T = END_T ;
}
} else {
T -= STEP ;
if ( T < START_T
) {
T = START_T ;
}
}
}
if ( CREATE_GUI
) {
CreateOperationPanel
();
CREATE_GUI = false ;
GUI_CREATED = true ;
KEEP_MOTION = false ;
T = START_T ;
}
PaintGraphics
( 1000 / FPS
);
if ( SAVE_A_PICTURE
) {
SaveImage
( "PNG"
) ;
if ( PICTURE_NUMBER > PICTURE_END_NUMBER
) {
ExitLoopOverImageLimit
() ;
}
}
if ( COUNT > COUNT_LIMIT
) {
ExitLoopOverCountLimit
() ;
}
COUNT ++ ;
}
exit();
}
// import
// LIB000
/* NUMERIC */
double o = 0.0
, a = 1.0
, d = 10.0 ;
double Slv = 2*
cos( PI/4
) , ISlv =
cos( PI/4
) ;
double Gld = 2*
cos( PI/5
) , IGld = Gld - 1.0 ;
double Plt = 2*
cos( PI/6
) , IPlt =
tan( PI/6
) ;
int O =
newVector( o
, o
, o
) ;
double l = 1.0 ; // 長さに用いる単位
int N ;
// symmetry
int S24 = 24
, S12 = 12
, S8 = 8
, S6 = 6
, S5 = 5
, S4 = 4
, S3 = 3
, S2 = 2 ;
int R3 = 3
, R4 = 4
, R5 = 5
, R6 = 6
, R8 = 8 ;
// LIB012
/* 3DGRAPHICS */
string TITLE ;
int MAIN_GRAPHICS
, MAIN_WINDOW
, MAIN_DISPLAY_LABEL
, RENDERER ;
int WIDTH = 0
, HEIGHT = 0
, WINDOW_POSITION_X = 0 ;
void Set3DGraphics
(
int w
, int h
, int x
, int y
, int leftspace
, int lowspace
, int bgcolor
[ ]
) {
WIDTH = w + leftspace ;
HEIGHT = h + lowspace;
WINDOW_POSITION_X = x ;
int bgred = bgcolor
[0
] ;
int bggreen = bgcolor
[1
] ;
int bgblue = bgcolor
[2
] ;
int framewidth_x = 14 ;
int framewidth_y = 39 ;
int bgalpha = 255 ;
MAIN_GRAPHICS =
newGraphics();
RENDERER =
newGraphics3DRenderer( w
, h
, MAIN_GRAPHICS
) ;
MAIN_WINDOW =
newWindow(
WINDOW_POSITION_X
, y
, WIDTH + framewidth_x
, HEIGHT + framewidth_y
, TITLE
) ;
MAIN_DISPLAY_LABEL =
newGraphicsLabel(
leftspace
, 0
, w
, h
, MAIN_GRAPHICS
) ;
addComponent( MAIN_DISPLAY_LABEL
, MAIN_WINDOW
);
setGraphics3DDefaultEventHandler( RENDERER
, MAIN_DISPLAY_LABEL
);
setGraphics3DColor( RENDERER
, bgred
, bggreen
, bgblue
, bgalpha
);
}
void PrepareStage
( int leftspace
, int lowspace
) {
setGraphics3DCenter(
RENDERER
, ( WIDTH - leftspace
) / 2
, ( HEIGHT - lowspace
) / 2
);
setGraphics3DDistance( RENDERER
, GRAPHIC_DISTANCE
);
setGraphics3DMagnification( RENDERER
, GRAPHIC_MAGNIFICATION
);
setGraphics3DClipFront( RENDERER
, o
);
setGraphics3DClipBack( RENDERER
, -1000.0
);
int w =
getWorldCoordinate( RENDERER
) ;
setCoordinateOrigin( w
, o
, o
, o
);
setCoordinateEulerAngle( w
, o
, o
, o
);
setCameraOrigin( w
, o
, o
, CAMERA_ORIGIN_Z
);
setCameraEulerAngle( w
, o
, o
, o
);
}
// LIB025_PLAYER_10 ;
/* EVENTHANDLERS */
void onWindowClose( int id
) {
KEEP_LOOP = false ;
}
int ACCEL= 1 ; // 倍速再生
void onKeyDown( int id
, string key
){
if ( GUI_CREATED
) {
if ( key == "SPACE"
) {
} else if ( key == "P"
) {
if ( KEEP_MOTION
) {
KEEP_MOTION = false ;
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][0
] ) ;
setComponentText( TEXT_LABEL
[0
], (string
)( (int
)( T - START_T
) ) ) ;
} else {
KEEP_MOTION = true ;
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][1
] ) ;
if ( INCREASE_T
) {
if ( T == END_T
) {
T = START_T ;
}
} else {
if ( T == START_T
) {
T = END_T ;
}
}
}
} else if ( key == "R"
) {
if ( INCREASE_T
) {
INCREASE_T = false ;
setComponentColor( TEXT_LABEL
[0
], 0
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
setComponentColor( TEXT_LABEL
[1
], 0
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
} else {
INCREASE_T = true ;
setComponentColor( TEXT_LABEL
[0
], 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
setComponentColor( TEXT_LABEL
[1
], 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
}
RefreshIndicator
() ;
} else if ( key == "S"
) {
if ( SPIN
) {
SPIN = false ;
} else {
SPIN = true ;
}
setComponentState( CHECK_BOX
[1
], SPIN
) ;
} else if ( key == "A"
) {
int formeri = ACCEL + 2 ;
ACCEL++ ;
if ( ACCEL > 4
) {
ACCEL = 0 ;
}
int n = ACCEL + 2 ;
STEP = TIME_FLOW / FPS *
( 2^
( ACCEL - 1
) ) ;
int c1
[ ] =
{ 30
, 30
, 30
, 255
, 80
, 80
, 255
, 80
} ;
int c2
[ ] =
{ 200
, 10
, 10
, 255
, 120
, 120
, 255
, 80
} ;
setComponentColor(
BUTTON
[formeri
],
c1
[0
], c1
[1
], c1
[2
], c1
[3
], c1
[4
], c1
[5
], c1
[6
], c1
[7
]
) ;
setComponentColor(
BUTTON
[n
],
c2
[0
], c2
[1
], c2
[2
], c2
[3
], c2
[4
], c2
[5
], c2
[6
], c2
[7
]
) ;
RefreshIndicator
() ;
} else
if ( key == "C"
) {
alert( " このキーは使用できません "
) ;
}
}
}
// operation panel
int BUTTON
[ 2+5
], N =
length( BUTTON
) ;
string BUTTON_TEXT
[ N
][ 2
] ;
int TEXT_LABEL
[ 6
] ;
int INDICATOR
[ 1
] ; // text label 要素数は WIDTH に依存するので、後で確定する
int INDIW ; // inidicator の幅
onMouseLeftDrag で必要なのでワールド変数
int CHECK_BOX
[ 2
] ;
void CreateOperationPanel
() {
int windowframew = 8 ;
int compareasidespace = 2 ;
int componentspace = 12 ;
int indiy =
getComponentSize( MAIN_DISPLAY_LABEL
)[1
] + 2 ;
// button
int labelh = 12 ;
int buttonx = 3*compareasidespace
, button0w = 115
, buttonh = 32 ;
int buttony = indiy + labelh + 4 ;
BUTTON_TEXT
[0
][0
] = " 実 行(P)" ;
BUTTON_TEXT
[0
][1
] = " 停 止(P)" ;
BUTTON
[0
] =
newButton(
3*compareasidespace
,
buttony
,
button0w
, buttonh
, BUTTON_TEXT
[0
][0
]
) ;
int button1w = 75 ;
int labelw = 26
, charw = 16
, labelx = buttonx + button0w + componentspace;
BUTTON_TEXT
[1
][0
] = "反転
(R
)" ;
BUTTON
[1
] =
newButton(
labelx + 2*labelw + 3*charw + componentspace
,
buttony + 1*buttonh/8
,
button1w
, 7*buttonh/8
, BUTTON_TEXT
[1
][0
]
) ;
setComponentFontBold( BUTTON
[1
], false
) ;
BUTTON_TEXT
[2
][0
] = "0.5" ;
BUTTON_TEXT
[3
][0
] = "1.0" ;
BUTTON_TEXT
[4
][0
] = "2.0" ;
BUTTON_TEXT
[5
][0
] = "4.0" ;
BUTTON_TEXT
[6
][0
] = "8.0" ;
int button2w = 51 ;
int c1
[ ] =
{ 200
, 10
, 10
, 255
, 120
, 120
, 255
, 80
} ;
int c2
[ ] =
{ 30
, 30
, 30
, 255
, 80
, 80
, 255
, 80
} ;
for ( int i=2; i<
length( BUTTON
); i++
) {
BUTTON
[i
] =
newButton(
labelx + 2*labelw + 4*charw + button1w + componentspace + button2w*
( i - 2
),
buttony + buttonh/2
,
button2w
, 1*buttonh/2
, BUTTON_TEXT
[i
][0
]
) ;
setComponentFontBold( BUTTON
[i
], true
) ;
if ( i == 3
) {
setComponentColor(
BUTTON
[i
],
c1
[0
], c1
[1
], c1
[2
], c1
[3
], c1
[4
], c1
[5
], c1
[6
], c1
[7
]
) ;
} else {
setComponentColor(
BUTTON
[i
],
c2
[0
], c2
[1
], c2
[2
], c2
[3
], c2
[4
], c2
[5
], c2
[6
], c2
[7
]
) ;
}
}
// text label TEXT_LABEL
[5
] はボタンとして使用
int labely = buttony ;
label h = buttonh/2 ;
TEXT_LABEL
[0
] =
newTextLabel(
labelx
,
labely
,
labelw
, labelh
, "0 "
) ;
setComponentFontBold( TEXT_LABEL
[0
], true
) ;
setComponentColor( TEXT_LABEL
[0
], 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
TEXT_LABEL
[1
] =
newTextLabel(
labelx + labelw
,
labely
,
charw
, labelh
, "秒"
) ;
setComponentFontBold( TEXT_LABEL
[1
], false
) ;
setComponentColor( TEXT_LABEL
[1
], 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
TEXT_LABEL
[2
] =
newTextLabel(
labelx + labelw + charw
,
labely
,
charw
, labelh
, "/"
) ;
string totaltimedisplay =
(string
)( (int
)( END_T - START_T
) ) ;
TEXT_LABEL
[3
] =
newTextLabel(
labelx + labelw + 2*charw
,
labely
,
labelw
, labelh
, totaltimedisplay
) ;
setComponentFontBold( TEXT_LABEL
[3
], false
) ;
TEXT_LABEL
[4
] =
newTextLabel(
labelx + 2*labelw + 2*charw
,
labely
,
charw
, labelh
, "秒"
) ;
setComponentFontBold( TEXT_LABEL
[4
], false
) ;
int label5x = labelx + 2*labelw + 4*charw + button1w + componentspace ;
int label5w = 2*button2w ;
TEXT_LABEL
[5
] =
newButton( // ボタンであること注意
label5x
,
buttony
,
label5w + 1
, buttonh/2
, "倍速
(A
)"
) ;
setComponentFontBold( TEXT_LABEL
[5
], false
) ;
setComponentColor(
TEXT_LABEL
[5
],
0
, 0
, 0
, c1
[3
], c1
[4
], c1
[5
], c1
[6
], c1
[7
]
) ;
// check box
CHECK_BOX
[0
] =
newCheckBox(
buttonx + button0w + componentspace - 5
,
labely + buttonh/2
,
90
, buttonh/2
, ""
, false
) ;
) ;
setComponentFontBold( CHECK_BOX
[0
], false
) ;
CHECK_BOX
[1
] =
newCheckBox(
label5x + label5w + componentspace - 3
,
buttony - 2
,
180
, buttonh/2
, "倍速に独立な定速回転
(S
)"
, SPIN
) ;
) ;
setComponentFontBold( CHECK_BOX
[1
], false
) ;
// indicator
int indiw = 14 ;
INDIW = indiw ;
int dummy
[ (int
)( ( WIDTH - 10
) / indiw
) ] ;
INDICATOR = dummy ; // WIDTH と indiw で要素数を決める
for ( int i=0; i<
length( INDICATOR
); i++
) {
INDICATOR
[i
] =
newTextLabel(
2*compareasidespace + indiw * i
,
indiy
,
indiw
, labelh
, "=="
) ;
setComponentFontBold( INDICATOR
[i
], true
) ;
setComponentColor( INDICATOR
[i
],
160
, 140
, 160
, 255
, 0
, 0
, 0
, 0
) ;
}
// operation panel
for ( int i=0; i<
length( BUTTON
); i++
) {
addComponent( BUTTON
[i
], MAIN_WINDOW
) ;
}
for ( int i=0; i<
length( TEXT_LABEL
); i++
) {
addComponent( TEXT_LABEL
[i
], MAIN_WINDOW
) ;
}
for ( int i=0; i<
length( INDICATOR
); i++
) {
addComponent( INDICATOR
[i
], MAIN_WINDOW
) ;
}
for ( int i=0; i<
length( CHECK_BOX
); i++
) {
addComponent( CHECK_BOX
[i
], MAIN_WINDOW
) ;
}
RefreshIndicator
() ;
}
void onButtonClick( int id
){
if ( GUI_CREATED
) {
if ( id != TEXT_LABEL
[5
] ) {
if ( id == BUTTON
[0
] ) {
if ( KEEP_MOTION
) {
KEEP_MOTION = false ;
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][0
] ) ;
setComponentText( TEXT_LABEL
[0
], (string
)( (int
)( T - START_T
) ) ) ;
} else {
KEEP_MOTION = true ;
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][1
] ) ;
if ( INCREASE_T
) {
if ( T == END_T
) {
T = START_T ;
}
} else {
if ( T == START_T
) {
T = END_T ;
}
}
}
} else if ( id == BUTTON
[1
] ) {
if ( INCREASE_T
) {
INCREASE_T = false ;
setComponentColor(
TEXT_LABEL
[0
], 0
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
setComponentColor(
TEXT_LABEL
[1
], 0
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
} else {
INCREASE_T = true ;
setComponentColor(
TEXT_LABEL
[0
], 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
setComponentColor(
TEXT_LABEL
[1
], 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
}
RefreshIndicator
() ;
} else {
int formeri = ACCEL + 2
, n = 2 ;
while ( id != BUTTON
[n
] ) {
n++ ;
}
ACCEL = n - 2 ;
STEP = TIME_FLOW / FPS *
( 2^
( ACCEL - 1
) ) ;
int c1
[ ] =
{ 30
, 30
, 30
, 255
, 80
, 80
, 255
, 80
} ;
int c2
[ ] =
{ 200
, 10
, 10
, 255
, 120
, 120
, 255
, 80
} ;
setComponentColor(
BUTTON
[formeri
],
c1
[0
], c1
[1
], c1
[2
], c1
[3
], c1
[4
], c1
[5
], c1
[6
], c1
[7
]
) ;
setComponentColor(
BUTTON
[n
],
c2
[0
], c2
[1
], c2
[2
], c2
[3
], c2
[4
], c2
[5
], c2
[6
], c2
[7
]
) ;
RefreshIndicator
() ;
}
} else { // TEXT_LABEL
[5
]
int formeri = ACCEL + 2 ;
ACCEL++ ;
if ( ACCEL > 4
) {
ACCEL = 0 ;
}
int n = ACCEL + 2 ;
STEP = TIME_FLOW / FPS *
( 2^
( ACCEL - 1
) ) ;
int c1
[ ] =
{ 30
, 30
, 30
, 255
, 80
, 80
, 255
, 80
} ;
int c2
[ ] =
{ 200
, 10
, 10
, 255
, 120
, 120
, 255
, 80
} ;
setComponentColor(
BUTTON
[formeri
],
c1
[0
], c1
[1
], c1
[2
], c1
[3
], c1
[4
], c1
[5
], c1
[6
], c1
[7
]
) ;
setComponentColor(
BUTTON
[n
],
c2
[0
], c2
[1
], c2
[2
], c2
[3
], c2
[4
], c2
[5
], c2
[6
], c2
[7
]
) ;
RefreshIndicator
() ;
}
}
}
void InitializeIndicator
() {
int n =
length( INDICATOR
) - 1 ;
int dispT = T - START_T ;
int cinc
[ 8
] =
{ 255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
} ;
int cdec
[ 8
] =
{ 0
, 0
, 255
, 255
, 0
, 0
, 0
, 0
} ;
int cind
[ 8
] =
{ 160
, 150
, 160
, 255
, 0
, 0
, 0
, 0
} ;
if ( INCREASE_T
) {
setComponentColor( TEXT_LABEL
[0
],
cinc
[0
], cinc
[1
], cinc
[2
], cinc
[3
], cinc
[4
], cinc
[5
], cinc
[6
], cinc
[7
]
) ;
setComponentColor( TEXT_LABEL
[1
],
cinc
[0
], cinc
[1
], cinc
[2
], cinc
[3
], cinc
[4
], cinc
[5
], cinc
[6
], cinc
[7
]
) ;
if ( T == START_T
) {
setComponentColor( INDICATOR
[0
],
cinc
[0
], cinc
[1
], cinc
[2
], cinc
[3
], cinc
[4
], cinc
[5
], cinc
[6
], cinc
[7
]
) ;
}
if ( T == END_T
) {
setComponentColor( INDICATOR
[n
],
cinc
[0
], cinc
[1
], cinc
[2
], cinc
[3
], cinc
[4
], cinc
[5
], cinc
[6
], cinc
[7
]
) ;
}
setComponentColor( INDICATOR
[n
],
cinc
[0
], cinc
[1
], cinc
[2
], cinc
[3
], cinc
[4
], cinc
[5
], cinc
[6
], cinc
[7
]
) ;
setComponentText( TEXT_LABEL
[0
], (string
)( dispT
) ) ;
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][0
] ) ;
if ( T == START_T
) {
setComponentText( INDICATOR
[0
], ">>"
) ;
} else if ( T == END_T
) {
setComponentText( INDICATOR
[n
], ">>"
) ;
}
if ( KEEP_MOTION
) {
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][1
] ) ;
}
} else {
setComponentColor( TEXT_LABEL
[0
],
cdec
[0
], cdec
[1
], cdec
[2
], cdec
[3
], cdec
[4
], cdec
[5
], cdec
[6
], cdec
[7
]
) ;
setComponentColor( TEXT_LABEL
[1
],
cdec
[0
], cdec
[1
], cdec
[2
], cdec
[3
], cdec
[4
], cdec
[5
], cdec
[6
], cdec
[7
]
) ;
if ( T == START_T
) {
setComponentColor( INDICATOR
[0
],
cdec
[0
], cdec
[1
], cdec
[2
], cdec
[3
], cdec
[4
], cdec
[5
], cdec
[6
], cdec
[7
]
) ;
}
if ( T == END_T
) {
setComponentColor( INDICATOR
[n
],
cdec
[0
], cdec
[1
], cdec
[2
], cdec
[3
], cdec
[4
], cdec
[5
], cdec
[6
], cdec
[7
]
) ;
}
setComponentText( TEXT_LABEL
[0
], "0 "
) ;
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][0
] ) ;
if ( T == START_T
) {
setComponentText( INDICATOR
[0
], "<<"
) ;
} else if ( T == END_T
) {
setComponentText( INDICATOR
[n
], "<<"
) ;
}
if ( KEEP_MOTION
) {
setComponentText( BUTTON
[0
], BUTTON_TEXT
[0
][1
] ) ;
}
}
for ( int i=1; i<n-1; i++
) {
setComponentColor( INDICATOR
[i
],
cind
[0
], cind
[1
], cind
[2
], cind
[3
], cind
[4
], cind
[5
], cind
[6
], cind
[7
]
) ;
setComponentText( INDICATOR
[i
], "=="
) ;
}
}
void RefreshIndicator
() {
double t =
( T - START_T
) /
( END_T - START_T
) ;
if ( t < o
) {
t = o ;
} else if ( t > a
) {
t = a ;
}
int n =
length( INDICATOR
) - 1 ;
int index = n * t ;
for ( int i=0; i<=n; i++
) {
if ( i == index
) {
if ( INCREASE_T
) {
setComponentColor( INDICATOR
[i
],
255
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
setComponentText( INDICATOR
[i
], ">>"
) ;
} else {
setComponentColor( INDICATOR
[i
],
0
, 0
, 255
, 255
, 0
, 0
, 0
, 0
) ;
setComponentText( INDICATOR
[i
], "<<"
) ;
}
} else {
setComponentColor( INDICATOR
[i
],
160
, 140
, 160
, 255
, 0
, 0
, 0
, 0
) ;
setComponentText( INDICATOR
[i
], "=="
) ;
}
}
}
void onMouseLeftClick( int id
, int x
, int y
, int count
){
if ( GUI_CREATED
) {
int n =
length( INDICATOR
) - 1 ;
for ( int i=0; i<
length( INDICATOR
); i++
) {
if ( id == INDICATOR
[i
] ) {
T = START_T +
( END_T - START_T
) * i / n ;
setComponentText(
TEXT_LABEL
[0
], (string
)( (int
)( T - START_T
) )
) ;
if ( !KEEP_MOTION
) {
Movie
( o
, true
) ;
}
RefreshIndicator
() ;
}
}
}
}
void onMouseLeftDrag( int id
, int x
, int y
, int count
){
if ( GUI_CREATED
) {
int n =
length( INDICATOR
) - 1
, nx ;
double u ;
for ( int i=0; i<
length( INDICATOR
); i++
) {
if ( id == INDICATOR
[i
] ) {
nx = INDIW * i + x ; // MAIN_WINDOW 左基準の座標値
u = a*nx /
( ( n + 1
) * INDIW
) ; // 規格化
if ( u < o
) {
u = o ;
} else if ( u > a
) {
u = a ;
}
T = START_T +
( END_T - START_T
) * u ;
setComponentText(
TEXT_LABEL
[0
], (string
)( (int
)( T - START_T
) )
) ;
if ( !KEEP_MOTION
) {
Movie
( o
, true
) ;
}
RefreshIndicator
() ;
}
}
}
}
void onCheckBoxClick( int id
, bool state
) {
if ( id == CHECK_BOX
[0
] ) {
alert( " このチェックボックスは使用できません "
) ;
} else {
if ( SPIN
) {
SPIN = false ;
} else {
SPIN = true ;
}
}
}
void PaintGraphics
( int sleeptime
) {
sleep( sleeptime
);
paintGraphics3D( RENDERER
);
paintComponent( MAIN_DISPLAY_LABEL
);
paintComponent( MAIN_WINDOW
);
}
void SaveImagePNG
( int picid
) {
int picnumber = 0 ;
PICTURE_NUMBER = PICTURE_NUMBER + 1 ;
picnumber = picid + PICTURE_NUMBER ;
exportGraphics(
MAIN_GRAPHICS
, "./movie/a" + picnumber + ".png"
, "PNG"
) ;
}
void SaveImageJPEG
( int picid
) {
int picnumber = 0 ;
PICTURE_NUMBER = PICTURE_NUMBER + 1 ;
picnumber = picid + PICTURE_NUMBER ;
exportGraphics(
MAIN_GRAPHICS
, "./movie/a" + picnumber + ".jpg"
, "JPEG"
) ;
}
void ExitLoopOverImageLimit
() {
alert(
"画像の保存が上限
( "
+ PICTURE_END_NUMBER
+ " 枚
) に達したため、CGアニメーションを終了します。"
);
KEEP_LOOP = false ;
}
void SaveImage
( string type
) {
if ( type == "PNG"
) {
if ( PICTURE_SAVED
) {
if ( PICTURE_ALERT
) {
PICTURE_ALERT = false ;
alert( PICTURE_NUMBER
+ " 枚目までで画像の保存を中止しました。"
) ;
}
SAVE_A_PICTURE = false ;
} else {
if ( PICTURE_ALERT
) {
PICTURE_ALERT = false ;
alert(
( PICTURE_NUMBER+1
) + " 枚目以降の画像を保存します。"
+ linefeed
() + "保存番号を入力して下さい"
) ;
string nin = choice
(
"1"
, "2"
, "3"
, "4"
, "5"
, "6"
, "7"
, "8"
, "9"
) ;
PICTURE_SAVE_ID = nin ;
}
SaveImagePNG
( PICTURE_SAVE_ID * 10000
) ;
}
}
}
void ExitLoopOverCountLimit
() {
show() ;
println( linefeed
()
+ linefeed
()
+ "****************************************************************"
+ linefeed
()
+ "*********** このプログラムは 10 秒後に自動終了します ***********"
+ linefeed
()
+ "****************************************************************"
) ;
print( "cout down ... "
) ;
for ( int i=0; i<10; i++
) {
print( ( 10 - i
) + "
, "
) ;
if ( i == 0
) {
beep( 1
) ;
}
sleep ( 1000
) ;
}
print( "0"
) ;
sleep( 1000
) ;
KEEP_LOOP = false ;
}
void PrintBasicInfo
() {
print( linefeed
()
+ " title " + TITLE + linefeed
()
+ linefeed
()
+ " movie " + linefeed
()
+ " start
time = " + START_T + " sec" + linefeed
()
+ " end
time = " + END_T + " sec" + linefeed
()
+ " running
time = " +
( END_T - START_T
) + " sec" + linefeed
()
+ " added
time = " +
( ADDED_T
) + " sec" + linefeed
()
+ " 2*PI rotation = " +
( ROT_N
) + " times" + linefeed
()
+ " number of frames = " +
(int
)( ( END_T - START_T
) / STEP
) + linefeed
()
+ " frames / 1sec = " + FPS + " /sec" + linefeed
()
+ " number of indexed states = " +
length( SX
) + linefeed
()
+ linefeed
()
+ " limit " + linefeed
()
+ " of image = " + PICTURE_END_NUMBER + linefeed
()
+ " of counter = " + COUNT_LIMIT + linefeed
()
) ;
}
// LIB030
/* FUNCTIONS */
// 等式評価
bool Equality
( double x1
, double x2
, double infinitesimal
) {
double dif = x1 - x2 ;
return abs( dif
) < infinitesimal ;
}
// permuation
int Permuation
( int n
[ ] ) {
}
// unit step function
double Step
( double x
) {
double value;
if ( x < 0.0
) {
value = 0.0 ;
} else {
value = 1.0 ;
}
return value ;
}
double Slope
( double x
, double x0
, double deltax
) {
double value;
if ( x < x0
) {
value = 0.0 ;
} else if ( x <
( x0 + deltax
) ) {
value =
( x - x0
) / deltax ;
} else {
value = 1.0 ;
}
return value ;
}
double VelvetySlope
( double x
, double x0
, double deltax
) {
double value;
if ( x < x0
) {
value = 0.0 ;
} else if ( x <
( x0 + deltax
) ) {
double y =
( x - x0
) / deltax ;
value =
( 1.0 +
sin( -PI/2 + PI*y
) ) / 2 ;
} else {
value = 1.0 ;
}
return value ;
}
// eyeteeth
( teeth of saw
)
double Eyeteeth
( double x
, double width
) {
// 0 <= x <=1
double s = x ;
if ( ( x < 0.0
) ||
( x > 1.0
) ) {
alert( "Error
( Eyeteeth
) "
);
} else {
while ( s > width
) {
s = s - width ;
}
}
return s / width ;
}
// pulsar
double Pulsar
( double x
, double cycle
, double upslope
, double top
, double downslope
) {
// 0 <= x <=1
double value;
double s = Eyeteeth
( x
, cycle
) ;
double ups = upslope / cycle ;
double tops = top / cycle ;
double downs = downslope / cycle ;
if ( s < ups
) {
value = Bump
( s / ups * 0.5
) ;
} else if ( s < ups + tops
) {
value = 1.0 ;
} else if ( s < ups + tops + downs
) {
value = Bump
( 0.5 +
( ( s -
( ups + tops
) ) / downs
) * 0.5
) ;
} else {
value = 0.0 ;
}
return value ;
}
// unit bump function
double Bump
( double x
) {
return ( sin( 2*PI * x - PI/2
) + 1.0
) / 2 ;
}
double TurnBump
( double x
) {
return 1.0 - Bump
( x
) ;
}
double MSlope
( double x
) {
double y ;
if ( x > 1.0
) {
y = x -
(int
)( x
) ;
} else if ( x >= 0.0
) {
y = x ;
} else {
y = x +
( 1.0 -
(int
)( x
) ) ;
}
double value ;
if ( y > 1.0/2
) {
y = 1.0 - y ;
}
if ( y > 1.0/3
) {
value = 0.0 ;
} else if ( y > 1.0/6
) {
value = 2 - 6*y ;
} else {
value = 1.0 ;
}
return value ;
}
int Parity
( int i
) {
int p;
if ( i % 2 == 0
) {
p = 1 ;
} else {
p = -1 ;
}
return p ;
}
double
[ ] SolveQuadraticEquation
( double a
, double b
, double c
) {
double D = b^2 - 4 * a * c ;
double solution
[2
];
solution
[0
] =
( -b - D^0.5
) /
( 2*a
) ;
solution
[1
] =
( -b + D^0.5
) /
( 2*a
) ;
return solution ;
}
// LIB040
/* ROUTINE */
void PrintVectorln
( int v
, string s
) {
println( "Vector " + s + " = "
+
getVectorX( v
) + "
, "
+
getVectorY( v
) + "
, "
+
getVectorZ( v
)
);
}
void PrintDoubleArray
( double a
[ ], string s
) {
int n =
length( a
) ;
for ( int i=0; i<n; i++
) {
println( "s
( " + i + "
) = " + a
[i
] );
}
}
void SetParallelLight
(
int light
, float x
, float y
, float z
, float power
, int renderer
) {
light =
newLight( x
, y
, z
, power
) ;
addLight( light
, renderer
);
}
void SetAmbientLight
(
int light
, float x
, float y
, float z
, float power
, int renderer
) {
light = newAmbientLight
( x
, y
, z
, power
) ;
addLight( light
, renderer
);
}
void SetPointLight
(
int light
, float x
, float y
, float z
, float power
, int renderer
) {
light =
newPointLight( x
, y
, z
, power
) ;
addLight( light
, renderer
);
}
void SetPolygonSurface
( int id
, float x
[ ] ) {
setPolygonEmissive( id
, x
[0
] );
setPolygonDiffractive( id
, x
[1
] );
setPolygonDiffuse( id
, x
[2
] );
setPolygonAmbient( id
, x
[3
] );
setPolygonSpecular( id
, x
[4
], x
[5
] );
}
void SetModelSurface
( int id
, float x
[ ] ) {
setModelEmissive( id
, x
[0
] );
setModelDiffractive( id
, x
[1
] );
setModelDiffuse( id
, x
[2
] );
setModelAmbient( id
, x
[3
] );
setModelSpecular( id
, x
[4
], x
[5
] );
}
// polygonの光学性質をもとめて指定
void SetPolygonSurface
( int polygon
[ ][ ][ ], float option
[ ] ) {
for ( int i=0; i<
length( polygon
)[2
]; i++
) {
for ( int j=0; j<
length( polygon
)[1
]; j++
) {
for ( int k=0; k<
length( polygon
)[0
]; k++
) {
SetPolygonSurface
( polygon
[i
][j
][k
], option
) ;
}
}
}
}
void SetPolygonSurface
( int polygon
[ ][ ], int ng
, float option
[ ] ) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
SetPolygonSurface
( polygon
[ng
][i
], option
) ;
}
}
void SetPolygonSurface
( int polygon
[ ][ ][ ], int ng
, float option
[ ] ) {
for ( int i=0; i<
length( polygon
)[1
]; i++
) {
for ( int j=0; j<
length( polygon
)[0
]; j++
) {
SetPolygonSurface
( polygon
[ng
][i
][j
], option
) ;
}
}
}
void SetPolygonColor
( int id
, int c
[ ], int opc
) {
setPolygonColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
// polygon色をまとめて指定
void SetPolygonColors
( int polygon
[ ][ ], int ng
, int color
[ ], int opacity
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
SetPolygonColor
( polygon
[ng
][i
], color
, opacity
) ;
}
}
void SetPolygonColors
( int polygon
[ ][ ][ ], int ng
, int color
[ ], int opacity
) {
for ( int i=0; i<
length( polygon
)[1
]; i++
) {
for ( int j=0; j<
length( polygon
)[0
]; j++
) {
SetPolygonColor
( polygon
[ng
][i
][j
], color
, opacity
) ;
}
}
}
void SetPolygonColors
(
int polygon
[ ][ ], int ng
, int color
[ ][ ], int nc
, int opacity
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
setPolygonColor(
polygon
[ng
][i
], color
[nc
][0
], color
[nc
][1
], color
[nc
][2
], opacity
) ;
}
}
// polygonのcullingをまとめて指定
void SetPolygonCull
( int polygon
[ ][ ][ ], bool cullout
, bool cullin
) {
for ( int i=0; i<
length( polygon
)[2
]; i++
) {
for ( int j=0; j<
length( polygon
)[1
]; j++
) {
for ( int k=0; k<
length( polygon
)[0
]; k++
) {
setPolygonCull( polygon
[i
][j
][k
], cullout
, cullin
) ;
}
}
}
}
void SetPolygonCull
( int polygon
[ ][ ], int ng
, bool cullout
, bool cullin
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
setPolygonCull( polygon
[ng
][i
], cullout
, cullin
) ;
}
}
void SetPolygonCull
( int polygon
[ ][ ][ ], int ng
, bool cullout
, bool cullin
) {
for ( int i=0; i<
length( polygon
)[1
]; i++
) {
for ( int j=0; j<
length( polygon
)[0
]; j++
) {
setPolygonCull( polygon
[ng
][i
][j
], cullout
, cullin
) ;
}
}
}
void SetModelColor
( int id
, int c
[ ], int opc
) {
setModelColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
void SetLightColor
( int id
, int c
[ ], int opc
) {
setLightColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
void PileCoordinate
( int cd
[ ] , int renderer
) {
int n =
length( cd
) ;
for ( int i=0; i<n; i++
) {
if ( i == 0
) {
addCoordinate( cd
[n-1-i
], renderer
);
} else {
addCoordinate( cd
[n-1-i
], renderer
, cd
[n-i
] );
}
}
}
// vectorの和を返す
int GetVectorSum
( int v1
, int v2
) {
int v =
newVector() ;
double vx =
getVectorX( v1
) +
getVectorX( v2
) ;
double vy =
getVectorY( v1
) +
getVectorY( v2
) ;
double vz =
getVectorZ( v1
) +
getVectorZ( v2
) ;
setVector( v
, vx
, vy
, vz
);
return v ;
}
// moveVectorの結果を返す
int GetMoveVector
( int v
, double x
, double y
, double z
) {
int u =
newVector( v
);
moveVector( u
, x
, y
, z
);
return u ;
}
// vectorの差を求めて代入する
void VectorDifference
( int v
, int v1
, int v2
) {
double vx =
getVectorX( v1
) -
getVectorX( v2
) ;
double vy =
getVectorY( v1
) -
getVectorY( v2
) ;
double vz =
getVectorZ( v1
) -
getVectorZ( v2
) ;
setVector( v
, vx
, vy
, vz
);
}
// vectorの差を返す
int GetVectorDifference
( int v1
, int v2
) {
double vx =
getVectorX( v1
) -
getVectorX( v2
) ;
double vy =
getVectorY( v1
) -
getVectorY( v2
) ;
double vz =
getVectorZ( v1
) -
getVectorZ( v2
) ;
int v =
newVector( vx
, vy
, vz
) ;
return v ;
}
// vectorの定数倍する
void ScaleVector
( int v
, double x
) {
scaleVector( v
, x
, x
, x
) ;
}
// vectorの定数倍を返す
int GetScaleVector
( int v
, double x
) {
int u =
newVector( v
) ;
scaleVector( u
, x
, x
, x
) ;
return u ;
}
// vectorの回転を求めて返す
int GetRotXVector
( int v
, double angle
) {
int u =
newVector( v
) ;
rotXVector( u
, angle
);
return u ;
}
int GetRotYVector
( int v
, double angle
) {
int u =
newVector( v
) ;
rotYVector( u
, angle
);
return u ;
}
int GetRotZVector
( int v
, double angle
) {
int u =
newVector( v
) ;
rotZVector( u
, angle
);
return u ;
}
int GetRotVector
( int v
, double angle
, int ax
, int rc
) {
int u =
newVector( v
) ;
rotVector( u
, angle
, ax
, rc
);
return u ;
}
// 内分点を求める。P1V ; VP2 = t : 1-t
int GetInternallyDividingVector
(
double x1
, double y1
, double z1
,
double x2
, double y2
, double z2
,
double t
) {
double vx =
( 1.0 - t
)*x1 + t*x2 ;
double vy =
( 1.0 - t
)*y1 + t*y2 ;
double vz =
( 1.0 - t
)*z1 + t*z2 ;
int v =
newVector ( vx
, vy
, vz
) ;
return v ;
}
int GetInternallyDividingVector
( int v1
, int v2
, double t
) {
double vx =
( 1.0 - t
)*
getVectorX( v1
) + t*
getVectorX( v2
) ;
double vy =
( 1.0 - t
)*
getVectorY( v1
) + t*
getVectorY( v2
) ;
double vz =
( 1.0 - t
)*
getVectorZ( v1
) + t*
getVectorZ( v2
) ;
int v =
newVector ( vx
, vy
, vz
) ;
return v ;
}
int GetMiddlePointVector
( int v1
, int v2
) {
double x =
( getVectorX( v1
) +
getVectorX( v2
) ) / 2 ;
double y =
( getVectorY( v1
) +
getVectorY( v2
) ) / 2 ;
double z =
( getVectorZ( v1
) +
getVectorZ( v2
) ) / 2 ;
int mid =
newVector( x
, y
, z
) ;
return mid ;
}
// vをcdに配置してCDへ変換したものを求める
int GetTransformedVector
( int v
, int renderer
, int cd
, int CD
) {
int u =
newVector( v
) ;
addVector( v
, renderer
, cd
);
transformVector( v
, u
, CD
);
removeVector
( v
, renderer
, cd
);
return u ;
}
void TransformVector
( int v
, int renderer
, int cd
, int u
, int CD
) {
addVector( v
, renderer
, cd
);
transformVector( v
, u
, CD
);
removeVector
( v
, renderer
, cd
);
}
void SetCoordinateOrigin
( int cd
, double x
[ ] ) {
setCoordinateOrigin( cd
, x
[0
], x
[1
], x
[2
] );
}
int GetVectorCoordinateOrigin
( int cd
) {
int v =
newVector(
getCoordinateOriginX( cd
),
getCoordinateOriginY( cd
),
getCoordinateOriginZ( cd
)
);
return v ;
}
// 重心を返す
int GetVectorGravityCenter
( int v
[ ] ) {
int g =
newVector( v
[0
] ) ;
for ( int i=1; i<
length( v
); i++
) {
moveVector( g
, v
[i
] );
}
double s = 1.0 /
length( v
) ;
scaleVector( g
, s
, s
, s
);
return g ;
}
double
[ ] getCenterOfGravity
( int v
[ ] ) {
int g =
newVector( v
[0
] ) ;
int lenv =
length( v
) ;
for ( int i=1; i<lenv; i++
) {
moveVector( g
, v
[i
] );
}
double s = 1.0 / lenv ;
scaleVector( g
, s
, s
, s
);
double x
[ 3
];
x
[0
] =
getVectorX( g
) ;
x
[1
] =
getVectorY( g
) ;
x
[2
] =
getVectorZ( g
) ;
return x ;
}
// normal vectorを返す
int GetNormalVectorQuadrangle
( int v
[ ] ) {
int v1 = GetVectorDifference
( v
[2
], v
[0
] ) ;
int v2 = GetVectorDifference
( v
[3
], v
[1
] ) ;
int normalv =
newVector() ;
getVectorCrossProduct( v1
, v2
, normalv
);
double length =
getVectorLength( normalv
) ;
if ( !
( length == o
) ) {
setVectorLength( normalv
, 1.0
);
} else {
alert( "error
( GetNormalVectorQuadrangle
)"
) ;
}
return normalv ;
}
// 2枚の面の作る角の余弦を返す
double GetAngleFaceFace
( int v1
[ ], int v2
[ ] ) {
int n1 = GetNormalVectorQuadrangle
( v1
) ;
int n2 = GetNormalVectorQuadrangle
( v2
) ;
double costh =
getVectorInnerProduct( n1
, n2
) ;
return costh ;
}
void SetVectorsCoordinateLocationAttitude
( int vo
, int va
, int cd
) {
double x =
getCoordinateOriginX( cd
) ;
double y =
getCoordinateOriginY( cd
) ;
double z =
getCoordinateOriginZ( cd
) ;
double a =
getCoordinateEulerAngleAlpha( cd
) ;
double b =
getCoordinateEulerAngleBeta( cd
) ;
double g =
getCoordinateEulerAngleGamma( cd
) ;
setVector( vo
, x
, y
, z
);
setVector( va
, a
, b
, g
);
}
void SetVectorsCoordinateLocationAttitude
( int so
[ ], int sa
[ ], int cd
[ ] ) {
double x
, y
, z
, a
, b
, g ;
for ( int i=0; i<
length( cd
); i++
) {
x =
getCoordinateOriginX( cd
[i
] ) ;
y =
getCoordinateOriginY( cd
[i
] ) ;
z =
getCoordinateOriginZ( cd
[i
] ) ;
a =
getCoordinateEulerAngleAlpha( cd
[i
] ) ;
b =
getCoordinateEulerAngleBeta( cd
[i
] ) ;
g =
getCoordinateEulerAngleGamma( cd
[i
] ) ;
setVector( so
[i
], x
, y
, z
) ;
setVector( sa
[i
], a
, b
, g
) ;
}
}
void SetCoordinateLocationAttitude
( int cd
, int vo
, int va
) {
double x =
getVectorX( vo
) ;
double y =
getVectorY( vo
) ;
double z =
getVectorZ( vo
) ;
double a =
getVectorX( va
) ;
double b =
getVectorY( va
) ;
double g =
getVectorZ( va
) ;
setCoordinateOrigin( cd
, x
, y
, z
);
setCoordinateEulerAngle( cd
, a
, b
, g
);
}
void SetCoordinateEulerAngle
( int cd
, int v
) {
setCoordinateEulerAngle( cd
,
getVectorX( v
), getVectorY( v
), getVectorZ( v
)
);
}
double
[ ] GetArryCoordinateEulerAngle
( int cd
) {
double ea
[ 3
];
ea
[0
] =
getCoordinateEulerAngleAlpha( cd
) ;
ea
[1
] =
getCoordinateEulerAngleBeta( cd
) ;
ea
[2
] =
getCoordinateEulerAngleGamma( cd
) ;
return ea ;
}
int GetVectorCoordinateEulerAngle
( int cd
) {
double ea
[ 3
];
ea
[0
] =
getCoordinateEulerAngleAlpha( cd
) ;
ea
[1
] =
getCoordinateEulerAngleBeta( cd
) ;
ea
[2
] =
getCoordinateEulerAngleGamma( cd
) ;
int v =
newVector( ea
) ;
return v ;
}
// リセットなしの回転
void RotateCoordinate
(
int cd
, int so
, int sa
, double angle
, int ax
, int rc
, int renderer
, int Cd
) {
int dummycd =
newCoordinate() ;
addCoordinate( dummycd
, renderer
, Cd
) ;
SetCoordinateLocationAttitude
( dummycd
, so
, sa
) ;
rotCoordinate( dummycd
, angle
, ax
, rc
) ;
int sovalue =
newVector() ;
int savalue =
newVector();
SetVectorsCoordinateLocationAttitude
( sovalue
, savalue
, dummycd
) ;
SetCoordinateLocationAttitude
( cd
, sovalue
, savalue
) ;
removeCoordinate( dummycd
, renderer
, Cd
) ;
}
// O から dist 離れた地点へresetなしに移す
, y-direction
void SetCoordinateLocationYdirection
( int cd
, double dist
) {
int dummycd =
newCoordinate() ;
int v =
newVector() ;
CopyCoordinateAttitude
( dummycd
, cd
) ;
walkCoordinate( dummycd
, o
, dist
, o
) ;
v = GetVectorCoordinateOrigin
( dummycd
) ;
setCoordinateOrigin( cd
, v
) ;
}
// 座標系の姿勢をコピー
(座標系原点はコピーせず O とする
)
void CopyCoordinateAttitude
( int cd
, int originalcd
) {
int sa = GetVectorCoordinateEulerAngle
( originalcd
) ;
SetCoordinateLocationAttitude
( cd
, O
, sa
) ;
}
// y軸及びz軸が引数ベクトルと平行な姿勢にする
void SetCoordinateAttitudeYZ
( int cd
, int vy
, int vz
) {
int uy =
newVector( vy
) ;
int uz =
newVector( vz
) ;
setVectorLength( uy
, 1.0
);
setVectorLength( uz
, 1.0
);
int ux =
newVector() ;
getVectorCrossProduct( uy
, uz
, ux
);
setCoordinateBaseX( cd
, ux
);
setCoordinateBaseY( cd
, uy
);
setCoordinateBaseZ( cd
, uz
);
}
// 原点が v2
, cylinder 端点が v1
, v2 となるように cd を set する
void SetCoordinateCylinder
( int cyl
, double rad
, int v1
, int v2
, int cd
) {
double x
[ 3
];
x
[0
] =
getVectorX( v1
) -
getVectorX( v2
) ;
x
[1
] =
getVectorY( v1
) -
getVectorY( v2
) ;
x
[2
] =
getVectorZ( v1
) -
getVectorZ( v2
) ;
int v21 =
newVector( x
) ;
double length =
getVectorLength( v21
) ; // シリンダーの長さ
if ( length != 0.0
) {
int xyprojection =
newVector( x
[0
], x
[1
], 0.0
) ;
setVectorLength( xyprojection
, 1.0
) ;
double cos1 =
getVectorY( xyprojection
) ; // xy射影がy軸となす角の余弦
double th1; // xy射影がy軸となす角度
if ( x
[1
] == 0.0
) {
if ( x
[0
] >= 0.0
) {
th1 = PI/2 ;
} else {
th1 = -PI/2 ;
}
} else if( x
[0
] < 0.0
) {
th1 = -
acos( cos1
) ;
} else {
th1 =
acos( cos1
) ;
}
setVectorLength( v21
, 1.0
);
double sin2 =
getVectorZ( v21
); // 射影と元のベクトルのなす角の正弦
double th2 =
asin( sin2
) ;
double alpha = -th1 ;
double beta = th2 - PI/2 ;
double gamma = 0.0 ;
if ( th1 < 0.0
) { gamma = PI ;
}
setCoordinateOrigin( cd
, v2
);
setCoordinateEulerAngle( cd
, alpha
, beta
, gamma
);
setModelSize( cyl
, rad
, rad
, length );
}
}
void SetSphereSize
( int sp
, double rad
) {
setModelSize( sp
, rad
, rad
, rad
);
}
// n 番目の多面体のすべての面の頂点を vector で指定する
void SetTriangleVector
( int p
[ ][ ], int n
, int v
[ ][ ] ) {
for ( int i=0; i<
length( p
); i++
) {
setPolygonVector( p
[n
][i
], v
[i
][0
], v
[i
][1
], v
[i
][2
] ) ;
}
}
void SetTriangleVector
( int p
[ ][ ][ ], int n
, int v
[ ][ ][ ] ) {
for ( int i=0; i<
length( p
)[1
]; i++
) {
for ( int j=0; j<
length( p
)[0
]; j++
) {
setPolygonVector( p
[n
][i
][j
], v
[i
][j
][0
], v
[i
][j
][1
], v
[i
][j
][2
] ) ;
}
}
}
// polygon をまとめて配置する
void AddPolygons
( int p
[ ][ ][ ], int renderer
, int cd
[ ] ) {
for ( int i=0; i<
length( p
)[2
]; i++
) {
for ( int j=0; j<
length( p
)[1
]; j++
) {
for ( int k=0; k<
length( p
)[0
]; k++
) {
addPolygon( p
[i
][j
][k
], renderer
, cd
[i
] ) ;
}
}
}
}
void AddPolygons
( int p
[ ][ ][ ], int ng
, int renderer
, int cd
[ ] ) {
for ( int i=0; i<
length( p
)[1
]; i++
) {
for ( int j=0; j<
length( p
)[0
]; j++
) {
addPolygon( p
[ng
][i
][j
], renderer
, cd
[ng
] ) ;
}
}
}
void AddPolygons
( int p
[ ][ ], int m
, int renderer
, int cd
[ ][ ], int n
) {
for ( int i=0; i<
length( p
)[0
]; i++
) {
addPolygon( p
[m
][i
], renderer
, cd
[n
][i
] ) ;
}
}
void AddPolygons
( int p
[ ][ ], int ng
, int renderer
, int cd
) {
for ( int i=0; i<
length( p
)[0
]; i++
) {
addPolygon( p
[ng
][i
], renderer
, cd
) ;
}
}
int
[ ] RV2_1
( int v
[ ][ ], int n
) { // ベクトルの2次元配列からベクトルの1次元配列を作る
int m =
length( v
)[0
] ;
int u
[ m
] ;
for ( int i=0; i<m; i++
) {
u
[i
] =
newVector( v
[n
][i
] ) ;
}
return u ;
}
int
[ ] RV2_0
( int v
[ ][ ], int n
) { // ベクトルの2次元配列からベクトルの1次元配列を作る
int m =
length( v
)[1
] ;
int u
[ m
] ;
for ( int i=0; i<m; i++
) {
u
[i
] =
newVector( v
[i
][n
] ) ;
}
return u ;
}
int
[ ] RA2_0
( int arry
[ ][ ], int n
) { // 整数型2次元配列から整数型1次元配列を作る
int m =
length( arry
)[0
] ;
int rarry
[ m
] ;
for ( int i=0; i<m; i++
) {
rarry
[i
] = arry
[n
][i
] ;
}
return rarry ;
}
// LIB052
/* MOTION */
void PrepareMovie
() {
bool loop = true ;
T = o ;
int rpm = 10 ;
double anglepf = 2*PI * rpm / 60 / FPS ;
while ( loop
) {
Movie
( anglepf
, false
) ;
if ( T >= END_T
) {
loop = false ;
}
if ( T == o
) {
NewStateVectors
( LENGTH
, NG
) ;
}
T += STEP ;
}
T = START_T ;
Movie
( anglepf
, false
) ;
T = o ;
}
void NewStateVectors
( int length1
, int length2
) {
int dummy1
[ length1
], dummy2
[ length1
][ length2
] ;
SX = dummy1 ;
SA = dummy1 ;
X = dummy2 ;
A = dummy2 ;
for ( int i=0; i<length1; i++
) {
for ( int j=0; j<length2; j++
) {
X
[i
][j
] =
newVector() ;
A
[i
][j
] =
newVector() ;
if ( j == 0
) {
SX
[i
] =
newVector() ;
SA
[i
] =
newVector() ;
}
}
}
}
double Linear
( int v
, bool tstate
) {
double t
, t0 =
getVectorX( v
), t1 =
getVectorY( v
) ;
if ( tstate
) {
if ( T < t0
) {
t = 0.0 ;
} else if ( T < t1 - STEP
) {
t =
( T - t0
) /
( t1 - t0 - STEP
) ;
} else {
t = 1.0 ;
}
} else {
if ( T > t1
) {
t = 1.0 ;
} else if ( T > t0 + STEP
) {
t =
( t0 + STEP - T
) /
( t0 + STEP - t1
) ;
} else {
t = 0.0 ;
}
}
return t ;
}
double Sin
( int v
, bool tstate
) {
double t = Linear
( v
, tstate
) ;
double s =
( 1.0 +
sin( PI*t - PI/2
) ) / 2 ;
return s ;
}
void SetTRangeRight
( int u
, int v
) {
setVector(
u
, getVectorX( u
), getVectorY( v
), getVectorY( v
) -
getVectorX( u
)
) ;
}
void SetTRange
( int v
, double dt1
, double dt0
) {
double t0 =
getVectorY( v
) + dt1 ;
double t1 = t0 + dt0 ;
setVector( v
, t0
, t1
, dt0
);
}
void SetTRangeAbsolutely
( int v
, double t0
, double t1
) {
setVector( v
, t0
, t1
, t1 - t0
);
}
bool Motion
( int v
) {
return ( T >=
getVectorX( v
) ) &&
( T <
getVectorY( v
) ) ;
}
bool Moment
( int v
) {
double t0 =
getVectorX( v
) ;
double t1 = t0 + STEP ;
return ( T >= t0
) &&
( T < t1
) ;
}
bool Border
( int v
) {
double t00 =
getVectorX( v
) ;
double t01 = t00 + STEP ;
double t10 =
getVectorY( v
) ;
double t11 = t00 - STEP ;
return ( ( T >= t00
) &&
( T < t01
) ) ||
( ( T > t11
) &&
( T <= t10
) ) ;
}
bool Border0
( int v
) {
double t00 =
getVectorX( v
) ;
double t01 = t00 + STEP ;
return ( T >= t00
) &&
( T < t01
) ;
}
bool Border1
( int v
) {
double t10 =
getVectorY( v
) ;
double t11 = t10 - STEP ;
return ( T > t11
) &&
( T <= t10
) ;
}
// blinder
void VisualizePolygon
( int polygon
, int renderer
, int r
, int g
, int b
, int v
) {
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
int screen =
getScreenCoordinate( renderer
) ;
addPolygon( polygon
, renderer
, screen
);
movePolygon( polygon
, o
, o
, -1.0
);
}
double t = Linear
( v
, true
) ;
int opacity = 255 * t ;
setPolygonColor( polygon
, r
, g
, b
, opacity
);
}
}
void RemovePolygonAfterUnvisualize
(
int polygon
, int renderer
, int r
, int g
, int b
, int v
) {
double endtime =
getVectorY( v
) ;
int screen =
getScreenCoordinate( renderer
) ;
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int opacity = 255 *
( 1.0 - t
) ;
setPolygonColor( polygon
, r
, g
, b
, opacity
);
if ( T > endtime - STEP
) {
removePolygon( polygon
, renderer
, screen
);
}
}
}
void UnvisualezePolygon
( int polygon
, int r
, int g
, int b
, int endopacity
, int v
) {
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int opacity = 255 -
( 255 - endopacity
) * t ;
setPolygonColor( polygon
, r
, g
, b
, opacity
);
}
}
// text
string TEXT_RUSEN = "http://rusen.seesaa.net/" ;
int BLINDER =
newQuadranglePolygon( 2*l
,2*l
,o
, -2*l
,2*l
,o
, -2*l
,-2*l
,o
, 2*l
,-2*l
,o
) ;
setPolygonEmissive( BLINDER
, 1.0
);
setPolygonSpecular( BLINDER
, o
, 0.01
);
int TEXT = NewTextPolygonLowLeft
( TEXT_RUSEN
, GRAPHIC_MAGNIFICATION
, -0.5
) ;
int NewTextPolygonLowLeft
( string text
, double magnification
, double z
) {
int framewidth_x = 14 ;
int framewidth_y = 39 ;
double size = -50 * z / magnification ;
double x = -size *
( WIDTH - framewidth_x
) / 100 ;
double y = -size *
( HEIGHT - framewidth_y
) / 100 ;
int txtpolygon =
newTextPolygon( x
, y
, 1.0 + z
, 0.9 * size
, text
) ;
return txtpolygon ;
}
void OpenTextWhite
( int v
, double t0
, double t1
) {
SetTRangeAbsolutely
( v
, t0
, t1
);
VisualizePolygon
( BLINDER
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, o
, 3.0
);
if ( Moment
( v
) ) {
COUNT = -1 ;
}
RemovePolygonAfterUnvisualize
( BLINDER
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, -4.0
, 4.0
);
VisualizePolygon
( TEXT
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, 3.0
, 8.0
);
UnvisualezePolygon
( TEXT
, 255
, 255
, 255
, 5
, v
);
SetTRange
( v
, -14.0
, o
);
}
void OpenBlindBlack
( int v
, double t0
, double t1
) {
SetTRangeAbsolutely
( v
, t0
, t1
);
VisualizePolygon
( BLINDER
, RENDERER
, 0
, 0
, 0
, v
);
SetTRange
( v
, o
, 3.0
);
if ( Moment
( v
) ) {
COUNT = -1 ;
}
RemovePolygonAfterUnvisualize
( BLINDER
, RENDERER
, 0
, 0
, 0
, v
);
SetTRange
( v
, -3.0
, 5.0
);
VisualizePolygon
( TEXT
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, 8.0
, 5.0
);
UnvisualezePolygon
( TEXT
, 255
, 255
, 255
, 5
, v
);
SetTRange
( v
, -18.0
, o
);
}
void CloseTextWhite
( int v
, double dt1
, double dt0
) {
SetTRange
( v
, dt1
, dt0
);
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int opacity = 255*t ;
setPolygonColor( TEXT
, 255
, 255
, 255
, opacity
);
}
SetTRange
( v
, dt1
, 3.0
);
VisualizePolygon
( BLINDER
, RENDERER
, 255
, 255
, 255
, v
);
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int c = 255 *
( a - t
) ;
setPolygonColor( TEXT
, c
, c
, c
, 255
) ;
}
SetTRange
( v
, o
, 2.0
);
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int opacity = 255 *
( a - t
) ;
setPolygonColor( TEXT
, 0
, 0
, 0
, opacity
);
}
}
void CloseBlindBlack
( int v
, double dt1
, double dt0
) {
SetTRange
( v
, dt1
, dt0
);
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int opacity = 255*t ;
setPolygonColor( TEXT
, 255
, 255
, 255
, opacity
);
}
SetTRange
( v
, 5.0
, 5.0
);
if ( Motion
( v
) ) {
double t = Linear
( v
, true
) ;
int opacity = 255 *
( a - t
) ;
setPolygonColor( TEXT
, 255
, 255
, 255
, opacity
);
}
}
// LIB060
/* COLORS */
int
[ ] Color
( int i
, int j
, int k
) {
int c
[ 3
] ;
if ( ( i < 0
) ||
( j < 0
) ||
( k < 0
)
||
( i > 255
) ||
( j > 255
) ||
( k > 255
) ) {
c = 0 ;
alert( "Error
( Color
) "
);
} else {
c
[0
] = i ;
c
[1
] = j ;
c
[2
] = k ;
}
return c ;
}
int
[ ] Color
( float r
, float g
, float b
) {
int c
[ 3
] ;
if ( ( r < 0.0
) ||
( g < 0.0
) ||
( b < 0.0
)
||
( r > 1.0
) ||
( g > 1.0
) ||
( b > 1.0
) ) {
c = 0 ;
alert( "Error
( Color
) "
);
} else {
c
[0
] = 255 * r ;
c
[1
] = 255 * g ;
c
[2
] = 255 * b ;
}
return c ;
}
int
[ ] Color
( float x
) {
int c
[ 3
] ;
if ( ( x < 0.0
) ||
( x > 1.0
) ) {
c = 0 ;
alert( "Error
( Color
) "
);
} else {
c = 255 * x ;
}
return c ;
}
int
[ ] BiColor
( float x
) {
int c
[ 3
] ;
c
[0
] = 255 * MSlope
( x
) ;
c
[1
] = 255 * MSlope
( x - 1.0/3
) ;
c
[2
] = 255 * MSlope
( x + 1.0/3
) ;
return c ;
}
int
[ ] MixedColor
(
float r1
, float g1
, float b1
,
float r2
, float g2
, float b2
,
double p
) {
int color
[ 3
] ;
float c1
[ ] =
{ r1
, g1
, b1
} ;
float c2
[ ] =
{ r2
, g2
, b2
} ;
for ( int i=0; i<
length( color
); i++
) {
color
[i
] = 255 *
( c1
[i
] *
( 1 - p
) + c2
[i
] * p
) ;
}
return color ;
}
int
[ ] MixedColor
( int color1
[ ], int color2
[ ], double p
){
int color
[ 3
] ;
for ( int i=0; i<
length( color
); i++
) {
color
[i
] = color1
[i
] *
( 1 - p
) + color2
[i
] * p ;
}
return color ;
}
// LIB070
/* GEOMETRY */
double GetHeightAntiprismByConnectionName
(
int nside
, double rad
, string polyhedronname
) {
double delta = rad *
( 1 -
cos( PI/nside
) ) ;
double antiprismdhangle ; // 底面と側面の normal vector の作る角
if ( polyhedronname == "cube"
) {
antiprismdhangle = 3*PI/4 ;
} else if ( polyhedronname == "octahedron"
) {
antiprismdhangle = PI/2 +
acos( Slv*IPlt
) ;
} else {
alert( "error
( GetHeightAntiprismByName
)"
) ;
}
double antiprismheight = delta *
tan( PI - antiprismdhangle
) ;
return antiprismheight ;
}
int
[ ] Get3Vectors4sideAntiprismCubeConnection
( double baserad
) {
int v
[ 3
] ;
v
[0
] =
newVector( o
, o
, baserad
) ;
v
[1
] = GetRotYVector
( v
[0
], PI/2
) ;
double h = GetHeightAntiprismByConnectionName
( 4
, baserad
, "cube"
) ;
v
[2
] =
newVector( o
, h
, o
) ;
return v ;
}
// dodecahedron の inradiusを返す
double GetInradiusDodecahedron
( double prad
) {
return prad *
( Gld + 1
) / 2 ;
}
// 原点中心、zx平面内、regular n-gonのz軸上の点
(z>0
)とその反時計回り隣の点
int
[ ] Get3VectorsNGon
( int n
, double rad
) {
int u
[ 3
] ;
u
[0
] =
newVector( o
, o
, o
) ;
u
[1
] =
newVector( o
, o
, rad
) ;
u
[2
] = GetRotYVector
( u
[1
], 2*PI/n
) ;
return u ;
}
// square cupola の頂点ベクトルを返す
int
[ ] Get12VectorsSquareCupola
( double baserad
) {
int v
[ 12
] ;
// 7 - 0 底面頂点
v
[0
] =
newVector( baserad*
sin(PI/8
), o
, baserad*
cos(PI/8
) ) ; // 底面の edge は z軸に直交する
for ( int i=1; i<=7; i++
) {
v
[i
] = GetRotYVector
( v
[0
], PI/4 * i
) ;
}
// 11 - 8 天井
double edge = 2 * baserad *
sin( PI/8
) ;
double h = edge * ISlv ;
v
[8
] =
newVector( edge/2
, h
, edge/2
) ;
for( int i=9; i<=11; i++
) {
v
[i
] = GetRotYVector
( v
[8
], PI/2 * i
) ;
}
return v ;
}
int
[ ] Get2VectorsSquareCupola
( double baserad
) {
int v
[ 2
] ;
v
[0
] =
newVector( baserad*
sin(PI/8
), o
, baserad*
cos(PI/8
) ) ; // 底面の edge は z軸に直交する
double edge = 2 * baserad *
sin( PI/8
) ;
double h = edge * ISlv ;
v
[1
] =
newVector( edge/2
, h
, edge/2
) ; // 天井の edge はx軸に平行
return v ;
}
// diamond space filler の頂点ベクトルを返す
int
[ ][ ][ ] GetVectorsDiamondSpaceFiller
( double x
) { // vertex
( x
, 0
, 0
)
int v
[ S4
][ R3*2
][ R3
] ;
v
[0
][0
][0
] =
newVector( o
, x
, o
) ;
v
[0
][0
][1
] =
newVector( -x/2
, x/2
, x/2
) ;
v
[0
][0
][2
] =
newVector( x/4
, x/4
, x/4
) ;
v
[0
][1
][0
] =
newVector( v
[0
][0
][1
] ) ;
v
[0
][1
][1
] =
newVector( o
, o
, x
) ;
v
[0
][1
][2
] =
newVector( v
[0
][0
][2
] ) ;
int ax0 =
newVector( a
, a
, a
) ;
int ax1 =
newVector( a
, o
, a
) ;
for ( int i=1; i<R3; i++
) {
for ( int j=0; j<R3; j++
) {
v
[0
][2*i
][j
] = GetRotVector
( v
[0
][0
][j
], 2*PI/3 * i
, ax0
, O
) ;
v
[0
][2*i+1
][j
] = GetRotVector
( v
[0
][1
][j
], 2*PI/3 * i
, ax0
, O
) ;
}
}
for ( int i=1; i<S4; i++
) {
for ( int j=0; j<R3*2; j++
) {
for ( int k=0; k<R3; k++
) {
v
[i
][j
][k
] = GetRotYVector
( v
[0
][j
][k
], PI/2 * i
) ;
if ( i%2 == 1
) {
rotVector( v
[i
][j
][k
], PI
, ax1
) ;
}
}
}
}
return v ;
}
void SetFacesDiamondSpaceFiller
( int p
[ ][ ][ ], int ng
, double x
) {
int u
[ ][ ][ ] = GetVectorsDiamondSpaceFiller
( x
) ;
SetTriangleVector
( p
, ng
, u
) ;
}
// octahedron の頂点ベクトルを返す
int
[ ][ ] GetVectorsOctahedron
( double x
) { // vertex
( x
, 0
, 0
)
int v
[ S8
][ R3
] ;
v
[0
][0
] =
newVector( x
, o
, o
) ;
v
[0
][1
] =
newVector( o
, x
, o
) ;
v
[0
][2
] =
newVector( o
, o
, x
) ;
for ( int i=1; i<S8; i++
) {
for ( int j=0; j<R3; j++
) {
if ( i <= 3
) {
v
[i
][j
] = GetRotYVector
( v
[0
][j
], PI/2 *
( i%4
) ) ;
} else {
v
[i
][j
] = GetRotZVector
( v
[0
][j
], PI
) ;
rotYVector( v
[i
][j
], PI/2 *
( ( i - 3
) % 4
) ) ;
}
}
}
return v ;
}
int
[ ] GetVectors4FacesSymmetry
( double x
) { //
( x
, x
, x
)
int v
[ 4
] ;
v
[0
] =
newVector( x
, x
, x
) ;
v
[1
] = GetRotYVector
( v
[0
], PI
) ;
v
[2
] = GetRotXVector
( v
[0
], PI
) ;
v
[3
] = GetRotZVector
( v
[0
], PI
) ;
return v ;
}
int
[ ] GetVectors6FacesSymmetry
( double x
) { //
( o
, x
, o
)
int v
[ 6
] ;
v
[0
] =
newVector( o
, x
, o
) ;
v
[1
] = GetRotZVector
( v
[0
], PI/2
) ;
for ( int i=2; i<=4; i++
) {
v
[i
] = GetRotYVector
( v
[1
], PI/2 *
( i - 1
) ) ;
}
v
[5
] = GetRotZVector
( v
[0
], PI
) ;
return v ;
}
int
[ ] GetVectors8FacesSymmetry
( double x
) { //
( x
, x
, x
)
int v
[ 8
] ;
v
[0
] =
newVector( x
, x
, x
) ;
v
[4
] =
newVector( x
, -x
, x
) ;
for ( int i=1; i<4; i++
) {
v
[i
] = GetRotYVector
( v
[0
], PI/2 * i
) ;
v
[4+i
] = GetRotYVector
( v
[4
], PI/2 * i
) ;
}
return v ;
}
int
[ ] GetEulerAngleVectors8FacesSymmetry
() { // y軸が normal vector
int sa
[8
] ;
int cd =
newCoordinate() ;
int ax =
newVector( a
, o
, -a
) ;
rotXCoordinate( cd
, -
atan( Slv
) ) ;
rotYCoordinate( cd
, -3*PI/4
) ;
sa
[0
] = GetVectorCoordinateEulerAngle
( cd
) ;
for ( int i=1; i<4; i++
) {
rotYCoordinate( cd
, PI/2
) ;
sa
[i
] = GetVectorCoordinateEulerAngle
( cd
) ;
}
setCoordinateEulerAngle( cd
, o
, o
, o
) ;
rotXCoordinate( cd
, PI/2 +
atan( ISlv
) ) ;
rotYCoordinate( cd
, PI/4
) ;
sa
[4
] = GetVectorCoordinateEulerAngle
( cd
) ;
for ( int i=5; i<8; i++
) {
rotYCoordinate( cd
, PI/2
) ;
sa
[i
] = GetVectorCoordinateEulerAngle
( cd
) ;
}
return sa ;
}
int
[ ][ ] GetTransformedVectors6FacesSymmetry
(
int v
[ ], double y
, double spiny
) {
int n =
length( v
) ;
int u
[ 6
][ n
] ;
int dely =
newVector( o
, y
, o
) ;
for ( int i=0; i<=5; i++
) {
for ( int j=0; j<n; j++
) {
if ( i == 0
) {
u
[i
][j
] =
newVector( v
[j
] ) ;
moveVector( u
[i
][j
], dely
) ;
rotYVector( u
[i
][j
], spiny
) ;
} else if ( i == 1
) {
u
[i
][j
] = GetRotZVector
( u
[0
][j
], -PI/2
) ;
} else if ( i <= 4
) {
u
[i
][j
] = GetRotYVector
( u
[1
][j
], PI/2 *
( i - 1
) ) ;
} else {
u
[i
][j
] = GetRotZVector
( u
[0
][j
], PI
) ;
}
}
}
return u ;
}
/* set lights */
int AMBIENT_LIGHT = newAmbientLight
( o
, o
, o
, o
) ;
int LIGHT1 =
newLight( 0.1
, 0.12
, 0.2
, o
) ;
int LIGHT2 =
newLight( -0.2
, -0.55
, 0.41
, o
) ;
void SetLights
() {
double power = o ;
SetAmbientLight
( AMBIENT_LIGHT
, o
, o
, o
, power
, RENDERER
);
}
/* create elements */
void SetElements
() {
SetElementOptions
();
AddElements
();
}
int NG = 10 ; // group の数
int TR00
[ NG
][ S4
][ R3*2
] ;
for ( int i=0; i<
length( TR00
)[2
]; i++
) {
for ( int j=0; j<
length( TR00
)[1
]; j++
) {
for ( int k=0; k<
length( TR00
)[0
]; k++
) {
TR00
[i
][j
][k
] =
newTrianglePolygon( O
, O
, O
) ;
}
}
}
int OPACITY
[ ] =
{ 255
, 175
} ;
float OPTION0
[ 6
], OPTION1
[ 6
];
{
float emissive = o ;
float diffractive = 0.8 ;
float diffuse = 0.8 ;
float ambient = 0.5 ;
float specularintensity = 0.8
, specularangle = PI/3.7;
OPTION0
[0
] = emissive ;
OPTION0
[1
] = diffractive ;
OPTION0
[2
] = diffuse ;
OPTION0
[3
] = ambient ;
OPTION0
[4
] = specularintensity ; OPTION0
[5
] = specularangle ;
OPTION1 = OPTION0 ;
OPTION1
[0
] = 0.3 ;
OPTION1
[3
] = 0.3 ;
OPTION1
[4
] = 1.0 ; OPTION1
[5
] = 1.5 ;
}
void SetElementOptions
() {
SetPolygonCull
( TR00
, false
, false
) ;
SetPolygonSurface
( TR00
, OPTION0
) ;
}
void AddElements
() {
int n =
length( COORD
);
addLight( LIGHT1
, RENDERER
, COORD
[n-1
] ) ;
addLight( LIGHT2
, RENDERER
, COORD
[n-1
] ) ;
AddPolygons
( TR00
, RENDERER
, CD
) ;
}
/* set coordinates */
int COORD
[ 7
];
int CD
[ NG
];
for ( int i=0; i<
length( COORD
); i++
) {
COORD
[i
] =
newCoordinate() ;
}
for ( int i=0; i<NG; i++
) {
CD
[i
] =
newCoordinate() ;
}
void SetCoordinates
() {
PileCoordinate
( COORD
, RENDERER
);
for ( int i=0; i<NG; i++
) {
addCoordinate( CD
[i
], RENDERER
, COORD
[0
] );
}
}
/* set axes */
int AXIS
[ 10
];
{
int n =
length( AXIS
) ;
float x
, y
, z ;
for ( int i=0; i<n; i++
) {
x =
( 5*l - 0.5*l*i
) * l ; y = x ; z = x ;
AXIS
[i
] =
newAxisModel( x
, y
, z
) ;
}
}
void SetAxes
() {
addModel( AXIS
[0
], RENDERER
, CD
[0
] ) ;
}
/* prepare stage */
int ICHNOGRAPH = 90 ;
double CAMERA_ORIGIN_Z = 10.5 * l * ICHNOGRAPH ;
float GRAPHIC_MAGNIFICATION = 1000.0 * ICHNOGRAPH ;
double GRAPHIC_DISTANCE = 10.0 ;
/* animation Loop */
bool KEEP_LOOP = true ;
bool SAVE_A_PICTURE = false ;
bool PICTURE_ALERT = true ;
bool PICTURE_SAVED = false ;
bool KEEP_MOTION = true ;
bool INCREASE_T = true ;
bool SPIN = false ;
bool CREATE_GUI = false ;
bool GUI_CREATED = false ;
int COUNT = 0 ;
int COUNT_LIMIT = 50000 ;
int FPS = 25 ; // frames / 1sec
int PICTURE_NUMBER = 0 ;
int PICTURE_SAVE_ID = 0 ;
int PICTURE_END_NUMBER = 5000 ;
double T = o
, START_T = -1.0
, END_T = 1000.0
, ADDED_T = o ;
double TIME_FLOW = 1.0
, STEP = TIME_FLOW / FPS ;
int ROT_N ; // アニメーションでの回転回数
int LENGTH = 1 ; //
length( vector
)
int SX
[ 1
], X
[ 1
][ NG
] ; // location
int SA
[ 1
], A
[ 1
][ NG
] ; // angle
void ForwardMotion
() {
int rpm = 10 ; // rotation
, r/min
double anglepf = 2*PI * rpm / 60 / FPS ; // angle/frame
if ( !SPIN
) {
anglepf = o ;
}
if ( !INCREASE_T
) {
anglepf = -anglepf ;
}
// animation
if ( !GUI_CREATED || KEEP_MOTION
) {
Movie
( anglepf
, true
) ;
if ( !GUI_CREATED
) {
CREATE_GUI =
( T >= START_T - STEP
) &&
( T < START_T
) ;
}
}
// 時刻表示更新と animation 終了処理
if ( ( T >= START_T
) &&
( T <= END_T
) ) {
if ( GUI_CREATED
) {
double t = T - START_T ;
int dispT = t ;
bool dispstate ;
if ( INCREASE_T
) {
dispstate =
( (int
)t !=
(int
)( t - STEP
) ) ;
if ( T == END_T
) {
KEEP_MOTION = false ;
}
} else {
dispstate =
( (int
)t !=
(int
)( t + STEP
) ) ;
if ( T == START_T
) {
KEEP_MOTION = false ;
}
}
if ( T == START_T
) {
dispT = 0 ;
}
if ( T == END_T
) {
dispT =
(int
)( END_T-START_T
) ;
}
RefreshIndicator
() ;
if ( dispstate || T == START_T || T == END_T
) {
setComponentText( TEXT_LABEL
[0
], (string
)( dispT
) ) ;
if ( T == START_T || T == END_T
) {
InitializeIndicator
() ;
}
}
}
}
// Spin
if ( T > START_T && SPIN
) {
int n =
length( COORD
) ;
if ( T < END_T
) {
rotYCoordinate( COORD
[n-4
], anglepf
) ;
} else if ( T >= END_T
) {
double q = PI/4 ;
double alp =
getCoordinateEulerAngleAlpha( COORD
[n-4
] ) / q ;
double bet =
getCoordinateEulerAngleBeta( COORD
[n-4
] ) / q ;
double gam =
getCoordinateEulerAngleGamma( COORD
[n-4
] ) / q ;
int inta = alp
, intb = bet
, intg = gam ;
double step = 0.8 ;
if ( alp - inta > step
) {
inta = inta + 1 ;
}
if ( bet - intb > step
) {
intb = intb + 1 ;
}
if ( gam - intg > step
) {
intg = intg + 1 ;
}
setCoordinateEulerAngle( COORD
[n-4
], q*inta
, q*intb
, q*intg
) ;
}
}
}
void Movie
( double anglepf
, bool movie
) {
int g = -1 ;
bool tstate = INCREASE_T
, preliminary = !movie ;
double unit = 1.0/3.0 ; // 時間の単位
int open =
newVector( o
, 0.5
, o
) ;
if ( Motion
( open
) ) {
setGraphics3DColor( RENDERER
, 0
, 0
, 0
, 255
) ;
}
SetTRange
( open
, o
, 0.5
) ;
if ( Motion
( open
) ) {
double t = Linear
( open
, tstate
) ;
int c = 255*t ;
setGraphics3DColor( RENDERER
, c
, c
, c
, 255
) ;
}
if ( T == o && preliminary
) {
START_T =
getVectorY( open
) ;
}
int time =
newVector( START_T
, START_T
, o
) ;
// animation ここから
SetTRange
( time
, o
, 3 * unit
) ;
if ( Motion
( time ) ) {
if ( Border0
( time ) ) {
setGraphics3DColor( RENDERER
, 255
, 255
, 255
, 255
) ;
setLightBrightness( AMBIENT_LIGHT
, o
) ;
setLightBrightness( LIGHT1
, o
) ;
setLightBrightness( LIGHT2
, o
) ;
for ( int i=0; i<
length( COORD
); i++
) {
SetCoordinateEulerAngle
( COORD
[i
], O
) ;
}
for ( int i=0; i<10; i++
) {
SetFacesDiamondSpaceFiller
( TR00
, i
, o
) ;
SetPolygonColors
( TR00
, i
, Color
( a
, a
, a
), OPACITY
[0
] ) ;
}
}
int a0 =
newVector( PI/4
, o
, o
), ax =
newVector( o
, o
, a
) ;
int x0
, v =
newVector( l
, o
, o
) ;
double t = Linear
( time
, tstate
) ;
double angle = -PI/4 ;
for ( int i=0; i<10; i++
) {
if ( i < 4
) {
x0 = GetRotZVector
( v
, PI/2 * i
) ;
ScaleVector
( x0
, t
) ;
RotateCoordinate
(
CD
[i
], x0
, a0
, angle
, ax
, x0
, RENDERER
, COORD
[0
]
) ;
SetFacesDiamondSpaceFiller
( TR00
, i
, l*t
) ;
} else {
SetCoordinateLocationAttitude
( CD
[i
], O
, O
) ;
SetFacesDiamondSpaceFiller
( TR00
, i
, o
) ;
}
}
}
SetTRange
( time
, 1 * unit
, 2 * unit
) ;
g ++ ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
if ( Border0
( time ) && preliminary
) {
int v
[ ] = GetVectors4FacesSymmetry
( Slv*l
) ;
for ( int i=0; i<4; i++
) {
SetVectorsCoordinateLocationAttitude
( X
[g
][i
], A
[g
][i
], CD
[i
] ) ;
setVector( X
[g+1
][i
], v
[i
] ) ;
}
}
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g
][i
], X
[g+1
][i
], t
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRange
( time
, o
, 1 * unit
) ;
g ++ ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
if ( Border0
( time ) && preliminary
) {
int v
[ ] = GetVectors4FacesSymmetry
( l/2
) ;
for ( int i=0; i<4; i++
) {
setVector( X
[g+1
][i
], v
[i
] ) ;
A
[g
][i
] = GetVectorCoordinateEulerAngle
( CD
[i
] ) ;
}
}
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g
][i
], X
[g+1
][i
], t/2
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRange
( time
, 1*unit
, 1 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g+1
][i
], X
[g
][i
], a/2 + t/2
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRange
( time
, o
, 2 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
setCoordinateEulerAngle( COORD
[0
], PI/2
, PI/4 * t
, -PI/2
) ;
rotXCoordinate( COORD
[0
], -
atan( ISlv
) * t
) ;
}
SetTRange
( time
, o
, 1 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g
][i
], X
[g+1
][i
], t/2
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRange
( time
, 1 * unit
, 1 * unit
) ;
int rot00 =
newVector( time ) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g+1
][i
], X
[g
][i
], a/2 + t/2
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRange
( time
, o
, 2 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g
][i
], X
[g+1
][i
], t
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRangeRight
( rot00
, time ) ;
SetTRange
( time
, 2 * unit
, 12 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
double s = Slope
( t
, o
, a/5
) ;
double angle = 8*PI * t ;
int xt
, ax =
newVector( a
, a
, -a
) ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g+1
][i
], X
[g
][i
], s
) ;
RotateCoordinate
(
CD
[i
], xt
, A
[g
][i
], angle
, ax
, xt
, RENDERER
, COORD
[0
]
) ;
}
s = Slope
( t
, a/4
, a-a/4
) ;
double s1 = Slope
( t
, 6*a/7
, a/7
) ;
angle = 6*PI * s ;
setVector( ax
, a
, -a
, o
) ;
int v
[ ] = GetVectors6FacesSymmetry
( 2*l
), sa ;
for ( int i=4; i<10; i++
) {
if ( Border0
( time ) && preliminary
) {
rotZCoordinate( CD
[i
], -3*PI/4
) ;
A
[g
][i
] = GetVectorCoordinateEulerAngle
( CD
[i
] ) ;
}
sa = GetScaleVector
( A
[g
][i
], ( 1 - s1
) ) ;
RotateCoordinate
(
CD
[i
], v
[i-4
], sa
, angle
, ax
, v
[i-4
], RENDERER
, COORD
[0
]
) ;
SetFacesDiamondSpaceFiller
( TR00
, i
, l*s
) ;
}
}
SetTRange
( time
, 3 * unit
, o
) ;
int rot10 =
newVector( time ) ;
SetTRange
( time
, 3 * unit
, 12 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
setLightBrightness( AMBIENT_LIGHT
, 0.5 * t
) ;
setLightBrightness( LIGHT1
, 0.2 * t
) ;
setLightBrightness( LIGHT2
, 0.5 * t
) ;
}
SetTRange
( time
, 2 * unit
, 4 * unit
) ;
if ( Motion
( time ) ) {
setLightBrightness( AMBIENT_LIGHT
, 0.5
) ;
setLightBrightness( LIGHT1
, 0.2
) ;
setLightBrightness( LIGHT2
, 0.5
) ;
double t = Linear
( time
, tstate
) ;
int c0
[ ] = Color
( a
, a
, a
), c1
[ ] = Color
( o
, o
, a
) ;
int c
[ ] = MixedColor
( c0
, c1
, t
) ;
for ( int i=0; i<4; i++
) {
SetPolygonColors
( TR00
, i
, c
, OPACITY
[0
] ) ;
SetFacesDiamondSpaceFiller
( TR00
, i
, a - d^-6
) ;
}
}
SetTRange
( time
, o
, 4 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<4; i++
) {
xt = GetInternallyDividingVector
( X
[g
][i
], X
[g+1
][i
], t
) ;
SetCoordinateLocationAttitude
( CD
[i
], xt
, A
[g
][i
] ) ;
}
}
SetTRange
( time
, 4 * unit
, 12 * unit
) ;
SetTRangeRight
( rot10
, time ) ;
SetTRange
( time
, 0 * unit
, 12 * unit
) ;
int rot01 =
newVector( getVectorX( time ) + 4*unit
, o
, o
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int c0
[ ] = Color
( a
, a
, a
), c1
[ ] = Color
( a
, o
, a
) ;
int c
[ ] = MixedColor
( c0
, c1
, t
) ;
for ( int i=4; i<10; i++
) {
SetPolygonColors
( TR00
, i
, c
, OPACITY
[0
] ) ;
SetFacesDiamondSpaceFiller
( TR00
, i
, a - d^-6
) ;
}
}
SetTRangeRight
( rot01
, time ) ;
SetTRange
( time
, o
, 5 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
double angle = PI/2 * t ;
int ax =
newVector() ;
for ( int i=4; i<10; i++
) {
if ( Border0
( time ) && preliminary
) {
X
[g
][i
] = GetVectorCoordinateOrigin
( CD
[i
] ) ;
}
if ( ( i == 4
) ||
( i == 10
) ){
setVector( ax
, o
, a
, o
) ;
} else if ( ( i == 5
) ||
( i == 7
) ) {
setVector( ax
, a
, o
, o
) ;
} else {
setVector( ax
, o
, o
, a
) ;
}
RotateCoordinate
(
CD
[i
], X
[g
][i
], O
, angle
, ax
, X
[g
][i
], RENDERER
, COORD
[0
]
) ;
}
}
SetTRange
( time
, o
, 5 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=4; i<10; i++
) {
if ( Border0
( time ) && preliminary
) {
A
[g
][i
] = GetVectorCoordinateEulerAngle
( CD
[i
] ) ;
}
xt = GetScaleVector
( X
[g
][i
], a - t/2
) ;
setCoordinateOrigin( CD
[i
], xt
) ;
if ( Border1
( time ) && preliminary
) {
X
[g+1
][i
] = GetVectorCoordinateOrigin
( CD
[i
] ) ;
}
}
}
SetTRange
( time
, 4 * unit
, 4 * unit
) ;
int rot02 =
newVector( time ) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int c
[ ] = Color
( o
, o
, a
) ;
int opacity = OPACITY
[0
] *
( 1 - 0.7*t
) ;
for ( int i=0; i<4; i++
) {
SetPolygonColors
( TR00
, i
, c
, opacity
) ;
}
}
SetTRange
( time
, 4 * unit
, 4 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int c
[ 3
], opacity ;
for ( int i=0; i<10; i++
) {
if ( i < 4
) {
c = Color
( o
, o
, a
) ;
opacity = OPACITY
[0
] *
( 0.3 + 0.7*t
) ;
} else {
c = Color
( a
, o
, a
) ;
opacity = OPACITY
[0
] *
( 1 - 0.7*t
) ;
}
SetPolygonColors
( TR00
, i
, c
, opacity
) ;
SetCoordinateLocationAttitude
( CD
[i
], X
[g+1
][i
], A
[g
][i
] ) ;
}
}
SetTRange
( time
, 4 * unit
, 4 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int c
[ ] = Color
( a
, o
, a
) ;
int opacity = OPACITY
[0
] *
( 0.3 + 0.7*t
) ;
for ( int i=4; i<10; i++
) {
SetPolygonColors
( TR00
, i
, c
, opacity
) ;
}
}
SetTRange
( time
, 4 * unit
, 4 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<10; i++
) {
xt = GetInternallyDividingVector
( X
[g+1
][i
], X
[g
][i
], t
) ;
setCoordinateOrigin( CD
[i
], xt
) ;
}
}
SetTRange
( time
, 4 * unit
, 4 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
int xt ;
for ( int i=0; i<10; i++
) {
xt = GetInternallyDividingVector
( X
[g
][i
], X
[g+1
][i
], t
) ;
setCoordinateOrigin( CD
[i
], xt
) ;
}
}
SetTRange
( time
, 2 * unit
, 4 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
setLightBrightness( AMBIENT_LIGHT
, 0.5 *
( 1 - t
) ) ;
setLightBrightness( LIGHT1
, 0.2 *
( 1 - t
) ) ;
setLightBrightness( LIGHT2
, 0.5 *
( 1 - t
) ) ;
for ( int i=0; i<10; i++
) {
SetCoordinateLocationAttitude
( CD
[i
], X
[g+1
][i
], A
[g
][i
] ) ;
}
}
SetTRangeRight
( rot02
, time ) ;
SetTRange
( time
, 1 * unit
, 12 * unit
) ;
int rot11 =
newVector( time ) ;
if ( Motion
( time ) ) {
setLightBrightness( AMBIENT_LIGHT
, o
) ;
setLightBrightness( LIGHT1
, o
) ;
setLightBrightness( LIGHT2
, o
) ;
for ( int i=0; i<10; i++
) {
SetCoordinateLocationAttitude
( CD
[i
], X
[g+1
][i
], A
[g
][i
] ) ;
}
}
SetTRange
( time
, 3 * unit
, 3 * unit
) ;
if ( Motion
( time ) ) {
double t = Linear
( time
, tstate
) ;
setLightBrightness( AMBIENT_LIGHT
, 0.5 * t
) ;
setLightBrightness( LIGHT1
, 0.2 * t
) ;
setLightBrightness( LIGHT2
, 0.5 * t
) ;
for ( int i=0; i<10; i++
) {
SetFacesDiamondSpaceFiller
( TR00
, i
, a - d^-6
) ;
SetCoordinateLocationAttitude
( CD
[i
], X
[g+1
][i
], A
[g
][i
] ) ;
if ( i < 4
) {
SetPolygonColors
( TR00
, i
, Color
( o
, o
, a
), OPACITY
[0
] ) ;
} else {
SetPolygonColors
( TR00
, i
, Color
( a
, o
, a
), OPACITY
[0
] ) ;
}
}
}
// COORDの回転など
if ( Motion
( rot00
) ) {
double t = Linear
( rot00
, tstate
) ;
setCoordinateEulerAngle( COORD
[0
], PI/2
, PI/4
, -PI/2
) ;
rotXCoordinate( COORD
[0
], -
atan( ISlv
) + PI * t
) ;
} else if ( Motion
( rot01
) ){
double t = Linear
( rot01
, tstate
) ;
setCoordinateEulerAngle( COORD
[0
], PI/2
, PI/4 *
( 1 - t
), -PI/2
) ;
rotXCoordinate( COORD
[0
], ( -
atan( ISlv
) + PI
) *
( 1 - t
) );
} else if ( Motion
( rot02
) ) {
double t = Sin
( rot02
, tstate
) ;
setCoordinateEulerAngle( COORD
[0
], o
, -10*PI*t
, o
) ;
}
if ( Motion
( rot10
) ) {
double t = Linear
( rot10
, tstate
) ;
double s1 = VelvetySlope
( t
, o
, 2*a/5
) ;
double s2 = VelvetySlope
( t
, 3*a/5
, 2*a/5
) ;
double anglet = -PI*s1 - PI*s2 ;
setCoordinateEulerAngle( COORD
[1
], PI/2
, anglet
, -PI/2
) ;
} else if ( Motion
( rot11
) ) {
double t = Linear
( rot11
, tstate
) ;
double s = Slope
( t
, 3*a/4
, a/4
) ;
setCoordinateEulerAngle( COORD
[1
], PI/2
, -17*PI/4 * t
, -PI/2
) ;
rotXCoordinate( COORD
[1
], ( atan( ISlv
) ) * s
) ;
}
// 終状態
if ( T >= END_T
) {
setCoordinateEulerAngle( COORD
[1
], PI/2
, -PI/4
, -PI/2
) ;
rotXCoordinate( COORD
[1
], ( atan( ISlv
) ) ) ;
setLightBrightness( AMBIENT_LIGHT
, 0.5
) ;
setLightBrightness( LIGHT1
, 0.2
) ;
setLightBrightness( LIGHT2
, 0.5
) ;
for ( int i=0; i<10; i++
) {
SetFacesDiamondSpaceFiller
( TR00
, i
, a - d^-6
) ;
SetCoordinateLocationAttitude
( CD
[i
], X
[g+1
][i
], A
[g
][i
] ) ;
if ( i < 4
) {
SetPolygonColors
( TR00
, i
, Color
( o
, o
, a
), OPACITY
[0
] ) ;
} else {
SetPolygonColors
( TR00
, i
, Color
( a
, o
, a
), OPACITY
[0
] ) ;
}
}
}
// animation ここまで
// 終了時刻の調整
if ( T == o && preliminary
) {
double dend =
getVectorY( time ) ;
double cycle = 1 /
( anglepf/
( 2*PI
) * FPS
) ;
if ( cycle -
(int
)( cycle
) < d^-8
) {
cycle =
(int
)( cycle
) ;
} else {
cycle =
(int
)( cycle
) + 1 ;
}
double rotn =
( dend - START_T
) / cycle ;
ROT_N = rotn ;
if ( ROT_N < rotn
) {
ROT_N = ROT_N + 1 ;
}
END_T = START_T +
(int
)( cycle
) * ROT_N ;
ADDED_T = END_T - dend ;
}
// 座標系位置、姿勢のセット数の確定
if ( T == o && preliminary
) {
LENGTH = g + 2 ;
}
}