encode Shift_JIS ;
import Graphics ;
import Graphics3D ;
import GUI ;
import Math ;
void main
( string args
[] ){
TITLE = "ペンタグラムと小星型十二面体" ;
int winw = 256*2.75
, winh = 256*2.75
, winx = 70 ;
int bgcolor
[ ] = Color
( a
) ;
hide();
Set3DGraphics
( winw
, winh
, winx
, bgcolor
) ;
SetLights
();
SetCoordinates
();
SetElements
();
PrepareStage
();
/* animation loop */
int picture_save_number = 1 * 10000 ;
int loop_periodic_time = 1000 / FPS ;
bool loop_termination = false ;
while ( KEEP_LOOP
){
T += STEP ;
COUNT ++ ;
if ( COUNT % 100 == 0
) {
print( (COUNT/100
) + "
, "
);
}
ForwardMotion
(); // アニメーション
if ( CREATE_GUI
) {
CreateGuiElements
();
CREATE_GUI = false ;
TURN_GUI = true ;
}
PaintGraphics
( loop_periodic_time
);
if ( SAVE_A_PICTURE
) {
SaveImagePNG
( picture_save_number
);
}
loop_termination =
( PICTURE_NUMBER == PICTURE_END_NUMBER
) ;
if ( loop_termination
) {
ExitLoopOverImageLimit
();
}
}
exit();
}
/*
import */
/* NUMERIC */
double o = 0.0
, a = 1.0 ;
double d = 0.1 ;
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
, R8 = 8 ;
/* 3DGRAPHICS */
string TITLE;
int MAIN_GRAPHICS
, MAIN_WINDOW
, MAIN_DISPLAY_LABEL
, RENDERER ;
int WIDTH
, HEIGHT
, WINDOW_POSITION_X ;
{
int n = 256 ;
WIDTH = n * 2.75 ; WIDTH = n * 4 ;
HEIGHT = n * 2.75 ; HEIGHT = n * 3 ;
WINDOW_POSITION_X = 70 ; WINDOW_POSITION_X = 1910 - WIDTH ;
}
void Set3DGraphics
( int w
, int h
, int x
, int bgcolor
[ ] ) {
WIDTH = w ;
HEIGHT = h ;
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( WIDTH
, HEIGHT
, MAIN_GRAPHICS
) ;
MAIN_WINDOW =
newWindow(
WINDOW_POSITION_X
, 0
, WIDTH + framewidth_x
, HEIGHT + framewidth_y
, TITLE
) ;
MAIN_DISPLAY_LABEL =
newGraphicsLabel( 0
, 0
, WIDTH
, HEIGHT
, MAIN_GRAPHICS
) ;
addComponent( MAIN_DISPLAY_LABEL
, MAIN_WINDOW
);
setGraphics3DDefaultEventHandler( RENDERER
, MAIN_DISPLAY_LABEL
);
setGraphics3DColor( RENDERER
, bgred
, bggreen
, bgblue
, bgalpha
);
}
/* GUI */
void onWindowClose( int id
) {
KEEP_LOOP = false ;
}
void onKeyDown( int id
, string key
){
if ( key == "SPACE"
) {
if ( SAVE_A_PICTURE
) {
SAVE_A_PICTURE = false ;
alert( PICTURE_NUMBER + " 枚目までで画像の保存を中止しました。"
);
} else {
alert( ( PICTURE_NUMBER+1
) + " 枚目以降の画像を保存します。"
);
SAVE_A_PICTURE = true ;
}
}
}
void PaintGraphics
( int sleeptime
) {
sleep( sleeptime
);
paintGraphics3D( RENDERER
);
paintComponent( MAIN_DISPLAY_LABEL
);
paintComponent( MAIN_WINDOW
);
}
void SavePicture
( int picid
) {
int picnumber = 0 ;
PICTURE_NUMBER = PICTURE_NUMBER + 1 ;
picnumber = picid + PICTURE_NUMBER ;
exportGraphics(
MAIN_GRAPHICS
, "./movie/0" + picnumber + ".png"
, "PNG"
) ;
}
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 ;
}
/* 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 ;
}
// 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
( out of range
, 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
) ;
}
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 ;
}
/* 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
] );
}
void SetPolygonColor
( int id
, int c
[ ], int opc
) {
setPolygonColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
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
] ) ;
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
);
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 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
, double ea
[ ] ) {
setCoordinateEulerAngle( cd
, ea
[0
], ea
[1
], ea
[2
] );
}
*/
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 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
] ) ;
}
}
}
/* MOTION */
double GetLinearTime
( int v
) {
double t0 =
getVectorX( v
) ;
double t1 =
getVectorY( v
) ;
double t;
if ( T < t0
) {
t = 0.0 ;
} else if ( T < t1 - STEP
) {
t =
( T - t0
) /
( t1 - t0 - STEP
) ;
} else {
t = 1.0 ;
}
return t ;
}
double GetSmoothTime
( int v
, double p
) {
// p=0でsin
, pはだいたい0.7くらいまで
double t0 =
getVectorX( v
) ;
double t1 =
getVectorY( v
) ;
double t;
if ( T < t0
) {
t = 0.0 ;
} else if ( T < t1 - STEP
) {
t =
( T - t0
) /
( t1 - t0 - STEP
) ;
} else {
t = 1.0 ;
}
double value ;
if ( p > 0.0
) {
if ( t < 0.5
) {
double u = 2 *
( 1.0 - t
) - 1.0 ;
double s =
( 1.0 + p
)/
( 2*p
)
*
( 1.0 -
sqrt( 1.0 - 4*p/
( ( 1.0 + p
)^2
) * u
) ) ;
value =
( 1.0 -
sin( PI/2 * s
) ) / 2 ;
} else {
double u = 2 * t - 1.0 ;
double s =
( 1.0 + p
)/
( 2*p
)
*
( 1.0 -
sqrt( 1.0 - 4*p/
( ( 1.0 + p
)^2
) * u
) ) ;
value =
( 1.0 +
sin( PI/2 * s
) ) / 2 ;
}
} else if ( p == 0.0
) {
if( t < 0.5
) {
double u = 2 *
( 1.0 - t
) - 1.0 ;
value =
( 1.0 -
sin( PI/2 * u
) ) / 2 ;
} else {
double u = 2 * t - 1.0 ;
value =
( 1.0 +
sin( PI/2 * u
) ) / 2 ;
}
}
return value ;
}
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
) ;
}
// 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 = GetLinearTime
( v
) ;
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 = GetLinearTime
( v
) ;
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 = GetLinearTime
( v
) ;
int opacity = 255 -
( 255 - endopacity
) * t ;
setPolygonColor( polygon
, r
, g
, b
, opacity
);
}
}
// text
string TEXT_RUSEN = "http://rusen.seesaa.net" ;
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 = GetLinearTime
( v
) ;
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 = GetLinearTime
( v
) ;
int c = 255 *
( a - t
) ;
setPolygonColor( TEXT
, c
, c
, c
, 255
) ;
}
SetTRange
( v
, o
, 2.0
);
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
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 = GetLinearTime
( v
) ;
int opacity = 255*t ;
setPolygonColor( TEXT
, 255
, 255
, 255
, opacity
);
}
SetTRange
( v
, 5.0
, 5.0
);
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
int opacity = 255 *
( a - t
) ;
setPolygonColor( TEXT
, 255
, 255
, 255
, opacity
);
}
}
/* 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 ;
}
/* GEOMETRY */
// antiprism
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 {
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
// 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 ;
}
// 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 ;
}
// 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 ;
}
/* set lights */
int AMBIENT_LIGHT = newAmbientLight
( o
, o
, o
, o
) ;
int LIGHT0 =
newPointLight( o
, o
, o
, o
) ;
int LIGHT1 =
newLight( -0.48
, 0.1
, 0.84
, o
) ;
int LIGHT2 =
newLight( 0.2
, 0.52
, -0.1
, o
) ;
void SetLights
() {
double power = 0.8 ;
SetAmbientLight
( AMBIENT_LIGHT
, o
, o
, o
, power
, RENDERER
);
}
/* create elements
(polygnのみ
) */
void SetElements
() {
SetElementOptions
();
AddElements
();
}
int NG = 1 ; // group の数
int Q11
[ NG
][ S12
][ R5*2
] ; // quadrangl
, pentagon
, 1st
int Q12
[ NG
][ S12
][ R5*2
] ; // quadrangl
, pentagon
, 2nd
int Q21
[ NG
][ S12
][ R5*2
] ; // quadrangl
, star
, 1st
int Q22
[ NG
][ S12
][ R5*2
] ; // quadrangl
, star
, 2nd
int Q23
[ NG
][ S12
][ R5*2
] ; // quadrangl
, star
, 3rd
, between 1st and 2nd
int L11
[ NG
][ S12
][ R5
][ 3
] ; // line
, star
, 1st
int L12
[ NG
][ S12
][ R5
][ 4
] ; // line
, star
, 2nd
for ( int i=0; i<
length( Q11
)[2
]; i++
) {
for ( int j=0; j<
length( Q11
)[1
]; j++
) {
for ( int k=0; k<
length( Q11
)[0
]; k++
) {
Q11
[i
][j
][k
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
Q12
[i
][j
][k
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
Q21
[i
][j
][k
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
Q22
[i
][j
][k
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
Q23
[i
][j
][k
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
if ( k < R5
) {
for ( int l=0; l<
length( L12
)[0
]; l++
) {
if ( l <
length( L11
)[0
] ) {
L11
[i
][j
][k
][l
] =
newLinePolygon( O
, O
, a/70
) ;
}
L12
[i
][j
][k
][l
] =
newLinePolygon( O
, O
, a/70
) ;
}
}
}
}
}
void RotSystems12FacesSymmetry
( int cd
[ ][ ], int n
, double spin
) {
int len =
length( cd
)[0
] ;
int dummycd
[ len
], sa
[ len
] ;
for ( int i=0; i<len; i++
) {
dummycd
[i
] =
newCoordinate() ;
}
double angleff = PI - 2 *
atan( IGld
) ;
for ( int i=0; i<S12; i++
) {
if ( ( i == 0
) ||
( i == 11
) ) {
rotXCoordinate( dummycd
[i
], PI
) ;
} else {
rotYCoordinate( dummycd
[i
], PI
) ;
rotXCoordinate( dummycd
[i
], angleff
) ;
double anglei = 2*PI/R5 *
( ( i -1
) % 5
) ;
rotYCoordinate( dummycd
[i
], anglei
) ;
}
if ( i <= 5
) {
rotZCoordinate( dummycd
[i
], PI
) ;
} else {
rotYCoordinate( dummycd
[i
], PI/R5
) ;
}
spinYCoordinate( dummycd
[i
], spin
) ;
sa
[i
] = GetVectorCoordinateEulerAngle
( dummycd
[i
] ) ;
SetCoordinateEulerAngle
( cd
[n
][i
], sa
[i
] ) ;
}
}
void SetPolygons5gon
( int q1
[ ][ ][ ], int q2
[ ][ ][ ], int n
, double prad
) {
int v
[ ] = Get3VectorsNGon
( 5
, prad
) ;
int mid = GetMiddlePointVector
( v
[1
], v
[2
] ) ;
int u
[ R5
][ 2
];
int m
[ R5
], um
[ R5
][ 2
], mm
[ R5
] ;
for ( int i=0; i<R5; i++
) {
u
[i
][0
] = GetRotYVector
( v
[1
], 2*PI/R5 * i
) ;
u
[i
][1
] = GetRotYVector
( v
[2
], 2*PI/R5 * i
) ;
m
[i
] = GetRotYVector
( mid
, 2*PI/R5 * i
) ;
um
[i
][0
] = GetScaleVector
( u
[i
][0
], 2*a/3
) ;
um
[i
][1
] = GetScaleVector
( u
[i
][1
], 2*a/3
) ;
mm
[i
] = GetScaleVector
( m
[i
], 2*a/3
) ;
}
for ( int i=0; i<S12; i++
) {
for ( int j=0; j<R5; j++
) {
setPolygonVector( q1
[n
][i
][2*j
], O
, um
[j
][0
], mm
[j
], O
) ;
setPolygonVector( q1
[n
][i
][2*j+1
], O
, mm
[j
], um
[j
][1
], O
) ;
setPolygonVector( q2
[n
][i
][2*j
], mm
[j
], um
[j
][0
], u
[j
][0
], m
[j
] ) ;
setPolygonVector( q2
[n
][i
][2*j+1
], m
[j
], u
[j
][1
], um
[j
][1
], mm
[j
] ) ;
}
}
}
void SetPolygons5gram
( // ある星型化率の pentagon
int l1
[ ][ ][ ][ ], int l2
[ ][ ][ ][ ],
int q1
[ ][ ][ ], int q2
[ ][ ][ ], int q3
[ ][ ][ ],
int n
, double prad
, double dist
, double spin
, double stellation
) {
int v
[ ] = Get3VectorsNGon
( 5
, prad
) ;
int mid = GetMiddlePointVector
( v
[1
], v
[2
] ) ;
int top = GetScaleVector
( mid
, 2 * Gld
) ;
int u
[ R5
][ 2
] ;
int m
[ R5
], t
[ R5
] ;
for ( int i=0; i<R5; i++
) {
u
[i
][0
] = GetRotYVector
( v
[1
], 2*PI/R5 * i
) ;
u
[i
][1
] = GetRotYVector
( v
[2
], 2*PI/R5 * i
) ;
m
[i
] = GetRotYVector
( mid
, 2*PI/R5 * i
) ;
t
[i
] = GetRotYVector
( top
, 2*PI/R5 * i
) ;
}
double dssd = GetInradiusDodecahedron
( prad
) ; // small stellated dodecahedron の場合
if ( spin == o
) {
double ds = 2*Gld * dssd ; // pentagram が dodecahedron 稜心を結んでできた形になる場合
if ( dist > ds
) {
if ( abs( a - stellation
) <= d^10
) {
for ( int i=0; i<S12; i++
) {
for ( int j=0; j<R5; j++
) {
setPolygonVector( q1
[n
][i
][2*j
], m
[j
], u
[j
][0
], t
[j
], t
[j
] ) ;
setPolygonVector( q1
[n
][i
][2*j+1
], u
[j
][1
], m
[j
], t
[j
], t
[j
] ) ;
setPolygonVector( q2
[n
][i
][2*j
], O
, O
, O
, O
) ;
setPolygonVector( q2
[n
][i
][2*j+1
], O
, O
, O
, O
) ;
setPolygonVector( q3
[n
][i
][2*j
], O
, O
, O
, O
) ;
setPolygonVector( q3
[n
][i
][2*j+1
], O
, O
, O
, O
) ;
setPolygonVector( l1
[n
][i
][j
][0
], u
[j
][0
], t
[j
] ) ;
setPolygonVector( l1
[n
][i
][j
][1
], u
[j
][1
], t
[j
] ) ;
setPolygonVector( l1
[n
][i
][j
][2
], u
[j
][0
], u
[j
][1
] ) ;
for ( int k=0; k<
length( l2
)[0
]; k++
) {
setPolygonVector( l2
[n
][i
][j
][k
], O
, O
) ;
}
}
}
} else if ( stellation < a
) {
int stel
[ R5
][ 2
], stelmid
[ R5
] ;
for ( int i=0; i<R5; i++
) {
stel
[i
][0
]
= GetInternallyDividingVector
( u
[i
][0
], t
[i
], stellation
) ;
stel
[i
][1
]
= GetInternallyDividingVector
( u
[i
][1
], t
[i
], stellation
) ;
stelmid
[i
]
= GetInternallyDividingVector
( m
[i
], t
[i
], stellation
) ;
}
for ( int i=0; i<S12; i++
) {
for ( int j=0; j<R5; j++
) {
setPolygonVector(
q1
[n
][i
][2*j
], m
[j
], u
[j
][0
], stel
[j
][0
], stelmid
[j
]
) ;
setPolygonVector(
q1
[n
][i
][2*j+1
], u
[j
][1
], m
[j
], stelmid
[j
], stel
[j
][1
]
) ;
setPolygonVector( q2
[n
][i
][2*j
], O
, O
, O
, O
) ;
setPolygonVector( q2
[n
][i
][2*j+1
], O
, O
, O
, O
) ;
setPolygonVector( q3
[n
][i
][2*j
], O
, O
, O
, O
) ;
setPolygonVector( q3
[n
][i
][2*j+1
], O
, O
, O
, O
) ;
setPolygonVector( l1
[n
][i
][j
][0
], u
[j
][0
], stel
[j
][0
] ) ;
setPolygonVector( l1
[n
][i
][j
][1
], u
[j
][1
], stel
[j
][1
] ) ;
setPolygonVector( l1
[n
][i
][j
][2
], u
[j
][0
], u
[j
][1
] ) ;
setPolygonVector( l2
[n
][i
][j
][0
], stel
[j
][0
], stel
[j
][1
] ) ;
for ( int k=1; k<
length( l2
)[0
]; k++
) {
setPolygonVector( l2
[n
][i
][j
][k
], O
, O
) ;
}
}
}
}
} else {
if ( dist >= dssd
) {
double s =
( dist - ds
) /
( dssd - ds
) ; // crss section parameter
int cross
[ R5
][ 2
], crossmid
[ R5
], stel
[ R5
][ 2
], stelmid
[ R5
] ;
int crstm
[ R5
][ 2
], mmm
[ R5
] ; // cross より上を2等分するため
for ( int i=0; i<R5; i++
) {
cross
[i
][0
] = GetInternallyDividingVector
( t
[i
], u
[i
][0
], s
) ;
cross
[i
][1
] = GetInternallyDividingVector
( t
[i
], u
[i
][1
], s
) ;
crossmid
[i
] = GetInternallyDividingVector
( t
[i
], m
[i
], s
) ;
stel
[i
][0
]
= GetInternallyDividingVector
( u
[i
][0
], t
[i
], stellation
) ;
stel
[i
][1
]
= GetInternallyDividingVector
( u
[i
][1
], t
[i
], stellation
) ;
stelmid
[i
]
= GetInternallyDividingVector
( m
[i
], t
[i
], stellation
) ;
crstm
[i
][0
]
= GetInternallyDividingVector
( cross
[i
][0
], stel
[i
][0
], 0.7
) ;
crstm
[i
][1
]
= GetInternallyDividingVector
( cross
[i
][1
], stel
[i
][1
], 0.7
) ;
mmm
[i
]
= GetInternallyDividingVector
( crossmid
[i
], stelmid
[i
], 0.7
) ;
}
if ( stellation >= a - s
) { // 星型化内で cross する場合
for ( int i=0; i<S12; i++
) {
for ( int j=0; j<R5; j++
) {
setPolygonVector( q1
[n
][i
][2*j
],
m
[j
], u
[j
][0
], cross
[j
][0
], crossmid
[j
]
) ;
setPolygonVector( q1
[n
][i
][2*j+1
],
u
[j
][1
], m
[j
], crossmid
[j
], cross
[j
][1
]
) ;
setPolygonVector( q2
[n
][i
][2*j
],
crossmid
[j
], cross
[j
][0
], crstm
[j
][0
], mmm
[j
]
) ;
setPolygonVector( q2
[n
][i
][2*j+1
],
cross
[j
][1
], crossmid
[j
], mmm
[j
], crstm
[j
][1
]
) ;
setPolygonVector( q3
[n
][i
][2*j
],
mmm
[j
], crstm
[j
][0
], stel
[j
][0
], stelmid
[j
]
) ;
setPolygonVector( q3
[n
][i
][2*j+1
],
crstm
[j
][1
], mmm
[j
], stelmid
[j
], stel
[j
][1
]
) ;
setPolygonVector(
l1
[n
][i
][j
][0
], u
[j
][0
], cross
[j
][0
]
) ;
setPolygonVector(
l1
[n
][i
][j
][1
], u
[j
][1
], cross
[j
][1
]
) ;
setPolygonVector(
l1
[n
][i
][j
][2
], u
[j
][0
], u
[j
][1
]
) ;
setPolygonVector(
l2
[n
][i
][j
][0
], stel
[j
][0
], stel
[j
][1
]
) ;
setPolygonVector(
l2
[n
][i
][j
][1
], cross
[j
][0
], stel
[j
][0
]
) ;
setPolygonVector(
l2
[n
][i
][j
][2
], cross
[j
][1
], stel
[j
][1
]
) ;
setPolygonVector(
l2
[n
][i
][j
][3
], cross
[j
][0
], cross
[j
][1
]
) ;
}
}
} else if ( stellation < a - s
) { // 星型化外で cross する場合
int stel
[ R5
][ 2
], stelmid
[ R5
] ;
for ( int i=0; i<R5; i++
) {
stel
[i
][0
]
= GetInternallyDividingVector
( u
[i
][0
], t
[i
], stellation
) ;
stel
[i
][1
]
= GetInternallyDividingVector
( u
[i
][1
], t
[i
], stellation
) ;
stelmid
[i
]
= GetInternallyDividingVector
( m
[i
], t
[i
], stellation
) ;
}
for ( int i=0; i<S12; i++
) {
for ( int j=0; j<R5; j++
) {
setPolygonVector(
q1
[n
][i
][2*j
], m
[j
], u
[j
][0
], stel
[j
][0
], stelmid
[j
]
) ;
setPolygonVector(
q1
[n
][i
][2*j+1
], u
[j
][1
], m
[j
], stelmid
[j
], stel
[j
][1
]
) ;
setPolygonVector( q2
[n
][i
][2*j
], O
, O
, O
, O
) ;
setPolygonVector( q2
[n
][i
][2*j+1
], O
, O
, O
, O
) ;
setPolygonVector( q3
[n
][i
][2*j
], O
, O
, O
, O
) ;
setPolygonVector( q3
[n
][i
][2*j+1
], O
, O
, O
, O
) ;
setPolygonVector( l1
[n
][i
][j
][0
], u
[j
][0
], stel
[j
][0
] ) ;
setPolygonVector( l1
[n
][i
][j
][1
], u
[j
][1
], stel
[j
][1
] ) ;
setPolygonVector( l1
[n
][i
][j
][2
], u
[j
][0
], u
[j
][1
] ) ;
setPolygonVector( l2
[n
][i
][j
][0
], stel
[j
][0
], stel
[j
][1
] ) ;
for ( int k=1; k<
length( l2
)[0
]; k++
) {
setPolygonVector( l2
[n
][i
][j
][k
], O
, O
) ;
}
}
}
}
}
}
}
}
int OPACITY
[ ] =
{ 255
, 10
, 30
} ;
float OPTION0
[ 6
], OPTION1
[ 6
];
{
float emissive = o ;
float diffractive = 0.5 ;
float diffuse = 0.9 ;
float ambient = 0.15 ;
float specularintensity = 0.6
, specularangle = PI/15 ;
OPTION0
[0
] = emissive ;
OPTION0
[1
] = diffractive ;
OPTION0
[2
] = diffuse ;
OPTION0
[3
] = ambient ;
OPTION0
[4
] = specularintensity ; OPTION0
[5
] = specularangle ;
OPTION1 = OPTION0 ;
OPTION1
[0
] = 0.9 ;
OPTION1
[3
] = 0.9 ;
OPTION1
[4
] = 0.4 ; OPTION1
[5
] = 1.5 ;
}
int COLOR
[ S12
][ 3
] ;
void SetElementOptions
() {
float r
, g
, b ;
int color
[ 3
] ;
for ( int i=0; i<
length( Q11
)[2
]; i++
) {
for ( int j=0; j<
length( Q11
)[1
]; j++
) {
if ( ( j == 0
) ||
( j == 7
) ||
( j == 9
) ) {
r = a ; g = o ; b = a/2 ;
} else if ( ( j == 1
) ||
( j == 4
) ||
( j == 11
) ) {
r = o ; g = 2*a/3 ; b = a ;
} else if ( ( j == 2
) ||
( j == 6
) ||
( j == 8
) ) {
r = a/2 ; g = a ; b = o ;
} else {
r = 1*a/3 ; g = o ; b = a ;
}
for ( int n=0; n<3; n++
) {
COLOR
[j
][n
] = Color
( r
, g
, b
)[n
] ;
}
color = Color
( r
, g
, b
) ;
for ( int k=0; k<
length( Q11
)[0
]; k++
) {
setPolygonSortOffset( Q12
[i
][j
][k
], -0.2*l
) ;
setPolygonCull( Q11
[i
][j
][k
], false
, false
) ;
setPolygonCull( Q12
[i
][j
][k
], false
, false
) ;
setPolygonCull( Q21
[i
][j
][k
], false
, false
) ;
setPolygonCull( Q22
[i
][j
][k
], false
, false
) ;
setPolygonCull( Q23
[i
][j
][k
], false
, false
) ;
SetPolygonColor
( Q11
[i
][j
][k
], color
, OPACITY
[0
] ) ;
SetPolygonColor
( Q12
[i
][j
][k
], color
, OPACITY
[0
] ) ;
SetPolygonColor
( Q21
[i
][j
][k
], color
, OPACITY
[0
] ) ;
SetPolygonColor
( Q22
[i
][j
][k
], color
, OPACITY
[1
] ) ;
SetPolygonColor
( Q23
[i
][j
][k
], color
, OPACITY
[1
] ) ;
if ( k <
length( L11
)[1
] ) {
for ( int l=0; l<
length( L12
)[0
]; l++
) {
if ( l <
length( L11
)[0
] ) {
SetPolygonColor
( L11
[i
][j
][k
][l
], color
, OPACITY
[2
] ) ;
}
SetPolygonColor
( L12
[i
][j
][k
][l
], color
, OPACITY
[2
] ) ;
}
}
SetPolygonSurface
( Q11
[i
][j
][k
], OPTION0
) ;
SetPolygonSurface
( Q12
[i
][j
][k
], OPTION0
) ;
SetPolygonSurface
( Q21
[i
][j
][k
], OPTION0
) ;
SetPolygonSurface
( Q22
[i
][j
][k
], OPTION1
) ;
SetPolygonSurface
( Q23
[i
][j
][k
], OPTION1
) ;
}
}
}
}
void AddElements
() {
int color
[ 3
];
addLight( LIGHT1
, RENDERER
, COORD
[length( COORD
)[0
]-1
] ) ;
addLight( LIGHT2
, RENDERER
, COORD
[length( COORD
)[0
]-1
] ) ;
setLightBrightness( LIGHT1
, 0.7
) ;
setLightBrightness( LIGHT2
, 0.3
) ;
double prad = o
, dist = GetInradiusDodecahedron
( l
), spin = o
, stellation = a ;
for ( int i=0; i<
length( Q11
)[2
]; i++
) {
RotSystems12FacesSymmetry
( CD
, i
, spin
) ;
SetPolygons5gon
( Q11
, Q12
, i
, prad
) ;
SetPolygons5gram
(
L11
, L12
,
Q21
, Q22
, Q23
,
i
, prad
, dist
, spin
, stellation
) ;
for ( int j=0; j<
length( Q11
)[1
]; j++
) {
SetCoordinateLocationYdirection
( CD
[i
][j
], dist
) ;
for( int k=0; k<
length( Q11
)[0
]; k++
) {
addPolygon( Q11
[i
][j
][k
], RENDERER
, CD
[i
][j
] ) ;
addPolygon( Q12
[i
][j
][k
], RENDERER
, CD
[i
][j
] ) ;
addPolygon( Q21
[i
][j
][k
], RENDERER
, CD
[i
][j
] ) ;
addPolygon( Q22
[i
][j
][k
], RENDERER
, CD
[i
][j
] ) ;
addPolygon( Q23
[i
][j
][k
], RENDERER
, CD
[i
][j
] ) ;
if ( k <
length( L11
)[1
] ) {
for ( int l=0; l<
length( L12
)[0
]; l++
) {
if ( l <
length( L11
)[0
] ) {
addPolygon( L11
[i
][j
][k
][l
], RENDERER
, CD
[i
][j
] ) ;
}
addPolygon( L12
[i
][j
][k
][l
], RENDERER
, CD
[i
][j
] ) ;
}
}
}
}
}
}
/* set coordinates */
int COORD
[ 7
];
int CD
[ NG
][ S12
]; //
for 12 faces
for ( int i=0; i<
length( COORD
)[0
]; i++
) {
COORD
[i
] =
newCoordinate() ;
}
for ( int i=0; i<
length( CD
)[1
]; i++
) {
for ( int j=0; j<
length( CD
)[0
]; j++
) {
CD
[i
][j
] =
newCoordinate() ;
}
}
void SetCoordinates
() {
PileCoordinate
( COORD
, RENDERER
);
for ( int i=0; i<
length( CD
)[1
]; i++
) {
for ( int j=0; j<
length( CD
)[0
]; j++
) {
addCoordinate( CD
[i
][j
], RENDERER
, COORD
[0
] );
}
}
}
/* set axes */
int AXIS
[ 10
];
{
float x
, y
, z ;
for ( int i=0; i<
length( AXIS
)[0
]; 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
, COORD
[0
] );
addModel( AXIS
[7
], RENDERER
, CD
[0
][0
] );
addModel( AXIS
[4
], RENDERER
, CD
[0
][1
] );
addModel( AXIS
[1
], RENDERER
, CD
[0
][2
] );
}
/* prepare stage */
double CAM_X0 = o;
double CAM_Y0 = o;
double CAM_Z0 = 16*l ;
float GRAPHIC_MAGNIFICATION = 1000.0 ;
double GRAPHIC_DISTANCE = 10.0 ;
int WORLD;
void PrepareStage
() {
setGraphics3DCenter( RENDERER
, WIDTH / 2
, HEIGHT / 2
);
setGraphics3DDistance( RENDERER
, GRAPHIC_DISTANCE
);
setGraphics3DMagnification( RENDERER
, GRAPHIC_MAGNIFICATION
);
setGraphics3DClipFront( RENDERER
, o
);
setGraphics3DClipBack( RENDERER
, -10000.0
);
WORLD =
getWorldCoordinate( RENDERER
);
setCoordinateOrigin( WORLD
, o
, o
, o
);
setCoordinateEulerAngle( WORLD
, o
, o
, o
);
setCameraOrigin( WORLD
, CAM_X0
, CAM_Y0
, CAM_Z0
);
setCameraEulerAngle( WORLD
, o
, o
, o
);
}
/* animation Loop except
ただし、ForwardMotion
() と CreateGuiElements
() 以外 */
bool KEEP_LOOP = true ;
bool SAVE_A_PICTURE = false ;
int COUNT = 0 ;
int FPS = 20 ; // frames / 1sec
int PICTURE_NUMBER = 0 ;
int PICTURE_END_NUMBER = 5000 ;
double T = o
, T0 = -100.0 ;
double STEP
, TIME_FLOW ;
{
TIME_FLOW = 1.0 ;
STEP = TIME_FLOW / FPS ;
}
/* create GUI elements */
int SETTING_WINDOW ;
int LABEL_SLIDER
[ 2
] ;
N =
length( LABEL_SLIDER
) ;
int SLIDER
[ N
] ;
string SLIDER_TEXT
[ N
] ;
double P
[ N
] = o
, P0
[ N
] ;
int CHECK_BOX
[ 2
] ;
N =
length( CHECK_BOX
) ;
string CHECK_TEXT
[ N
] ;
bool SPIN = true
, LIMIT = false ;
int LABEL_SELECT
[ 1
] ;
N =
length( LABEL_SELECT
) ;
int SELECT
[ N
] ;
string SELECT_TITLE
[ N
] ;
string SELECT_TEXT
[ N
][ 3
] ;
bool GET_TIME = false ;
bool TURN_GET_TIME = false ;
int OPACITY_INDEX = 0 ;
int FORMER_OPACITY_INDEX = 0 ;
SELECT_TITLE
[0
] = "星型化部分の透明度" ;
SELECT_TEXT
[0
][0
] = "ほぼ透明" ;
SELECT_TEXT
[0
][1
] = "半透明" ;
SELECT_TEXT
[0
][2
] = "不透明" ;
CHECK_TEXT
[0
] = "多面体の回転" ;
CHECK_TEXT
[1
] = "操作を4面に対してのみ行う" ;
SLIDER_TEXT
[0
] = "面と原点の距離変更" ;
SLIDER_TEXT
[1
] = "面の変形(正五角形 〜 五芒星)" ;
void CreateGuiElements
() {
// setting window
int sidewidth = 6 ;
int nsell =
length( SELECT
) ;
int nsel = nsell ;
int nsldl =
length( SLIDER
) ;
int nsld = nsldl ;
int lx = 15
, lw = 250 ;
int lh = 15 ;
int lyspace = 20 ;
int sliderx = lx
, sliderw = lw
, sliderh = 20
, slideryspace = 10 ;
int sliderlabely
[ nsldl
] ;
int slidery
[ nsld
] ;
int selectx = lx
, selectw = lw - sidewidth
, selecth = 20
, selectyspace = 10 ;
int selectlabely
[ nsell
] ;
int selecty
[ nsel
] ;
int check0x = lx
, check0w = lw
, check0h = lh
, check0yspace = 40;
int check0y ;
int check1x = lx
, check1w = lw
, check1h = lh
, check1yspace = 40 ;
int check1y ;
{
int initial_ly = 20;
check0y = initial_ly ;
for ( int i=0; i<nsel; i++
) {
selectlabely
[i
] = check0y + check0h + lyspace
+
( lyspace + lh + selectyspace + selecth
) * i ;
selecty
[i
] = selectlabely
[i
] + lh + selectyspace ;
}
check1y = selecty
[nsel-1
] + selecth + lyspace ;
for ( int i=0; i<nsld; i++
) {
sliderlabely
[i
] = check1y + check1h + lyspace
+
( lyspace + lh + slideryspace + sliderh
) * i ;
slidery
[i
] = sliderlabely
[i
] + lh + slideryspace ;
}
}
int wx = WINDOW_POSITION_X + WIDTH + 1 * sidewidth ;
int wy = 0 ;
int framewidth_y = 30 ;
int ww = lw + 2*lx + 2*sidewidth ;
int wh = slidery
[nsld-1
] + 75 ;
{
string wtext = "Setting Window" ;
SETTING_WINDOW =
newWindow( wx
, wy
, ww
, wh
, wtext
) ;
// select field
int lentex
[ ] =
length( SELECT_TEXT
) ;
int lentex0 = lentex
[0
] ;
for ( int i=0; i<nsel; i++
) {
LABEL_SELECT
[i
] =
newTextLabel(
lx
, selectlabely
[i
], lw
, lh
, SELECT_TITLE
[i
]
) ;
addComponent( LABEL_SELECT
[i
], SETTING_WINDOW
) ;
setComponentFontSize( LABEL_SELECT
[i
], 14
) ; // default 12
string text
[ lentex0
] ;
for ( int j=0; j<lentex0; j++
) {
text
[j
] = SELECT_TEXT
[i
][j
] ;
}
SELECT
[i
] =
newSelectField( selectx
, selecty
[i
], selectw
, selecth
, text
) ;
addComponent( SELECT
[i
], SETTING_WINDOW
) ;
}
// 一番上
CHECK_BOX
[0
] =
newCheckBox (
lx
, check0y
, lw
, check0h
, CHECK_TEXT
[0
], true
) ;
setComponentFontSize( CHECK_BOX
[0
], 14
) ; // default 12
addComponent( CHECK_BOX
[0
], SETTING_WINDOW
) ;
// スライダーの上
CHECK_BOX
[1
] =
newCheckBox (
lx
, check1y
, lw
, check1h
, CHECK_TEXT
[1
], false
) ;
setComponentFontSize( CHECK_BOX
[1
], 14
) ; // default 12
addComponent( CHECK_BOX
[1
], SETTING_WINDOW
) ;
// slider
for ( int i=0; i<nsld; i++
) {
LABEL_SLIDER
[i
] =
newTextLabel(
lx
, sliderlabely
[i
], lw
, lh
, SLIDER_TEXT
[i
]
) ;
setComponentFontSize( LABEL_SLIDER
[i
], 14
) ; // default 12
addComponent( LABEL_SLIDER
[i
], SETTING_WINDOW
) ;
double inivalue = o ;
if ( i == 1
) {
inivalue = a ;
}
SLIDER
[i
] =
newHorizontalSlider(
sliderx
, slidery
[i
], sliderw
, sliderh
, inivalue
) ;
addComponent( SLIDER
[i
], SETTING_WINDOW
) ;
}
P
[1
] = a ;
}
paintComponent( SETTING_WINDOW
) ;
}
/* event handlers */
void onSliderMove( int id
, double value
) {
double prad = l ;
double p0 = 1 +
( 2*Gld - 1
) *
getComponentValue( SLIDER
[0
] ) ;
double p1 =
getComponentValue( SLIDER
[1
] ) ;
P
[0
] = p0 * GetInradiusDodecahedron
( prad
) ;
P
[1
] = p1 ;
double dist = P
[0
], stellation = P
[1
], spin = o ;
float indexslider0 =
(int
)( 100*p0
) / 100.0 ;
float indexslider1 =
(int
)( 1000*p1
) / 10.0 ;
SLIDER_TEXT
[0
] = "面と原点の距離" +
(string
)indexslider0 + "倍 " ;
SLIDER_TEXT
[1
] = "面の変形" +
(string
)indexslider1 + " % " ;
for ( int i=0; i<
length( SLIDER_TEXT
); i++
) {
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
}
if ( ( TURN_GET_TIME &&
( ! LIMIT
) ) ||
( ( ! TURN_GET_TIME
) && LIMIT
) ) {
S12 = 4 ;
}
for ( int i=0; i<NG; i++
) {
RotSystems12FacesSymmetry
( CD
, i
, spin
) ;
SetPolygons5gon
( Q11
, Q12
, i
, prad
) ;
SetPolygons5gram
(
L11
, L12
,
Q21
, Q22
, Q23
,
i
, prad
, dist
, spin
, stellation
) ;
for ( int j=0; j<S12; j++
) {
SetCoordinateLocationYdirection
( CD
[i
][j
], dist
) ;
}
}
S12 = 12 ;
}
void onCheckBoxClick( int id
, bool state
){
if ( ! TURN_GET_TIME
) {
if ( id == CHECK_BOX
[0
] ) {
SPIN = state ;
} else {
LIMIT = state ;
GET_TIME = true ;
TURN_GET_TIME = true ;
}
}
}
void onSelectFieldClick( int id
, string text
){
if ( ! TURN_GET_TIME
) {
for ( int i=0; i<
length( SELECT_TEXT
)[0
]; i++
) {
if ( text == SELECT_TEXT
[0
][i
] ) {
if ( i != FORMER_OPACITY_INDEX
) {
OPACITY_INDEX = i ;
GET_TIME = true ;
TURN_GET_TIME = true ;
}
}
}
}
}
/* forward motion */
bool CREATE_GUI = false ;
bool TURN_GUI = false ;
double STOP_TIME ;
double GUI_UPTIME ;
void ForwardMotion
() {
int t =
newVector( o
, o
, o
) ; // x
,y成分がそれぞれmotion開始、終了時刻
double toprotrate ;
if ( SPIN
) {
toprotrate = 4/180.0 * PI ;
} else {
toprotrate = o ;
}
if ( (!TURN_GUI
) || TURN_GET_TIME
) {
DesignMotion
( t
, toprotrate
) ; // アニメーション
STOP_TIME =
getVectorY( t
) ; // motion終了時刻
GUI_UPTIME = STOP_TIME + 0.2 ;
CREATE_GUI =
( T >= GUI_UPTIME
) &&
( T < GUI_UPTIME + STEP
) ;
}
if ( T < GUI_UPTIME + 1000.0
) {
rotYCoordinate( COORD
[2
], toprotrate
) ;
}
}
int SO
[ NG
][ S12
]; //
system origin point
int SA
[ NG
][ S12
]; //
system Euler Angle
int RC
[ NG
][ S12
]; // rotation center vector
int AX
[ NG
][ S12
]; // rotation axis vector
for ( int i=0; i<NG; i++
) {
for ( int j=0; j<S12; j++
) {
SO
[i
][j
] =
newVector() ;
SA
[i
][j
] =
newVector() ;
RC
[i
][j
] =
newVector() ;
AX
[i
][j
] =
newVector() ;
}
}
int G =
newVector() ; // center of gravity
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
) ;
void DesignMotion
( int v
, double yrotation
) {
double start_t = 1.0 ;
double unit = 1.0 / 2.0 ; // 時間の単位
SetTRangeAbsolutely
( v
, start_t
, start_t
);
SetTRange
( v
, o
, STEP
) ;
if ( Moment
( v
) ) {
setCoordinateEulerAngle( COORD
[3
], o
, PI/2 - 2*
atan( IGld
), o
) ;
}
SetTRange
( v
, o
, 2*unit
);
if ( Motion
( v
) ) {
double prad = l ;
int w
[ ] = Get3VectorsNGon
( 5
, prad
) ;
int mid = GetMiddlePointVector
( w
[1
], w
[2
] ) ;
int top = GetScaleVector
( mid
, 2 * Gld
) ;
int u
[ R5
][ 2
] ;
int md
[ R5
], tp
[ R5
] ;
for ( int i=0; i<R5; i++
) {
u
[i
][0
] = GetRotYVector
( w
[1
], 2*PI/R5 * i
) ;
u
[i
][1
] = GetRotYVector
( w
[2
], 2*PI/R5 * i
) ;
md
[i
] = GetRotYVector
( mid
, 2*PI/R5 * i
) ;
tp
[i
] = GetRotYVector
( top
, 2*PI/R5 * i
) ;
}
double t = GetLinearTime
( v
) ;
int n = 0 ;
for ( int i=0; i<S12; i++
) {
for ( int j=0; j<R5; j++
) {
int mdt = GetInternallyDividingVector
( tp
[j
], md
[j
], t
) ;
int ut0 = GetInternallyDividingVector
( tp
[j
], u
[j
][0
], t
) ;
int ut1 = GetInternallyDividingVector
( tp
[j
], u
[j
][1
], t
) ;
setPolygonVector(
Q21
[n
][i
][2*j
], mdt
, ut0
, tp
[j
], mdt
) ;
setPolygonVector(
Q21
[n
][i
][2*j+1
], mdt
, tp
[j
], ut1
, mdt
) ;
setPolygonVector( L11
[n
][i
][j
][0
], ut0
, tp
[j
] ) ;
setPolygonVector( L11
[n
][i
][j
][1
], ut1
, tp
[j
] ) ;
setPolygonVector( L11
[n
][i
][j
][2
], ut0
, ut1
) ;
}
}
}
SetTRange
( v
, o
, STEP
) ;
if ( Motion
( v
) ) {
double prad = l ;
for ( int i=0; i<
length( Q11
)[2
]; i++
) {
SetPolygons5gon
( Q11
, Q12
, i
, prad
) ;
}
}
SetTRange
( v
, o
, 2*unit
) ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
int opacity = OPACITY
[0
] *
( 1 - t
) + OPACITY
[1
] * t ;
float emissive = OPTION0
[0
] *
( 1 - t
) + OPTION1
[0
] * t ;
float ambient = OPTION0
[3
] *
( 1 - t
) + OPTION1
[3
] * t ;
float sref = OPTION0
[4
] *
( 1 - t
) + OPTION1
[4
] * t ;
float sangle = OPTION0
[5
] *
( 1 - t
) + OPTION1
[5
] * t ;
int color
[ 3
] ;
for ( int i=0; i<
length( Q21
)[2
]; i++
) {
for ( int j=0; j<
length( Q21
)[1
]; j++
) {
for ( int n=0; n<3; n++
) {
color
[n
] = COLOR
[j
][n
] ;
}
for ( int k=0; k<
length( Q21
)[0
]; k++
) {
SetPolygonColor
( Q21
[i
][j
][k
], color
, opacity
) ;
setPolygonEmissive( Q21
[i
][j
][k
], emissive
) ;
setPolygonAmbient( Q21
[i
][j
][k
], ambient
) ;
setPolygonSpecular( Q21
[i
][j
][k
], sref
, sangle
) ;
}
}
}
}
int stop =
newVector( v
) ;
if ( GET_TIME
) {
T0 = T ;
GET_TIME = false ;
}
SetTRangeAbsolutely
( v
, T0
, T0 + unit
) ;
if ( FORMER_OPACITY_INDEX != OPACITY_INDEX
) {
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
float r0 = FORMER_OPACITY_INDEX / 2.0 ;
float r1 = OPACITY_INDEX / 2.0 ;
int opacity0 = OPACITY
[0
] * r0 + OPACITY
[1
] *
( 1 - r0
) ;
int opacity1 = OPACITY
[0
] * r1 + OPACITY
[1
] *
( 1 - r1
) ;
int opacity = opacity0 *
( 1 - t
) + opacity1 * t ;
float emissive0 = OPTION0
[0
] * r0 + OPTION1
[0
] *
( 1 - r0
) ;
float emissive1 = OPTION0
[0
] * r1 + OPTION1
[0
] *
( 1 - r1
) ;
float emissive = emissive0 *
( 1 - t
) + emissive1 * t ;
float ambient0 = OPTION0
[3
] * r0 + OPTION1
[3
] *
( 1 - r0
) ;
float ambient1 = OPTION0
[3
] * r1 + OPTION1
[3
] *
( 1 - r1
) ;
float ambient = ambient0 *
( 1 - t
) + ambient1 * t ;
float sref0 = OPTION0
[4
] * r0 + OPTION1
[4
] *
( 1 - r0
) ;
float sref1 = OPTION0
[4
] * r1 + OPTION1
[4
] *
( 1 - r1
) ;
float sref = sref0 *
( 1 - t
) + sref1 * t ;
float sangle0 = OPTION0
[5
] * r0 + OPTION1
[5
] *
( 1 - r0
) ;
float sangle1 = OPTION0
[5
] * r1 + OPTION1
[5
] *
( 1 - r1
) ;
float sangle = sangle0 *
( 1 - t
) + sangle1 * t ;
int color
[ 3
] ;
for ( int i=0; i<
length( Q21
)[2
]; i++
) {
for ( int j=0; j<
length( Q21
)[1
]; j++
) {
for ( int n=0; n<3; n++
) {
color
[n
] = COLOR
[j
][n
] ;
}
for ( int k=0; k<
length( Q21
)[0
]; k++
) {
SetPolygonColor
( Q21
[i
][j
][k
], color
, opacity
) ;
SetPolygonColor
( Q22
[i
][j
][k
], color
, opacity
) ;
SetPolygonColor
( Q23
[i
][j
][k
], color
, opacity
) ;
setPolygonEmissive( Q21
[i
][j
][k
], emissive
) ;
setPolygonEmissive( Q22
[i
][j
][k
], emissive
) ;
setPolygonEmissive( Q23
[i
][j
][k
], emissive
) ;
setPolygonAmbient( Q21
[i
][j
][k
], ambient
) ;
setPolygonAmbient( Q22
[i
][j
][k
], ambient
) ;
setPolygonAmbient( Q23
[i
][j
][k
], ambient
) ;
setPolygonSpecular( Q21
[i
][j
][k
], sref
, sangle
) ;
setPolygonSpecular( Q22
[i
][j
][k
], sref
, sangle
) ;
setPolygonSpecular( Q23
[i
][j
][k
], sref
, sangle
) ;
}
}
}
if ( t == a
) {
FORMER_OPACITY_INDEX = OPACITY_INDEX ;
TURN_GET_TIME = false ;
}
}
} else {
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
double p0ini
, p1ini ;
if ( Moment
( v
) ) {
p0ini =
getComponentValue( SLIDER
[0
] ) ;
p1ini =
getComponentValue( SLIDER
[1
] ) ;
}
double p0 = p0ini *
( 1 - t
) ;
double p1 = p1ini *
( 1 - t
) ;
setComponentValue( SLIDER
[0
], p0
) ;
setComponentValue( SLIDER
[1
], p1
) ;
if ( t == a
) {
TURN_GET_TIME = false ;
int n = 0 ;
if ( LIMIT
) {
for ( int i=0; i<
length( L12
)[2
]; i++
) {
for ( int j=0; j<
length( L12
)[1
]; j++
) {
removePolygon( L12
[n
][i
][j
][3
], RENDERER
, CD
[n
][i
] ) ;
}
}
} else {
for ( int i=0; i<
length( L12
)[2
]; i++
) {
for ( int j=0; j<
length( L12
)[3
]; j++
) {
addPolygon( L12
[n
][i
][j
][3
], RENDERER
, CD
[n
][i
] ) ;
}
}
}
}
}
}
setVector( v
, stop
) ;
}