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
, n = 255 ;
int bgcolor
[ ] = Color
( n
, n
, n
) ;
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 ++ ; // loop カウント
if ( COUNT % 100 == 0
) {
print( (COUNT/100
) + "
, "
) ;
}
ForwardMotion
() ; // アニメーション
if ( CREATE_GUI
) {
CreateGuiElements
() ; // GUI の設置
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 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 R4 = 4
, 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 */
// 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 ;
}
// 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 GetCoordinateOriginVector
( 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 SetCoordinateEulerAngleVector
( int cd
, int v
) {
setCoordinateEulerAngle( cd
,
getVectorX( v
), getVectorY( v
), getVectorZ( v
)
);
}
double
[ ] GetCoordinateEulerAngle
( int cd
) {
double ea
[ 3
];
ea
[0
] =
getCoordinateEulerAngleAlpha( cd
) ;
ea
[1
] =
getCoordinateEulerAngleBeta( cd
) ;
ea
[2
] =
getCoordinateEulerAngleGamma( cd
) ;
return ea ;
}
int GetCoordinateEulerAngleVector
( 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
) ;
}
// 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
);
}
/* 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 ;
}
/* 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 {
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 ;
}
//
import end
/* set lights */
int AMBIENT_LIGHT = newAmbientLight
( o
, o
, o
, o
) ;
int LIGHT0 =
newPointLight( -l
, -l
, -l
, 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 = 0.8 ;
SetAmbientLight
( AMBIENT_LIGHT
, o
, o
, o
, power
, RENDERER
) ;
}
/* create elements
(polygnのみ
) */
void SetElements
() {
SetElementOptions
() ;
AddElements
() ;
}
int NG = S6 ; // group の数
int TB0
[ NG
][ R8+R4
] ; // 底面0
, octagn=R8
, 頂点付近=R4
int TB1
[ NG
][ R8+R4
] ; // 底面1
, octagn=R8
, 頂点付近=R4
int TL0
[ NG
][ 3*R4
] ; // 側面0
, 1枚を3分割する
int TL1
[ NG
][ 3*R4
] ; // 側面1
, 1枚を3分割する
for ( int i=0; i<NG; i++
) {
for ( int j=0; j<R8+R4; j++
) {
TB0
[i
][j
] =
newTrianglePolygon( O
, O
, O
) ;
TB1
[i
][j
] =
newTrianglePolygon( O
, O
, O
) ;
}
for ( int j=0; j<3*R4; j++
) {
TL0
[i
][j
] =
newTrianglePolygon( O
, O
, O
) ;
TL1
[i
][j
] =
newTrianglePolygon( O
, O
, O
) ;
}
}
void SetPolygons4sideAntiprismCubeConnection
(
int base0
[ ][ ], int base1
[ ][ ], int latt0
[ ][ ], int latt1
[ ][ ],
int ng
, double baserad
) {
int v
[ ] = Get3Vectors4sideAntiprismCubeConnection
( baserad
) ; // v
[0
]はz軸上、v
[0
], v
[1
]は底面の2頂点、v
[2
]は高さ
// edge分点
int mid1 = GetInternallyDividingVector
( v
[0
], v
[1
], 1 - ISlv
) ;
int mid2 = GetRotYVector
( mid1
, 2*PI/R8
) ;
int mid3 = GetRotYVector
( mid1
, -2*PI/R8
) ;
// 底面
for ( int i=0; i<R8+R4; i++
) {
if ( i < R8
) {
setPolygonVector( base0
[ng
][i
], O
, mid2
, mid1
) ;
setPolygonVector( base1
[ng
][i
], O
, mid1
, mid2
) ;
rotYPolygon( base0
[ng
][i
], 2*PI/R8 * i
) ;
rotYPolygon( base1
[ng
][i
], 2*PI/R8 * i
) ;
} else {
int n = i - R8 ;
setPolygonVector( base0
[ng
][i
], v
[0
], mid3
, mid1
) ;
setPolygonVector( base1
[ng
][i
], v
[0
], mid1
, mid3
) ;
rotYPolygon( base0
[ng
][i
], -PI/2 * n
) ;
rotYPolygon( base1
[ng
][i
], PI/2 * n
) ;
}
movePolygon( base1
[ng
][i
], v
[2
] ) ;
rotYPolygon( base1
[ng
][i
], 2*PI/R8
) ;
}
// 側面
int u = GetRotYVector
( v
[0
], 2*PI/R8
) ;
moveVector( u
, v
[2
] ) ;
for ( int i=0; i<3*R4; i++
) {
if ( i%3 == 0
) {
setPolygonVector( latt0
[ng
][i
], v
[0
], mid1
, u
) ;
setPolygonVector( latt1
[ng
][i
], v
[0
], mid1
, u
) ;
} else if ( i%3 == 1
) {
setPolygonVector( latt0
[ng
][i
], mid1
, mid2
, u
) ;
setPolygonVector( latt1
[ng
][i
], mid1
, mid2
, u
) ;
} else {
setPolygonVector( latt0
[ng
][i
], mid2
, v
[1
], u
) ;
setPolygonVector( latt1
[ng
][i
], mid2
, v
[1
], u
) ;
}
rotPolygon( latt1
[ng
][i
], PI
, mid2
) ;
movePolygon( latt1
[ng
][i
], v
[2
] ) ;
rotYPolygon( latt0
[ng
][i
], 2*PI/R4 *
( i / 3
) ) ;
rotYPolygon( latt1
[ng
][i
], 2*PI/R4 *
( i / 3
) ) ;
}
}
int OPACITY
[ ] =
{ 255
, 100
} ;
float OPTION0
[ 6
], OPTION1
[ 6
] ;
{
float emissive = o ;
float diffractive = 0.4 ;
float diffuse = 0.6 ;
float ambient = 0.1 ;
float specularintensity = 0.9
, specularangle = PI/7;
OPTION0
[0
] = emissive ;
OPTION0
[1
] = diffractive ;
OPTION0
[2
] = diffuse ;
OPTION0
[3
] = ambient ;
OPTION0
[4
] = specularintensity ; OPTION0
[5
] = specularangle ;
OPTION1 = OPTION0 ;
OPTION1
[4
] = 1.0 ; OPTION1
[5
] = 1.5 ;
}
void SetElementOptions
() {
for ( int i=0; i<NG; i++
) {
for ( int j=0; j<R8+R4; j++
) {
setPolygonColor( TB0
[i
][j
], 100
, 30
, 255
, OPACITY
[0
] ) ;
setPolygonColor( TB1
[i
][j
], 255
, 30
, 100
, OPACITY
[0
] ) ;
}
for ( int j=0; j<3*R4; j++
) {
setPolygonColor( TL0
[i
][j
], 180
, 255
, 30
, OPACITY
[0
] ) ;
setPolygonColor( TL1
[i
][j
], 255
, 250
, 30
, OPACITY
[0
] ) ;
}
for ( int j=0; j<12; j++
) {
SetPolygonSurface
( TB0
[i
][j
], OPTION0
) ;
SetPolygonSurface
( TB1
[i
][j
], OPTION0
) ;
SetPolygonSurface
( TL0
[i
][j
], OPTION0
) ;
SetPolygonSurface
( TL1
[i
][j
], OPTION0
) ;
}
}
}
void AddElements
() {
int n =
length( COORD
) ;
addLight( LIGHT1
, RENDERER
, COORD
[n-1
] ) ;
addLight( LIGHT2
, RENDERER
, COORD
[n-1
] ) ;
setLightBrightness( LIGHT1
, 0.7
) ;
setLightBrightness( LIGHT2
, 0.4
) ;
for ( int i=0; i<NG; i++
) {
SetPolygons4sideAntiprismCubeConnection
( TB0
, TB1
, TL0
, TL1
, i
, o
) ;
for ( int j=0; j<12; j++
) {
addPolygon( TB0
[i
][j
], RENDERER
, CD
[i
] ) ;
addPolygon( TB1
[i
][j
], RENDERER
, CD
[i
] ) ;
addPolygon( TL0
[i
][j
], RENDERER
, CD
[i
] ) ;
addPolygon( TL1
[i
][j
], RENDERER
, CD
[i
] ) ;
}
}
}
/* 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
) ;
int len
[ ] =
length( CD
) ;
for ( int i=0; i<NG; i++
) {
addCoordinate( CD
[i
], RENDERER
, COORD
[0
] ) ;
}
}
/* set axes */
int AXIS
[ 13
] ;
{
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
, COORD
[0
] ) ;
for ( int i=0; i<NG; i++
) {
addModel( AXIS
[2+i
], RENDERER
, CD
[i
] ) ;
}
}
/* prepare stage */
double CAM_X0 = o;
double CAM_Y0 = o;
double CAM_Z0 = 13*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 = 25 ; // frames / 1sec
int PICTURE_NUMBER = 0 ;
int PICTURE_END_NUMBER = 5000 ;
double T = o ;
double T0 = -100.0 ;
double STEP
, TIME_FLOW ;
{
TIME_FLOW = 1.0 ;
STEP = TIME_FLOW / FPS ;
}
/* create GUI elements */
int SETTING_WINDOW ;
int LABEL_SLIDER
[ 5
] ;
N =
length( LABEL_SLIDER
) ;
int SLIDER
[ N
] ;
string SLIDER_TEXT
[ N
] ;
double P
[ N
] = o
, P0
[ N
] ;
int CHECK_BOX
[ 1
] ;
N =
length( CHECK_BOX
) ;
string CHECK_TEXT
[ N
] ;
bool SYNCHRO_SLIDER = true ;
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 UNFOLD_INDEX = 0 ;
int FORMER_UNFOLD_INDEX = 0 ;
SELECT_TITLE
[0
] = "展開のパターン" ;
SELECT_TEXT
[0
][0
] = "リセット(展開のパターンは下から選択)" ;
SELECT_TEXT
[0
][1
] = "頂点でつながった展開のパターン" ;
SELECT_TEXT
[0
][2
] = "稜線でつながった展開のパターン" ;
CHECK_TEXT
[0
] = "反角柱間の角度をすべてそろえる" ;
SLIDER_TEXT
[0
] = "1番目と2番目の反角柱間の角度" ;
SLIDER_TEXT
[1
] = "2番目と3番目の反角柱間の角度" ;
SLIDER_TEXT
[2
] = "3番目と4番目の反角柱間の角度" ;
SLIDER_TEXT
[3
] = "4番目と5番目の反角柱間の角度" ;
SLIDER_TEXT
[4
] = "5番目と6番目の反角柱間の角度" ;
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 = lh
, slideryspace = 5 ;
int sliderlabely
[ nsldl
] ;
int slidery
[ nsld
] ;
int selectx = lx
, selectw = lw - sidewidth
, selecth = 20
, selectyspace = 5 ;
int selectlabely
[ nsell
] ;
int selecty
[ nsel
] ;
int checkx = lx
, checkw = lw
, checkh = lh
, checkyspace = 5 ;
int checky ;
{
int initial_ly = 10;
for ( int i=0; i<nsel; i++
) {
selectlabely
[i
] = initial_ly
+
( lyspace + lh + selectyspace + selecth
) * i ;
selecty
[i
] = selectlabely
[i
] + lh + selectyspace ;
}
checky = selecty
[nsel-1
] + selecth + lyspace ;
for ( int i=0; i<nsld; i++
) {
sliderlabely
[i
] = checky + checkh + 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
] + 70 ;
{
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 (select field と slider の間)
CHECK_BOX
[0
] =
newCheckBox (
lx
, checky
, lw
, checkh
, CHECK_TEXT
[0
], true
) ;
addComponent( CHECK_BOX
[0
], SETTING_WINDOW
) ;
// slider
for ( int i=0; i<nsld; i++
) {
LABEL_SLIDER
[i
] =
newTextLabel(
lx
, sliderlabely
[i
], lw
, lh
, SLIDER_TEXT
[i
]
) ;
addComponent( LABEL_SLIDER
[i
], SETTING_WINDOW
) ;
SLIDER
[i
] =
newHorizontalSlider( sliderx
, slidery
[i
], sliderw
, sliderh
, o
) ;
addComponent( SLIDER
[i
], SETTING_WINDOW
) ;
if ( SYNCHRO_SLIDER
) {
if ( i >= 1
) {
hideComponent( SLIDER
[i
] ) ;
}
}
}
}
paintComponent( SETTING_WINDOW
) ;
}
/* event handlers */
void onSliderMove( int id
, double value
) {
if ( ! TURN_GET_TIME
) {
double p ;
int deg
[ SLIDER
] ;
if ( SYNCHRO_SLIDER
) {
if ( UNFOLD_INDEX == 1
) {
for ( int i=0; i<
length( SLIDER
); i++
) {
if ( id == SLIDER
[i
] ) {
p = value ;
}
}
P = p ;
deg = p * 90 ;
FoldArroundVertex
( P
) ;
} else if ( UNFOLD_INDEX == 2
) {
double anglerange = 2*GetAngleLateralLateral
() ;
float degrange = anglerange/PI * 180 ;
for ( int i=0; i<
length( SLIDER
); i++
) {
if ( id == SLIDER
[i
] ) {
p = value ;
}
}
P = p ;
deg =
( p - a/2
) * degrange ;
FoldArroundEdge
( P
) ;
}
for ( int i=0; i<
length( SLIDER
); i++
) {
int nth = i + 1
, next = nth + 1 ;
SLIDER_TEXT
[i
] =
nth + " 番目と" + next + " 番目の反角柱間の角度 "
+ deg
[i
] + " 度" ;
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
}
} else {
if ( UNFOLD_INDEX == 1
) {
for ( int i=0; i<
length( SLIDER
); i++
) {
P
[i
] =
getComponentValue( SLIDER
[i
] ) ;
deg
[i
] = P
[i
] * 90 ;
}
FoldArroundVertex
( P
) ;
} else if ( UNFOLD_INDEX == 2
) {
double anglerange = 2*GetAngleLateralLateral
() ;
float degrange = anglerange/PI * 180 ;
for ( int i=0; i<
length( SLIDER
); i++
) {
P
[i
] =
getComponentValue( SLIDER
[i
] ) ;
deg
[i
] =
( P
[i
] -a/2
) * degrange ;
}
FoldArroundEdge
( P
) ;
}
for ( int i=0; i<
length( SLIDER
); i++
) {
int nth = i
, next = nth + 1 ;
SLIDER_TEXT
[i
] =
nth + " 番目と" + next + " 番目の反角柱間の角度 "
+ deg
[i
] + " 度" ;
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
}
}
}
if ( FORMER_UNFOLD_INDEX == 0 && UNFOLD_INDEX == 0
) {
SLIDER_TEXT
[0
] = "展開のパターンを選択して下さい" ;
setComponentFontSize( LABEL_SLIDER
[0
], 14
) ;
setComponentText( LABEL_SLIDER
[0
], SLIDER_TEXT
[0
] ) ;
paintComponent( LABEL_SLIDER
[0
] ) ;
paintComponent( SLIDER
[0
] ) ;
}
}
void onSelectFieldClick( int id
, string text
){
if ( TURN_GET_TIME
) {
} else {
if ( id == SELECT
[0
] ) {
int n
[ ] =
length( SELECT_TEXT
) ;
for ( int i=0; i<n
[0
]; i++
) {
if ( text == SELECT_TEXT
[0
][i
] ) {
if ( ( i == FORMER_UNFOLD_INDEX
) &&
( i != 0
) ) {
} else {
if ( FORMER_UNFOLD_INDEX == 0 && UNFOLD_INDEX == 0
) {
SLIDER_TEXT
[0
] = "1 番目と2 番目の反角柱間の角度 "
+ 0 + " 度" ;
setComponentFontSize( LABEL_SLIDER
[0
], 12
) ;
setComponentText( LABEL_SLIDER
[0
], SLIDER_TEXT
[0
] ) ;
paintComponent( LABEL_SLIDER
[0
] ) ;
paintComponent( SLIDER
[0
] ) ;
}
UNFOLD_INDEX = i ;
GET_TIME = true ;
TURN_GET_TIME = true ;
}
}
}
}
}
}
void onCheckBoxClick( int id
, bool state
) {
if ( !TURN_GET_TIME
) {
if ( id == CHECK_BOX
[0
] ) {
SYNCHRO_SLIDER = state ;
if ( SYNCHRO_SLIDER
) {
for ( int i=1; i<
length( SLIDER
); i++
) {
hideComponent( SLIDER
[i
] ) ;
}
GET_TIME = true ;
TURN_GET_TIME = true ;
} else {
P
[0
] =
getComponentValue( SLIDER
[0
] ) ;
for ( int i=1; i<
length( SLIDER
); i++
) {
P
[i
] = P
[0
] ;
showComponent( SLIDER
[i
] ) ;
setComponentValue( SLIDER
[i
], P
[i
] ) ;
}
}
}
}
}
/* 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 = 2/180.0 * PI ;
if ( (!TURN_GUI
) || TURN_GET_TIME
) {
DesignMotion
( t
, toprotrate
) ; // アニメーション
STOP_TIME =
getVectorY( t
) ; // motion終了時刻
GUI_UPTIME = STOP_TIME + 1.0 ;
CREATE_GUI =
( T >= GUI_UPTIME
) &&
( T < GUI_UPTIME + STEP
) ;
}
if ( T < GUI_UPTIME + 100.0
) {
rotYCoordinate( COORD
[2
], toprotrate
) ;
}
}
{
int len
[ ] =
length( CD
) ;
N = len
[0
] ;
}
int SO
[ N
] ; //
system origin point
int SA
[ N
] ; //
system Euler Angle
int RC
[ N
] ; // rotation center vector
int AX
[ N
] ; // rotation axis vector
for ( int i=0; i<N; i++
) {
SO
[i
] =
newVector() ;
SA
[i
] =
newVector() ;
RC
[i
] =
newVector() ;
AX
[i
] =
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 d = 1.0 / 3.0 ; // 時間の単位
SetTRangeAbsolutely
( v
, start_t
, start_t
) ;
SetTRange
( v
, o
, STEP
) ;
if ( Motion
( v
) ) {
double h ;
for ( int i=0; i<NG; i++
) {
h = 2*GetHeightAntiprismByConnectionName
( 4
, l
, "cube"
) *
( i - NG / 2
) ;
setCoordinateOrigin( CD
[i
], o
, h
, o
) ;
}
setCoordinateOrigin( COORD
[0
], o
,10*l
, o
) ;
setCoordinateEulerAngle( COORD
[1
], o
, PI/2
, o
) ;
}
SetTRange
( v
, o
, 10*d
) ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
double rad = l * t ;
for ( int i=0; i<NG; i++
) {
SetPolygons4sideAntiprismCubeConnection
( TB0
, TB1
, TL0
, TL1
, i
, rad
) ;
double s = Slope
( t
, 0.25/NG * i
, 1 - 0.25/NG *
( NG - 1
) ) ;
double rt = 4*l *
sin( 2*PI*s
) ;
double h = 3*GetHeightAntiprismByConnectionName
( 4
, l
, "cube"
)
*
( i - NG / 2
) ;
int vt =
newVector( rt *
sin( 4*PI*s
), h
, rt *
cos( 4*PI*s
) ) ;
setCoordinateOrigin( CD
[i
], vt
) ;
}
setCoordinateOrigin( COORD
[0
], o
, 4*l *
( 1 - t
), o
) ;
setCoordinateEulerAngle( COORD
[1
], o
, PI/2 *
( 1 - 0.1*t
), o
) ;
}
int stop =
newVector( v
) ;
if ( GET_TIME
) {
T0 = T ;
GET_TIME = false ;
}
if ( FORMER_UNFOLD_INDEX != 0
) {
SetTRangeAbsolutely
( v
, T0
, T0 + 3*d - 3*STEP
) ;
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
for ( int i=0; i<
length( SLIDER
); i++
) {
P0
[i
] =
getComponentValue( SLIDER
[i
] ) ;
}
}
double t = GetLinearTime
( v
) ;
int deg ;
for ( int i=0; i<
length( SLIDER
); i++
) {
if ( FORMER_UNFOLD_INDEX != UNFOLD_INDEX
) {
if ( SYNCHRO_SLIDER
) {
P
[i
] = P0
[0
] *
( 1 - t
) ;
} else {
P
[i
] = P0
[i
] *
( 1 - t
) ;
}
} else if ( FORMER_UNFOLD_INDEX == UNFOLD_INDEX
) {
P
[i
] = P0
[i
] *
( 1 - t
) + P0
[0
] * t ;
}
}
if ( FORMER_UNFOLD_INDEX == 1
) {
for( int i=0; i<
length( SLIDER
); i++
) {
deg = P
[i
] * 90 ;
setComponentValue( SLIDER
[i
], P
[i
] ) ;
SLIDER_TEXT
[i
] =
"反角柱間の角度 " + deg + " 度" + " ...please wait... ";
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
}
FoldArroundVertex
( P
) ;
} else ( FORMER_UNFOLD_INDEX == 2
) {
double anglerange = 2*GetAngleLateralLateral
() ;
float degrange = anglerange/PI * 180 ;
for( int i=0; i<
length( SLIDER
); i++
) {
deg =
( P
[i
] - a/2
) * degrange ;
setComponentValue( SLIDER
[i
], P
[i
] ) ;
SLIDER_TEXT
[i
] =
"反角柱間の角度 " + deg + " 度" + " ...please wait... ";
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
if ( UNFOLD_INDEX == 1 || UNFOLD_INDEX == 0
) {
P
[i
] = P
[i
] + 0.5 * t ;
}
}
FoldArroundEdge
( P
) ;
}
if ( t == a
) {
if ( FORMER_UNFOLD_INDEX != UNFOLD_INDEX
) {
for ( int i=0; i<
length( SLIDER
); i++
) {
int nth = i + 1
, next = nth + 1 ;
SLIDER_TEXT
[i
] =
nth + " 番目と" + next + " 番目の反角柱間の角度 "
+ 0 + " 度" ;
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
}
} else if ( FORMER_UNFOLD_INDEX == UNFOLD_INDEX
) {
for ( int i=0; i<
length( SLIDER
); i++
) {
if ( FORMER_UNFOLD_INDEX == 1
) {
deg = P
[i
] * 90 ;
} else if ( FORMER_UNFOLD_INDEX == 2
) {
double anglerange = 2*GetAngleLateralLateral
() ;
float degrange = anglerange/PI * 180 ;
deg =
( P
[i
] - a/2
) * degrange ;
}
int nth = i + 1
, next = nth + 1 ;
SLIDER_TEXT
[i
] =
nth + " 番目と" + next + " 番目の反角柱間の角度 "
+ deg + " 度" ;
setComponentText( LABEL_SLIDER
[i
], SLIDER_TEXT
[i
] ) ;
paintComponent( LABEL_SLIDER
[i
] ) ;
setComponentValue( SLIDER
[i
], P
[i
] ) ;
}
}
if ( ( FORMER_UNFOLD_INDEX == UNFOLD_INDEX
) &&
( UNFOLD_INDEX != 0
) ) {
TURN_GET_TIME = false ;
}
}
}
}
double t0 = T0 ;
if ( FORMER_UNFOLD_INDEX != 0
) { t0 = T0 + 3*d ;
}
SetTRangeAbsolutely
( v
, t0
, t0 + 3*d
);
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
setVector( AX
[0
], o
, a
, o
) ;
for ( int i=0; i<NG; i++
) {
SetVectorsCoordinateLocationAttitude
( SO
[i
], SA
[i
], CD
[i
] ) ;
if ( i <= 4
) {
hideComponent( SLIDER
[i
] ) ;
}
}
}
double t = GetLinearTime
( v
) ;
double angle = o ;
if ( FORMER_UNFOLD_INDEX == 0
) {
double s1 = Slope
( t
, o
, 0.5*a
) ;
double s2 = Slope
( t
, 0.5*a
, 0.5*a
) ;
if ( UNFOLD_INDEX == 0
) {
for ( int i=0; i<NG; i++
) {
double s = Slope
( t
, 0.06*i
, a - 0.06*i
) ;
double h = 3*GetHeightAntiprismByConnectionName
( 4
, l
, "cube"
)
*
( i - NG / 2
) ;
setCoordinateOrigin( CD
[i
], o
, h
, o
) ;
setCoordinateEulerAngle( CD
[i
], PI/2
, 2*PI * s
, -PI/2
) ;
}
} else {
for ( int i=0; i<NG; i++
) {
double x = -3*l + 2*l *
( ( i + 1
) / 2
) ;
double y =
getVectorY( SO
[i
] ) ;
double z = 2*l - 2*l *
( i / 2
) ;
int v1 =
newVector( x
, y
, z
) ;
int vt1 = GetInternallyDividingVector
( SO
[i
], v1
, s1
) ;
int vt2 =
newVector( o
, -y * s2
, o
) ;
SetCoordinateLocationAttitude
( CD
[i
], vt1
, SA
[i
] ) ;
moveCoordinate( CD
[i
], vt2
) ;
}
}
if( UNFOLD_INDEX == 2
) {
for ( int i=0; i<=4; i++
) {
angle = PI/4 * s2 * Parity
( i
) ;
int j = 1 ;
if ( i%2 == 1
) { j = 2 ;
}
int rc = GetVertexVector
( CD
[i
], j
) ; // i番目の回りの回転 center
for ( int j=1+i; j<=5; j++
) {
rotCoordinate( CD
[j
], angle
, AX
[0
], rc
) ;
}
}
int origin
[ 2
] ;
origin
[0
] = GetCoordinateOriginVector
( CD
[0
] ) ;
origin
[1
] = GetCoordinateOriginVector
( CD
[5
] ) ;
G = GetVectorGravityCenter
( origin
) ;
scaleVector( G
, -a
, -a
, -a
) ;
setCoordinateOrigin( COORD
[0
], G
) ;
}
} else if ( FORMER_UNFOLD_INDEX == 1
) {
double s1 = Slope
( t
, o
, a/2
) ;
double s2 = Slope
( t
, a/2
, a/2
) ;
if( UNFOLD_INDEX == 0
) {
for ( int i=0; i<NG; i++
) {
double x =
getVectorX( SO
[i
] ) ;
double y = 3*GetHeightAntiprismByConnectionName
( 4
, l
, "cube"
)
*
( i - NG / 2
) ;
double z =
getVectorZ( SO
[i
] ) ;
int v1 =
newVector( x
, y
, z
) ;
int vt1 = GetInternallyDividingVector
( SO
[i
], v1
, s1
) ;
int vt2 =
newVector( -x*s2
, o
, -z*s2
) ;
setCoordinateOrigin( CD
[i
], vt1
) ;
moveCoordinate( CD
[i
], vt2
) ;
}
} else if( UNFOLD_INDEX == 2
) {
for ( int i=0; i<NG; i++
) {
SetCoordinateLocationAttitude
( CD
[i
], SO
[i
], SA
[i
] ) ;
}
for ( int i=0; i<=4; i++
) {
angle = PI/4 * t * Parity
( i
) ;
int j = 1 ;
if ( i%2 == 1
) { j = 2 ;
}
int rc = GetVertexVector
( CD
[i
], j
) ; // i番目の回りの回転 center
for ( int j=1+i; j<=5; j++
) {
rotCoordinate( CD
[j
], angle
, AX
[0
], rc
) ;
}
}
int origin
[ 2
] ;
origin
[0
] = GetCoordinateOriginVector
( CD
[0
] ) ;
origin
[1
] = GetCoordinateOriginVector
( CD
[5
] ) ;
G = GetVectorGravityCenter
( origin
) ;
scaleVector( G
, -a
, -a
, -a
) ;
setCoordinateOrigin( COORD
[0
], G
) ;
}
} else if ( FORMER_UNFOLD_INDEX == 2
) {
double s1 = Slope
( t
, o
, a/2
) ;
double s2 = Slope
( t
, a/4
, a/2
) ;
double s3 = Slope
( t
, a/2
, a/2
) ;
if( UNFOLD_INDEX == 0
) {
int so
[ NG
] ;
for ( int i=0; i<NG; i++
) {
SetCoordinateLocationAttitude
( CD
[i
], SO
[i
], SA
[i
] ) ;
so
[i
] =
newVector( SO
[i
] ) ;
}
for ( int i=0; i<=4; i++
) {
angle = -PI/4 * s1 * Parity
( i
) ;
int j = 1 ;
if ( i%2 == 1
) { j = 2 ;
}
int rc = GetVertexVector
( CD
[i
], j
) ; // i番目の回りの回転 center
for ( int j=1+i; j<=5; j++
) {
rotCoordinate( CD
[j
], angle
, AX
[0
], rc
) ;
so
[j
] = GetCoordinateOriginVector
( CD
[j
] ) ;
}
}
for ( int i=0; i<NG; i++
) {
double x =
getVectorX( so
[i
] ) ;
double y = 3*GetHeightAntiprismByConnectionName
( 4
, l
, "cube"
)
*
( i - NG / 2
) ;
double z =
getVectorZ( so
[i
] ) ;
int v1 =
newVector( x
, y
, z
) ;
int vt1 = GetInternallyDividingVector
( so
[i
], v1
, s2
) ;
int vt2 =
newVector( -x*s3
, o
, -z*s3
) ;
setCoordinateOrigin( CD
[i
], vt1
) ;
moveCoordinate( CD
[i
], vt2
) ;
}
} else if( UNFOLD_INDEX == 1
) {
for ( int i=0; i<NG; i++
) {
SetCoordinateLocationAttitude
( CD
[i
], SO
[i
], SA
[i
] ) ;
}
for ( int i=0; i<=4; i++
) {
angle = -PI/4 * t * Parity
( i
) ;
int j = 1 ;
if ( i%2 == 1
) { j = 2 ;
}
int rc = GetVertexVector
( CD
[i
], j
) ; // i番目の回りの回転 center
for ( int j=1+i; j<=5; j++
) {
rotCoordinate( CD
[j
], angle
, AX
[0
], rc
) ;
}
}
}
int origin
[ 2
] ;
origin
[0
] = GetCoordinateOriginVector
( CD
[0
] ) ;
origin
[1
] = GetCoordinateOriginVector
( CD
[5
] ) ;
G = GetVectorGravityCenter
( origin
) ;
scaleVector( G
, -a
, -a
, -a
) ;
setCoordinateOrigin( COORD
[0
], G
) ;
}
if ( t == a
) {
for ( int i=0; i<
length( SLIDER
); i++
) {
if ( UNFOLD_INDEX == 2
) {
P
[i
] = a/2 ;
setComponentValue( SLIDER
[i
], P
[i
] ) ; // slieder原点を瞬間的に移すため、onSliderMove内の処理と干渉しないこと
} else {
P
[i
] = o ;
setComponentValue( SLIDER
[i
], P
[i
] ) ;
}
if ( SYNCHRO_SLIDER
) {
if ( i == 0
) {
showComponent( SLIDER
[i
] ) ;
}
} else {
if ( i <= 4
) {
showComponent( SLIDER
[i
] ) ;
}
}
}
FORMER_UNFOLD_INDEX = UNFOLD_INDEX ;
TURN_GET_TIME = false ;
}
}
setVector( v
, stop
) ;
}
// n番目の頂点ベクトルを返す
int GetVertexVector
( int cd
, int n
) {
int v
[ ] = Get3Vectors4sideAntiprismCubeConnection
( l
) ;
int u =
newVector( v
[0
] ) ;
if ( n <= 3
) {
rotYVector( u
, PI/2 * n
) ;
} else {
rotYVector( u
, PI/2 *
( n - 4
) + PI/4
) ;
moveVector( u
, v
[2
] ) ;
}
int w = GetTransformedVector
( u
, RENDERER
, cd
, COORD
[0
] ) ;
return w ;
}
// 頂点の回りに折る
void FoldArroundVertex
( double anp
[ ] ) {
double angle
[ ] = anp * PI/2;
double rot
[ NG
] ;
int so
[ NG
], sa
[NG
], rc
[ NG
] ;
int ax
[ NG
];
int dummycd
[ NG
] ;
for( int i=0; i<NG; i++
) {
dummycd
[i
] =
newCoordinate() ;
addCoordinate( dummycd
[i
], RENDERER
, COORD
[0
] ) ;
sa
[i
] =
newVector() ;
}
for ( int i=0; i<NG; i++
) {
so
[i
] =
newVector( -3*l + 2*l *
( ( i + 1
) / 2
), o
, 2*l - 2*l *
( i / 2
) ) ;
SetCoordinateLocationAttitude
( dummycd
[i
], so
[i
], O
) ;
int n ;
if ( ( i == 0
) ||
( i == 2
) ) {
n = 1 ;
} else if ( ( i == 1
) ) {
n = 2 ;
} else if ( ( i == 3
) ||
( i == 5
) ) {
n = 3 ;
} else {
n = 0 ;
}
rc
[i
] = GetVertexVector
( dummycd
[i
], n
) ;
if ( ( i == 0
) ||
( i == 2
) ||
( i == 3
) ||
( i == 5
) ) {
ax
[i
] =
newVector( o
, o
, a
) ;
} else {
ax
[i
] =
newVector( a
, o
, o
) ;
}
if ( ( i == 0
) ||
( i == 1
) ) {
rot
[i
] = -angle
[i
] ;
} else if ( i == 2
) {
rot
[i
] = -angle
[i
]/2 ;
} else if ( i == 3
) {
rot
[i
] = angle
[i-1
]/2 ;
} else {
rot
[i
] = angle
[i-1
] ;
}
}
for ( int i=0; i<=2; i++
) {
for ( int j=0; j<=i; j++
) {
rotCoordinate( dummycd
[j
], rot
[i
], ax
[i
], rc
[i
] ) ;
rotCoordinate( dummycd
[5-j
], rot
[5-i
], ax
[5-i
], rc
[5-i
] ) ;
}
}
double offset ;
for ( int i=0; i<NG; i++
) {
SetVectorsCoordinateLocationAttitude
( so
[i
], sa
[i
], dummycd
[i
] ) ;
SetCoordinateLocationAttitude
( CD
[i
], so
[i
], sa
[i
] ) ;
for ( int j=0; j<12; j++
) {
offset =
( angle
[0
] + angle
[1
] + angle
[2
] + angle
[3
] + angle
[4
] ) / 20 ;
setPolygonSortOffset( TL1
[i
][j
], -offset
) ;
}
}
}
// 稜線の回りに折る
void FoldArroundEdge
( double anp
[ ] ) {
double anglerange = 2*GetAngleLateralLateral
() ;
double angle
[ ] =
( anp - a/2
) * anglerange ;
double rot
[ NG
] ;
int so
[ NG
], sa
[NG
], rc
[ NG
] ;
int ax
[ NG
];
int dummycd
[ NG
] ;
for( int i=0; i<NG; i++
) {
dummycd
[i
] =
newCoordinate() ;
addCoordinate( dummycd
[i
], RENDERER
, COORD
[0
] ) ;
sa
[i
] =
newVector() ;
}
for ( int i=0; i<NG; i++
) {
so
[i
] =
newVector( -3*l + 2*l *
( ( i + 1
) / 2
), o
, 2*l - 2*l *
( i / 2
) ) ;
SetCoordinateLocationAttitude
( dummycd
[i
], so
[i
], O
) ;
}
for ( int i=0; i<=4; i++
) {
double th = PI/4 * Parity
( i
) ;
int j = 1 ;
if ( i%2 == 1
) { j = 2 ;
}
int ax =
newVector( o
, a
, o
) ;
int rc = GetVertexVector
( dummycd
[i
], j
) ;
for ( int j=1+i; j<=5; j++
) {
rotCoordinate( dummycd
[j
], th
, ax
, rc
) ;
}
}
for ( int i=0; i<NG; i++
) {
int n
, m ;
if ( ( i == 0
) ||
( i == 2
) ) {
n = 1 ; m = 5 ;
} else if ( ( i == 1
) ) {
n = 2 ; m = 5 ;
} else if ( ( i == 3
) ||
( i == 5
) ) {
n = 3 ; m = 6 ;
} else {
n = 0 ; m = 4 ;
}
rc
[i
] = GetVertexVector
( dummycd
[i
], n
) ;
int ax0 = GetVertexVector
( dummycd
[i
], m
) ;
ax
[i
] = GetVectorDifference
( ax0
, rc
[i
] ) ;
if ( ( i == 0
) ||
( i == 1
) ||
( i == 4
) ||
( i == 5
) ) {
int j = i ;
if ( i >= 4
) { j = i - 1 ;
}
rot
[i
] = angle
[j
] * Parity
( i
) ;
} else if ( i == 2
) {
rot
[i
] = angle
[i
]/2 * Parity
( i
) ;
} else if ( i == 3
) {
rot
[i
] = angle
[i-1
]/2 * Parity
( i
) ;
}
}
for ( int i=0; i<=2; i++
) {
for ( int j=0; j<=i; j++
) {
rotCoordinate( dummycd
[j
], rot
[i
], ax
[i
], rc
[i
] ) ;
rotCoordinate( dummycd
[5-j
], rot
[5-i
], ax
[5-i
], rc
[5-i
] ) ;
}
}
double offset ;
for ( int i=0; i<NG; i++
) {
SetVectorsCoordinateLocationAttitude
( so
[i
], sa
[i
], dummycd
[i
] ) ;
SetCoordinateLocationAttitude
( CD
[i
], so
[i
], sa
[i
] ) ;
for ( int j=0; j<12; j++
) {
offset =
( angle
[0
] + angle
[1
] + angle
[2
] + angle
[3
] + angle
[4
] ) / 50 ;
setPolygonSortOffset( TB0
[i
][j
], offset
) ;
setPolygonSortOffset( TB1
[i
][j
], -offset
) ;
setPolygonSortOffset( TL0
[i
][j
], offset
) ;
setPolygonSortOffset( TL1
[i
][j
], -offset
) ;
}
}
}
// 側面二面角
double GetAngleLateralLateral
() {
int v
[ ] = Get3Vectors4sideAntiprismCubeConnection
( l
) ;
int u1
[ 4
], u2
[ 4
] ;
u1
[0
] =
newVector( v
[0
] ) ;
u1
[1
] =
newVector( v
[1
] ) ;
int m = GetRotYVector
( v
[0
], PI/4
) ;
moveVector( m
, v
[2
] ) ;
u1
[2
] =
newVector( m
) ;
u1
[3
] =
newVector( v
[0
] ) ;
for ( int i=0; i<
length( u2
); i++
) {
u2
[i
] =
newVector( u1
[i
] ) ;
rotZVector( u2
[i
], PI
) ;
rotYVector( u2
[i
], PI/4
) ;
}
double costh = GetAngleFaceFace
( u1
, u2
) ;
return acos( costh
) ;
}