encode Shift_JIS ;
import Graphics ;
import Graphics3D ;
import GUI ;
import Math ;
void main
( string args
[] ){
hide();
Set3DGraphics
();
SetLights
();
SetCoordinates
();
// SetAxes
();
SetElements
();
PrepareStage
();
/* animation Loop */
int picture_save_number = 1 * 1000 ;
int loop_periodic_time = 1000 / PAINT_FREQUENCY ;
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 ;
}
PaintGraphics
( loop_periodic_time
);
if ( SAVE_A_PICTURE
) {
SavePicture
( picture_save_number
);
}
loop_termination =
( PICTURE_NUMBER == PICTURE_END_NUMBER
) ;
if ( loop_termination
) {
ExitLoop
();
}
}
exit();
}
/*
import numbers */
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 ;
/*
import set 3D graphics */
string TITLE = "1110_cuboctahedron_stellation" ;
int MAIN_GRAPHICS
, MAIN_WINDOW
, MAIN_DISPLAY_LABEL
, RENDERER ;
int WIDTH
, HEIGHT
, WINDOW_POSITION_X ;
{
int n = 256 ;
WIDTH = n * 2.5 ;
HEIGHT = n * 2.5 ;
WINDOW_POSITION_X = 70 ;
}
void Set3DGraphics
() {
int backgroundcolor = 255 * a ;
int bgred = backgroundcolor ;
int bggreen = backgroundcolor ;
int bgblue = backgroundcolor ;
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
);
}
/*
import event handlers */
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 ExitLoop
() {
alert(
"画像の保存が上限
( "
+ PICTURE_END_NUMBER
+ " 枚
) に達したため、CGアニメーションを終了します。"
);
KEEP_LOOP = false ;
}
/*
import functions */
// 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 ;
}
// 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 ;
}
/*
import routine */
void PrintVectorln
( int v
, string s
) {
println( "Vectors " + 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 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 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 ;
}
// vectorの差を求めて代入する
void GetVectorDifference
( 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の差を返す
void 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の定数倍を返す
int GetScaleVector
( int v
, double x
) {
int u =
newVector( v
) ;
scaleVector( u
, x
, x
, x
) ;
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 TransformVector
( 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 GetCenterOfGravityVector
( 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 ;
}
void GetCoordinateLocationAttitude
( 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 ;
}
// 原点が 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
);
}
/*
import animation */
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
) {
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 dt0
, double dt1
) {
double t0 =
getVectorY( v
) + dt0 ;
double t1 = t0 + dt1 ;
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
) ;
}
/* set lights */
int LIGHT;
int AMBIENT_LIGHT;
void SetLights
() {
float power = 0.9 ;
SetParallelLight
( LIGHT
, -4.0
, 10.0
, 5.0
, power
);
power = 0.7 ;
SetAmbientLight
( AMBIENT_LIGHT
, o
, o
, o
, power
);
}
void SetParallelLight
( int light
, float x
, float y
, float z
, float power
) {
light =
newLight( x
, y
, z
, power
) ;
addLight( light
, RENDERER
);
}
void SetAmbientLight
( int light
, float x
, float y
, float z
, float power
) {
light = newAmbientLight
( x
, y
, z
, power
) ;
addLight( light
, RENDERER
);
}
/* set coordinates */
int COORD
[ 2
], CD
[ 1
] ;
{
for ( int i=0; i<
length( COORD
); i++
) {
COORD
[i
] =
newCoordinate() ;
}
for ( int i=0; i<
length( CD
); i++
) {
CD
[i
] =
newCoordinate() ;
}
}
void SetCoordinates
() {
PileCoordinate
( COORD
, RENDERER
);
for ( int i=0; i<
length( CD
); i++
) {
addCoordinate( CD
[i
], RENDERER
, COORD
[0
] );
}
}
/* set axes */
int AXIS
[ 2
];
{
float x
, y
, z ;
for ( int i=0; i<
length( AXIS
); i++
) {
x =
( 4 - 0.9*i
) * l ; y = x ; z = x ;
AXIS
[i
] =
newAxisModel( x
, y
, z
) ;
}
}
void SetAxes
() {
addModel( AXIS
[0
], RENDERER
, COORD
[0
] );
addModel( AXIS
[1
], RENDERER
, CD
[0
] );
}
/* create elements */
void SetElements
() {
SetElementVectors
();
SetElementColors
();
SetElementOptions
();
AddElements
();
}
int NG = 1 ; // number of groups
int NQ = 6 ;
int QP
[ NG
][ NQ
] ; // quadrangle polygon
int NT = 8 ;
int TP
[ NG
][ NT
] ; // triangle polygon
{
for ( int n3=0; n3<NG; n3++
) {
for ( int i=0; i<NQ; i++
) {
QP
[0
][i
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
}
for ( int i=0; i<NT; i++
) {
TP
[0
][i
] =
newTrianglePolygon( O
, O
, O
) ;
}
}
}
int VQ
[ 4
], VT
[ 3
] ; // vectors
for a polygon
{
for ( int i=0; i<4; i++
) {
VQ
[i
] =
newVector() ;
}
for ( int i=0; i<3; i++
) {
VT
[i
] =
newVector() ;
}
}
void SetElementVectors
() {
SetVectors68hedronQuadrangle
( VQ
);
SetVectors68hedronTriangle
( VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
}
void SetVectors68hedronQuadrangle
( int v
[ ] ) {
for ( int i=0; i<4; i++
) {
setVector( v
[i
], o
, l
, l
) ;
rotYVector( v
[i
], PI/2 * i
);
}
}
void SetVectors68hedronTriangle
( int v
[ ] ) {
setVector( v
[0
], o
, l
, l
) ;
setVector( v
[1
], l
, o
, l
) ;
setVector( v
[2
], l
, l
, o
) ;
}
void SetPolygons8hedronVertexSymmetry
( int p
[ ][ ], int v
[ ] ) {
int n
[ ] =
length( p
) ;
for ( int i=0; i<n
[0
]; i++
) {
setPolygonVector( p
[0
][i
], v
[0
], v
[1
], v
[2
], v
[3
] );
if ( i == 1
) {
rotXPolygon( p
[0
][i
], PI/2
);
} else if ( i == 2
) {
rotZPolygon( p
[0
][i
], -PI/2
);
} else if ( i == 3
) {
rotXPolygon( p
[0
][i
], -PI/2
);
} else if ( i == 4
) {
rotZPolygon( p
[0
][i
], PI/2
);
} else if ( i == 5
) {
rotZPolygon( p
[0
][i
], PI
);
}
}
}
void SetPolygons6hedronVertexSymmetry
( int p
[ ][ ], int v
[ ] ) {
int n
[ ] =
length( p
) ;
for ( int i=0; i<n
[0
]; i++
) {
setPolygonVector( p
[0
][i
], v
[0
], v
[1
], v
[2
] );
if ( ( i >= 1
) &&
( i <= 3
) ) {
rotYPolygon( p
[0
][i
], PI/2 * i
);
} else if ( ( i >= 4
) ) {
rotZPolygon( p
[0
][i
], PI
);
rotYPolygon( p
[0
][i
], PI/2 *
( i - 3
) );
}
}
}
int COLOR_Q
[ 3
] , COLOR_T
[ 3
] ;
{
int sred
[3
] ; sred
[0
] = 255 ; sred
[1
] = 25 ; sred
[2
] = 50 ;
int sblue
[3
] ; sblue
[0
] = 50 ; sblue
[1
] = 25 ; sblue
[2
] = 255 ;
COLOR_Q = sred ;
COLOR_T = sblue ;
}
N = 2 ;
int OPACITY
[ N
];
{
OPACITY
[0
] = 255 ;
OPACITY
[1
] = 255 ;
}
void SetElementColors
() {
for ( int i=0; i<NQ; i++
) {
SetPolygonColor
( QP
[0
][i
], COLOR_Q
, OPACITY
[0
] );
}
for ( int i=0; i<NT; i++
) {
SetPolygonColor
( TP
[0
][i
], COLOR_T
, OPACITY
[1
] );
}
}
N = 6 ;
float OPTIN
[ N
];
{
float emissive = o ;
float diffractive = 0.4 ;
float diffuse = 0.9 ;
float ambient = 0.4 ;
float specularintensity = 0.5
, specularangle = 0.7 ;
OPTIN
[0
] = emissive ;
OPTIN
[1
] = diffractive ;
OPTIN
[2
] = diffuse ;
OPTIN
[3
] = ambient ;
OPTIN
[4
] = specularintensity ; OPTIN
[5
] = specularangle ;
}
void SetElementOptions
() {
for ( int i=0; i<NQ; i++
) {
setPolygonCull( QP
[0
][i
], false
, false
);
SetPolygonSurface
( QP
[0
][i
], OPTIN
);
}
for ( int i=0; i<NT; i++
) {
setPolygonCull( TP
[0
][i
], false
, false
);
SetPolygonSurface
( TP
[0
][i
], OPTIN
);
}
}
void AddElements
() {
for ( int i=0; i<NQ; i++
){
addPolygon( QP
[0
][i
], RENDERER
, CD
[0
] );
}
for ( int i=0; i<NT; i++
){
addPolygon( TP
[0
][i
], RENDERER
, CD
[0
] );
}
}
/* prepare stage */
double CAMERA_ORIGIN_Z = 7 * l ;
float GRAPHIC_MAGNIFICATION = 1000.0 ;
double GRAPHIC_DISTANCE = 10.0 ;
void PrepareStage
() {
setGraphics3DCenter( RENDERER
, WIDTH / 2
, HEIGHT / 2
);
setGraphics3DDistance( RENDERER
, GRAPHIC_DISTANCE
);
setGraphics3DMagnification( RENDERER
, GRAPHIC_MAGNIFICATION
);
setGraphics3DClipFront( RENDERER
, o
);
setGraphics3DClipBack( RENDERER
, -1000.0
);
int w =
getWorldCoordinate( RENDERER
) ;
setCoordinateOrigin( w
, o
, o
, o
);
setCoordinateEulerAngle( w
, o
, o
, o
);
setCameraOrigin( w
, o
, o
, CAMERA_ORIGIN_Z
);
setCameraEulerAngle( w
, o
, o
, o
);
}
/* animation Loop except
ただし、ForwardMotion
() と CreateGuiElements
() 以外 */
bool KEEP_LOOP = true ;
bool SAVE_A_PICTURE = false ;
int COUNT = 0 ;
int PAINT_FREQUENCY = 20 ;
int PICTURE_NUMBER = 0 ;
int PICTURE_END_NUMBER = 2000 ;
double T = o ;
double STEP
, TIME_FLOW ;
{
TIME_FLOW = 1.0 ;
STEP = TIME_FLOW / PAINT_FREQUENCY ;
}
/* create GUI elements */
int SETTING_WINDOW;
int LABEL
[ 2
];
N =
length( LABEL
) ;
int SLIDER
[ N
];
int CHECK_BOX
[ 2
];
bool REMOVE_HEXAHEDRON = false ;
bool REMOVE_OCTAHEDRON = false ;
double P
[ N
] = o ;
string LABEL_TEXT
[ N
];
N =
length( CHECK_BOX
) ;
string CHECK_BOX_TEXT
[ N
];
{
CHECK_BOX_TEXT
[0
] = "正六面体の表面と内部を描画しない" ;
CHECK_BOX_TEXT
[1
] = "正八面体の表面と内部を描画しない" ;
LABEL_TEXT
[0
] = "赤い面(正六面体)を広げる" ;
LABEL_TEXT
[1
] = "青い面(正八面体)を広げる" ;
}
void CreateGuiElements
() {
int nc =
length( CHECK_BOX
) ;
int nl =
length( LABEL
) , ns = nl ;
int lx = 15
, lw = 280 ;
int lh = 15 ;
int lyspace = 15 ;
int ly
[nl
];
int sx = lx
, sw = lw
, sh = lh
, syspace = 5 ;
int sy
[ns
];
int cbx = lx
, cbw = lw
, cby = 20
, cbh = 15
, cbyspace = lyspace ;
{
int initial_ly = nc*cby + nc*cbyspace + lyspace + 10;
for ( int i=0; i<
length( LABEL
); i++
) {
ly
[i
] = initial_ly +
( lh + lyspace + sh + syspace
) * i ;
sy
[i
] = ly
[i
] + lh + syspace ;
}
}
int wx = WINDOW_POSITION_X + WIDTH + 12 ;
int wy = 0 ;
int framewidth_y = 39 ;
int ww = lw + 40 ;
int wh = sy
[ns-1
] + sh + 70 ;
{
string wtext = "Setting Window" ;
SETTING_WINDOW =
newWindow( wx
, wy
, ww
, wh
, wtext
);
for ( int i=0; i<nc; i++
) {
int y = cby +
(cby + cbyspace
) * i ;
CHECK_BOX
[i
] =
newCheckBox( cbx
, y
, cbw
, cbh
, CHECK_BOX_TEXT
[i
], false
);
addComponent( CHECK_BOX
[i
], SETTING_WINDOW
);
}
for ( int i=0; i<nl; i++
) {
LABEL
[i
] =
newTextLabel( lx
, ly
[i
], lw
, lh
, LABEL_TEXT
[i
] );
addComponent( LABEL
[i
], SETTING_WINDOW
);
SLIDER
[i
] =
newHorizontalSlider( sx
, sy
[i
], sw
, sh
, o
);
addComponent( SLIDER
[i
], SETTING_WINDOW
);
}
}
paintComponent( SETTING_WINDOW
);
}
/* event handlers */
void onSliderMove( int id
, double value
) {
if ( id == SLIDER
[0
] ) {
if ( REMOVE_HEXAHEDRON == false
) {
P
[0
] = value;
l = a ;
AppendQuadrangle_to_QP
( P
[0
] );
}
} else if ( id == SLIDER
[1
] ) {
if ( REMOVE_OCTAHEDRON == false
) {
P
[1
] = value ;
l = a ;
AppendQuadrangle_to_TP
( P
[1
] );
}
}
}
int QQ
[ NQ
][ 4
]; // append to QP
{
for ( int i=0; i<NQ; i++
) {
for ( int j=0; j<4; j++
) {
QQ
[i
][j
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
setPolygonCull( QQ
[i
][j
], false
, false
);
SetPolygonSurface
( QQ
[i
][j
], OPTIN
);
SetPolygonColor
( QQ
[i
][j
], COLOR_Q
, OPACITY
[0
] );
}
}
}
void AppendQuadrangle_to_QP
( double p
) {
int n
[ ] =
length( QQ
);
int m = n
[0
]; // number of QQs
for a QP
int v
[ m
][ 4
];
for ( int i=0; i<m; i++
) {
v
[i
][0
] =
newVector( o
, l
, l
);
v
[i
][1
] =
newVector( p*l
, l
, l
);
v
[i
][2
] =
newVector( l
, l
, p*l
);
v
[i
][3
] =
newVector( l
, l
, o
);
for ( int j=0; j<4; j++
) {
rotYVector( v
[i
][j
], PI/2 * i
);
}
}
for ( int i=0; i<NQ; i++
) {
for ( int j=0; j<m; j++
) {
setPolygonVector( QQ
[i
][j
], v
[j
][0
], v
[j
][1
], v
[j
][2
], v
[j
][3
] );
if ( ( i >= 1
) &&
( i <= 4
) ) {
rotXPolygon( QQ
[i
][j
], PI/2
);
rotYPolygon( QQ
[i
][j
], PI/2 *
( i - 1
) );
} else if ( i == 5
) {
rotXPolygon( QQ
[i
][j
], PI
);
}
setPolygonSortOffset( QQ
[i
][j
], 0.4*
( 1.0 - p
) );
}
}
}
int QT
[ NT
][ 3
]; // append to TP
{
for ( int i=0; i<NT; i++
) {
for ( int j=0; j<3; j++
) {
QT
[i
][j
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
setPolygonCull( QT
[i
][j
], false
, false
);
SetPolygonSurface
( QT
[i
][j
], OPTIN
);
SetPolygonColor
( QT
[i
][j
], COLOR_T
, OPACITY
[1
] );
}
}
}
void AppendQuadrangle_to_TP
( double p
) {
int n
[ ] =
length( QT
);
int m = n
[0
]; // number of QTs
for a TP
int v
[ m
][ 4
];
for ( int i=0; i<m; i++
) {
v
[i
][0
] =
newVector( o
, l
, l
);
v
[i
][1
] =
newVector( l
, l
, o
);
v
[i
][2
] = GetInternallyDividingVector
( l
, l
, o
, o
, 2*l
, o
, p
);
v
[i
][3
] = GetInternallyDividingVector
( o
, l
, l
, o
, 2*l
, o
, p
);
for ( int j=0; j<4; j++
) {
rotVector( v
[i
][j
], 2*PI/3 * i
, l
, l
, l
);
}
}
for ( int i=0; i<NT; i++
) {
for ( int j=0; j<m; j++
) {
setPolygonVector( QT
[i
][j
], v
[j
][0
], v
[j
][1
], v
[j
][2
], v
[j
][3
] );
if ( ( i >= 1
) &&
( i <= 3
) ) {
rotYPolygon( QT
[i
][j
], PI/2 * i
);
} else if ( i >= 4
) {
rotZPolygon( QT
[i
][j
], PI
);
rotYPolygon( QT
[i
][j
], PI/2 *
( i -3
) );
}
setPolygonSortOffset( QT
[i
][j
], 0.4*
( 1.0 - p
) );
}
}
}
void onCheckBoxClick( int id
, bool remove
){
if ( id == CHECK_BOX
[0
] ) {
REMOVE_HEXAHEDRON = remove ;
if ( REMOVE_HEXAHEDRON
) {
l = o ;
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_QP
( P
[0
] );
} else {
l = a ;
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_QP
( P
[0
] );
REMOVE_HEXAHEDRON = remove ;
}
} else if ( id == CHECK_BOX
[1
] ) {
REMOVE_OCTAHEDRON = remove ;
if ( REMOVE_OCTAHEDRON
) {
l = o ;
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_TP
( P
[1
] );
} else {
l = a ;
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_TP
( P
[1
] );
REMOVE_OCTAHEDRON = remove ;
}
}
}
/* forward motion */
bool CREATE_GUI = false ;
void ForwardMotion
() {
int t =
newVector( o
, o
, o
) ; // x
,y成分がそれぞれ開始、終了時刻
DesignMotion
( t
); // アニメーション
float gui_uptime =
getVectorY( t
) ; //終了時刻にGUI windowを配置
CREATE_GUI =
( T >= gui_uptime
) &&
( T < gui_uptime + STEP
) ;
SetTRangeAbsolutely
( t
, o
, gui_uptime + 60.0
);
if ( Motion
( t
) ) {
spinYCoordinate( COORD
[0
], 2/180.0 * PI
);
}
}
void DesignMotion
( int v
) {
float start_t = 2.0 ;
double d = 0.3 ; // 時間の単位
SetTRangeAbsolutely
( v
, start_t
, start_t + 2*d
) ;
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
for ( int i=0; i<NQ; i++
) {
for ( int j=0; j<4; j++
) {
addPolygon( QQ
[i
][j
], RENDERER
, CD
[0
] );
}
}
}
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_QP
( t
);
}
SetTRange
( v
, d
, 2*d
);
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_QP
( 1.0 - t
);
}
SetTRange
( v
, d
, 2*d
);
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
for ( int i=0; i<NT; i++
) {
for ( int j=0; j<3; j++
) {
addPolygon( QT
[i
][j
], RENDERER
, CD
[0
] );
}
}
}
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_TP
( t
);
}
int u1 =
newVector( v
) ;
SetTRange
( v
, d
, 2*d
);
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_QP
( t
);
}
SetTRange
( v
, 2*d
, STEP
);
int u2 =
newVector( v
) ;
if ( Motion
( v
) ) {
l = o ;
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_QP
( o
);
l = 1.0 ;
}
SetTRange
( v
, 2*d
, STEP
);
if ( Motion
( v
) ) {
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_QP
( a
);
}
SetTRange
( v
, 2*d
, STEP
);
if ( Motion
( v
) ) {
l = o ;
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_TP
( o
);
l = 1.0 ;
}
SetTRange
( v
, 2*d
, STEP
);
if ( Motion
( v
) ) {
SetVectors68hedronTriangle
( VT
);
SetVectors68hedronQuadrangle
( VQ
);
SetPolygons6hedronVertexSymmetry
( TP
, VT
);
SetPolygons8hedronVertexSymmetry
( QP
, VQ
);
AppendQuadrangle_to_TP
( a
);
}
SetTRange
( v
, 2*d
, 4*d
);
float dt0 =
getVectorZ( v
) ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_TP
( 1.0 - t
);
}
SetTRange
( v
, -dt0/2
, dt0/2
);
float p1 = Slv - 1.0 ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_QP
( 1.0 - t + p1*t
);
}
SetTRange
( v
, 2*d
, 2*d
);
float p2 = 1.0/3 ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_TP
( p2*t
);
AppendQuadrangle_to_QP
( p1*
( 1.0 - t
) );
}
SetTRange
( v
, 2*d
, 2*d
);
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
AppendQuadrangle_to_TP
( p2*
( 1.0 - t
) );
}
SetTRangeAbsolutely
( u1
, start_t
, getVectorY( u1
) );
if ( Motion
( u1
) ) {
double t = GetLinearTime
( u1
) ;
setCoordinateEulerAngle( COORD
[1
], o
, 1.0*2*PI * t
, o
);
}
SetTRangeAbsolutely
( u2
, getVectorX( u2
), getVectorY( v
) );
if ( Motion
( u2
) ) {
double t = GetLinearTime
( u2
) ;
setCoordinateEulerAngle( COORD
[1
], 2*PI * t
, 1.0*2*PI
, o
);
}
SetTRange
( v
, o
, 5*d
);
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
setCoordinateEulerAngle( COORD
[1
], o
, o
, o
);
rotYCoordinate( COORD
[1
], -PI/2 * t
);
rotXCoordinate( COORD
[1
], atan( ISlv
) * t
);
}
}