import
Graphics ;
import Graphics3D ;
import GUI ;
import Math ;
void main
( string args
[] ){
TITLE = "菱形十二面体と立方八面体" ;
int winw = 256*2.75
, winh = 256*2.75
, winx = 90
, n = 0 ;
int bgcolor
[ ] = Color
( n
, n
, n
) ;
hide();
Set3DGraphics
( winw
, winh
, winx
, bgcolor
) ;
SetLights
();
SetCoordinates
();
SetElements
();
PrepareStage
();
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 ;
GUI_CREATED = true ;
}
PaintGraphics
( loop_periodic_time
);
if ( SAVE_A_PICTURE
) {
if ( PICTURE_SAVED
) {
if ( PICTURE_ALERT
) {
PICTURE_ALERT = false ;
alert( PICTURE_NUMBER
+ " 枚目までで画像の保存を中止しました。"
) ;
}
SAVE_A_PICTURE = false ;
} else {
if ( PICTURE_ALERT
) {
PICTURE_ALERT = false ;
alert(
( PICTURE_NUMBER+1
) + " 枚目以降の画像を保存します。"
+ linefeed
() + "保存番号を入力して下さい"
) ;
string nin = choice
(
"0"
, "1"
, "2"
, "3"
, "4"
, "5"
, "6"
, "7"
, "8"
, "9"
) ;
PICTURE_SAVE_ID = nin ;
}
SaveImagePNG
( PICTURE_SAVE_ID * 10000
) ;
}
}
loop_termination =
( PICTURE_NUMBER >= PICTURE_END_NUMBER
) ;
if ( loop_termination
) {
ExitLoopOverImageLimit
() ;
}
}
exit();
}
/*
import ここから */
// LIB000
/* 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
, R6 = 6
, R8 = 8 ;
// LIB010
/* 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
);
}
// LIB020
/* EVENTHANDLERS */
void onWindowClose( int id
) {
KEEP_LOOP = false ;
}
void onKeyDown( int id
, string key
){
if ( key == "SPACE"
) {
if ( SAVE_A_PICTURE
) {
PICTURE_SAVED = true ;
PICTURE_ALERT = true ;
} else {
PICTURE_SAVED = false ;
PICTURE_ALERT = true ;
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 ;
}
// LIB030
/* FUNCTIONS */
// 等式評価
bool Equality
( double x1
, double x2
, double infinitesimal
) {
double dif = x1 - x2 ;
return abs( dif
) < infinitesimal ;
}
// permuation
int Permuation
( int n
[ ] ) {
}
// unit step function
double Step
( double x
) {
double value;
if ( x < 0.0
) {
value = 0.0 ;
} else {
value = 1.0 ;
}
return value ;
}
double Slope
( double x
, double x0
, double deltax
) {
double value;
if ( x < x0
) {
value = 0.0 ;
} else if ( x <
( x0 + deltax
) ) {
value =
( x - x0
) / deltax ;
} else {
value = 1.0 ;
}
return value ;
}
double VelvetySlope
( double x
, double x0
, double deltax
) {
double value;
if ( x < x0
) {
value = 0.0 ;
} else if ( x <
( x0 + deltax
) ) {
double y =
( x - x0
) / deltax ;
value =
( 1.0 +
sin( -PI/2 + PI*y
) ) / 2 ;
} else {
value = 1.0 ;
}
return value ;
}
// eyeteeth
( teeth of saw
)
double Eyeteeth
( double x
, double width
) {
// 0 <= x <=1
double s = x ;
if ( ( x < 0.0
) ||
( x > 1.0
) ) {
alert( "Error
( Eyeteeth
) "
);
} else {
while ( s > width
) {
s = s - width ;
}
}
return s / width ;
}
// pulsar
double Pulsar
( double x
, double cycle
, double upslope
, double top
, double downslope
) {
// 0 <= x <=1
double value;
double s = Eyeteeth
( x
, cycle
) ;
double ups = upslope / cycle ;
double tops = top / cycle ;
double downs = downslope / cycle ;
if ( s < ups
) {
value = Bump
( s / ups * 0.5
) ;
} else if ( s < ups + tops
) {
value = 1.0 ;
} else if ( s < ups + tops + downs
) {
value = Bump
( 0.5 +
( ( s -
( ups + tops
) ) / downs
) * 0.5
) ;
} else {
value = 0.0 ;
}
return value ;
}
// unit bump function
double Bump
( double x
) {
return ( sin( 2*PI * x - PI/2
) + 1.0
) / 2 ;
}
double TurnBump
( double x
) {
return 1.0 - Bump
( x
) ;
}
double MSlope
( double x
) {
double y ;
if ( x > 1.0
) {
y = x -
(int
)( x
) ;
} else if ( x >= 0.0
) {
y = x ;
} else {
y = x +
( 1.0 -
(int
)( x
) ) ;
}
double value ;
if ( y > 1.0/2
) {
y = 1.0 - y ;
}
if ( y > 1.0/3
) {
value = 0.0 ;
} else if ( y > 1.0/6
) {
value = 2 - 6*y ;
} else {
value = 1.0 ;
}
return value ;
}
int Parity
( int i
) {
int p;
if ( i % 2 == 0
) {
p = 1 ;
} else {
p = -1 ;
}
return p ;
}
double
[ ] SolveQuadraticEquation
( double a
, double b
, double c
) {
double D = b^2 - 4 * a * c ;
double solution
[2
];
solution
[0
] =
( -b - D^0.5
) /
( 2*a
) ;
solution
[1
] =
( -b + D^0.5
) /
( 2*a
) ;
return solution ;
}
// LIB040
/* ROUTINE */
void PrintVectorln
( int v
, string s
) {
println( "Vector " + s + " = "
+
getVectorX( v
) + "
, "
+
getVectorY( v
) + "
, "
+
getVectorZ( v
)
);
}
void PrintDoubleArray
( double a
[ ], string s
) {
int n =
length( a
) ;
for ( int i=0; i<n; i++
) {
println( "s
( " + i + "
) = " + a
[i
] );
}
}
void SetParallelLight
(
int light
, float x
, float y
, float z
, float power
, int renderer
) {
light =
newLight( x
, y
, z
, power
) ;
addLight( light
, renderer
);
}
void SetAmbientLight
(
int light
, float x
, float y
, float z
, float power
, int renderer
) {
light = newAmbientLight
( x
, y
, z
, power
) ;
addLight( light
, renderer
);
}
void SetPointLight
(
int light
, float x
, float y
, float z
, float power
, int renderer
) {
light =
newPointLight( x
, y
, z
, power
) ;
addLight( light
, renderer
);
}
void SetPolygonSurface
( int id
, float x
[ ] ) {
setPolygonEmissive( id
, x
[0
] );
setPolygonDiffractive( id
, x
[1
] );
setPolygonDiffuse( id
, x
[2
] );
setPolygonAmbient( id
, x
[3
] );
setPolygonSpecular( id
, x
[4
], x
[5
] );
}
void SetModelSurface
( int id
, float x
[ ] ) {
setModelEmissive( id
, x
[0
] );
setModelDiffractive( id
, x
[1
] );
setModelDiffuse( id
, x
[2
] );
setModelAmbient( id
, x
[3
] );
setModelSpecular( id
, x
[4
], x
[5
] );
}
void SetPolygonColor
( int id
, int c
[ ], int opc
) {
setPolygonColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
// polygon色をまとめて指定
void SetPolygonColors
( int polygon
[ ][ ], int ng
, int color
[ ], int opacity
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
SetPolygonColor
( polygon
[ng
][i
], color
, opacity
) ;
}
}
void SetPolygonColors
(
int polygon
[ ][ ], int ng
, int color
[ ][ ], int nc
, int opacity
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
setPolygonColor(
polygon
[ng
][i
], color
[nc
][0
], color
[nc
][1
], color
[nc
][2
], opacity
) ;
}
}
// polygonのcullingをまとめて指定
void SetPolygonCull
( int polygon
[ ][ ], int ng
, bool cullout
, bool cullin
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
setPolygonCull( polygon
[ng
][i
], cullout
, cullin
) ;
}
}
// polygonの光学性質をもとめて指定
void SetPolygonSurface
( int polygon
[ ][ ], int ng
, float option
[ ] ) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
SetPolygonSurface
( polygon
[ng
][i
], option
) ;
}
}
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
, 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 m
, int renderer
, int cd
[ ][ ], int n
) {
for ( int i=0; i<
length( p
)[0
]; i++
) {
addPolygon( p
[m
][i
], renderer
, cd
[n
][i
] ) ;
}
}
void AddPolygons
( int p
[ ][ ], int ng
, int renderer
, int cd
) {
for ( int i=0; i<
length( p
)[0
]; i++
) {
addPolygon( p
[ng
][i
], renderer
, cd
) ;
}
}
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
] ) ;
}
}
}
int
[ ] ReduceDimension_2
( int v
[ ][ ], int n
) {
int m =
length( v
)[0
] ;
int u
[ m
] ;
for ( int i=0; i<m; i++
) {
u
[i
] =
newVector( v
[n
][i
] ) ;
}
return u ;
}
// LIB050
/* 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
);
}
}
// LIB060
/* COLORS */
int
[ ] Color
( int i
, int j
, int k
) {
int c
[ 3
] ;
if ( ( i < 0
) ||
( j < 0
) ||
( k < 0
)
||
( i > 255
) ||
( j > 255
) ||
( k > 255
) ) {
c = 0 ;
alert( "Error
( Color
) "
);
} else {
c
[0
] = i ;
c
[1
] = j ;
c
[2
] = k ;
}
return c ;
}
int
[ ] Color
( float r
, float g
, float b
) {
int c
[ 3
] ;
if ( ( r < 0.0
) ||
( g < 0.0
) ||
( b < 0.0
)
||
( r > 1.0
) ||
( g > 1.0
) ||
( b > 1.0
) ) {
c = 0 ;
alert( "Error
( Color
) "
);
} else {
c
[0
] = 255 * r ;
c
[1
] = 255 * g ;
c
[2
] = 255 * b ;
}
return c ;
}
int
[ ] Color
( float x
) {
int c
[ 3
] ;
if ( ( x < 0.0
) ||
( x > 1.0
) ) {
c = 0 ;
alert( "Error
( Color
) "
);
} else {
c = 255 * x ;
}
return c ;
}
int
[ ] BiColor
( float x
) {
int c
[ 3
] ;
c
[0
] = 255 * MSlope
( x
) ;
c
[1
] = 255 * MSlope
( x - 1.0/3
) ;
c
[2
] = 255 * MSlope
( x + 1.0/3
) ;
return c ;
}
// LIB070
/* GEOMETRY */
double GetHeightAntiprismByConnectionName
(
int nside
, double rad
, string polyhedronname
) {
double delta = rad *
( 1 -
cos( PI/nside
) ) ;
double antiprismdhangle ; // 底面と側面の normal vector の作る角
if ( polyhedronname == "cube"
) {
antiprismdhangle = 3*PI/4 ;
} else if ( polyhedronname == "octahedron"
) {
antiprismdhangle = PI/2 +
acos( Slv*IPlt
) ;
} else {
alert( "error
( GetHeightAntiprismByName
)"
) ;
}
double antiprismheight = delta *
tan( PI - antiprismdhangle
) ;
return antiprismheight ;
}
int
[ ] Get3Vectors4sideAntiprismCubeConnection
( double baserad
) {
int v
[ 3
] ;
v
[0
] =
newVector( o
, o
, baserad
) ;
v
[1
] = GetRotYVector
( v
[0
], PI/2
) ;
double h = GetHeightAntiprismByConnectionName
( 4
, baserad
, "cube"
) ;
v
[2
] =
newVector( o
, h
, o
) ;
return v ;
}
// dodecahedron の inradiusを返す
double GetInradiusDodecahedron
( double prad
) {
return prad *
( Gld + 1
) / 2 ;
}
// 原点中心、zx平面内、regular n-gonのz軸上の点
(z>0
)とその反時計回り隣の点
int
[ ] Get3VectorsNGon
( int n
, double rad
) {
int u
[ 3
] ;
u
[0
] =
newVector( o
, o
, o
) ;
u
[1
] =
newVector( o
, o
, rad
) ;
u
[2
] = GetRotYVector
( u
[1
], 2*PI/n
) ;
return u ;
}
// square cupola の頂点ベクトルを返す
int
[ ] Get12VectorsSquareCupola
( double baserad
) {
int v
[ 12
] ;
// 7 - 0 底面頂点
v
[0
] =
newVector( baserad*
sin(PI/8
), o
, baserad*
cos(PI/8
) ) ; // 底面の edge は z軸に直交する
for ( int i=1; i<=7; i++
) {
v
[i
] = GetRotYVector
( v
[0
], PI/4 * i
) ;
}
// 11 - 8 天井
double edge = 2 * baserad *
sin( PI/8
) ;
double h = edge * ISlv ;
v
[8
] =
newVector( edge/2
, h
, edge/2
) ;
for( int i=9; i<=11; i++
) {
v
[i
] = GetRotYVector
( v
[8
], PI/2 * i
) ;
}
return v ;
}
int
[ ] Get2VectorsSquareCupola
( double baserad
) {
int v
[ 2
] ;
v
[0
] =
newVector( baserad*
sin(PI/8
), o
, baserad*
cos(PI/8
) ) ; // 底面の edge は z軸に直交する
double edge = 2 * baserad *
sin( PI/8
) ;
double h = edge * ISlv ;
v
[1
] =
newVector( edge/2
, h
, edge/2
) ; // 天井の edge はx軸に平行
return v ;
}
// diamond space filler の頂点ベクトルを返す
int
[ ][ ][ ] GetVectorsDiamondSpaceFiller
( double x
) { // vertex
( x
, 0
, 0
)
int v
[ S4
][ R3*2
][ R3
] ;
v
[0
][0
][0
] =
newVector( o
, x
, o
) ;
v
[0
][0
][1
] =
newVector( -x/2
, x/2
, x/2
) ;
v
[0
][0
][2
] =
newVector( x/4
, x/4
, x/4
) ;
v
[0
][1
][0
] =
newVector( v
[0
][0
][1
] ) ;
v
[0
][1
][1
] =
newVector( o
, o
, x
) ;
v
[0
][1
][2
] =
newVector( v
[0
][0
][2
] ) ;
int ax0 =
newVector( a
, a
, a
) ;
int ax1 =
newVector( a
, o
, a
) ;
for ( int i=1; i<R3; i++
) {
for ( int j=0; j<R3; j++
) {
v
[0
][2*i
][j
] = GetRotVector
( v
[0
][0
][j
], 2*PI/3 * i
, ax0
, O
) ;
v
[0
][2*i+1
][j
] = GetRotVector
( v
[0
][1
][j
], 2*PI/3 * i
, ax0
, O
) ;
}
}
for ( int i=1; i<S4; i++
) {
for ( int j=0; j<R3*2; j++
) {
for ( int k=0; k<R3; k++
) {
v
[i
][j
][k
] = GetRotYVector
( v
[0
][j
][k
], PI/2 * i
) ;
if ( i%2 == 1
) {
rotVector( v
[i
][j
][k
], PI
, ax1
) ;
}
}
}
}
return v ;
}
// octahedron の頂点ベクトルを返す
int
[ ][ ] GetVectorsOctahedron
( double x
) { // vertex
( x
, 0
, 0
)
int v
[ S8
][ R3
] ;
v
[0
][0
] =
newVector( x
, o
, o
) ;
v
[0
][1
] =
newVector( o
, x
, o
) ;
v
[0
][2
] =
newVector( o
, o
, x
) ;
for ( int i=1; i<S8; i++
) {
for ( int j=0; j<R3; j++
) {
if ( i <= 3
) {
v
[i
][j
] = GetRotYVector
( v
[0
][j
], PI/2 *
( i%4
) ) ;
} else {
v
[i
][j
] = GetRotZVector
( v
[0
][j
], PI
) ;
rotYVector( v
[i
][j
], PI/2 *
( ( i - 3
) % 4
) ) ;
}
}
}
return v ;
}
int
[ ] GetVectors4FacesSymmetry
( double x
) { //
( x
, x
, x
)
int v
[ 4
] ;
v
[0
] =
newVector( x
, x
, x
) ;
v
[1
] = GetRotYVector
( v
[0
], PI
) ;
v
[2
] = GetRotXVector
( v
[0
], PI
) ;
v
[3
] = GetRotZVector
( v
[0
], PI
) ;
return v ;
}
int
[ ] GetVectors6FacesSymmetry
( double x
) { //
( o
, x
, o
)
int v
[ 6
] ;
v
[0
] =
newVector( o
, x
, o
) ;
v
[1
] = GetRotZVector
( v
[0
], PI/2
) ;
for ( int i=2; i<=4; i++
) {
v
[i
] = GetRotYVector
( v
[1
], PI/2 *
( i - 1
) ) ;
}
v
[5
] = GetRotZVector
( v
[0
], PI
) ;
return v ;
}
int
[ ][ ] GetTransformedVectors6FacesSymmetry
(
int v
[ ], double y
, double spiny
) {
int n =
length( v
) ;
int u
[ 6
][ n
] ;
int dely =
newVector( o
, y
, o
) ;
for ( int i=0; i<=5; i++
) {
for ( int j=0; j<n; j++
) {
if ( i == 0
) {
u
[i
][j
] =
newVector( v
[j
] ) ;
moveVector( u
[i
][j
], dely
) ;
rotYVector( u
[i
][j
], spiny
) ;
} else if ( i == 1
) {
u
[i
][j
] = GetRotZVector
( u
[0
][j
], -PI/2
) ;
} else if ( i <= 4
) {
u
[i
][j
] = GetRotYVector
( u
[1
][j
], PI/2 *
( i - 1
) ) ;
} else {
u
[i
][j
] = GetRotZVector
( u
[0
][j
], PI
) ;
}
}
}
return u ;
}
/*
import ここまで */
/* set lights */
int AMBIENT_LIGHT = newAmbientLight
( o
, o
, o
, o
) ;
int LIGHT0 =
newPointLight( -0.2*l
, -1.1*l
, 1.5*l
, o
) ;
int LIGHT1 =
newLight( 4.0
, 10.0
, 10.0
, o
) ;
int LIGHT2 =
newLight( -8.0
, -12.0
, 6.0
, o
) ;
void SetLights
() {
double power = 0.3 ;
SetAmbientLight
( AMBIENT_LIGHT
, o
, o
, o
, power
, RENDERER
);
}
/* create elements */
void SetElements
() {
SetElementOptions
();
AddElements
();
}
int NG = 1 ; // group の数
int R
[ NG
][ S12
]; // rhombus
int S
[ NG
][ S6
]; // square
int D
[ NG
][ S8
]; // triangle
int L
[ NG
][ S24
]; // lectangle
for ( int ng=0; ng<NG; ng++
) {
for ( int i=0; i<S12; i++
) {
R
[ng
][i
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
}
for ( int i=0; i<S6; i++
) {
S
[ng
][i
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
}
for ( int i=0; i<S8; i++
) {
D
[ng
][i
] =
newTrianglePolygon( O
, O
, O
) ;
}
for ( int i=0; i<S24; i++
) {
L
[ng
][i
] =
newQuadranglePolygon( O
, O
, O
, O
) ;
}
}
// 稜長xの立方体に外接する菱形十二面体菱形に対して相似比rの菱形
void SetSimilarRhombus
( double x
, double r
) {
int v
[ ] = GetVectorRhombus
( x
) ;
int g = GetVectorGravityCenter
( v
) ;
for ( int i=0; i<
length( v
); i++
) {
v
[i
] = GetVectorDifference
( v
[i
], g
) ;
scaleVector( v
[i
], r
, r
, r
);
v
[i
] = GetVectorSum
( g
, v
[i
] ) ;
}
for ( int ng=0; ng<NG; ng++
) {
for ( int i=0; i<S12; i++
) {
setPolygonVector( R
[ng
][i
], v
[0
], v
[1
], v
[2
], v
[3
] );
}
}
}
// 稜長xの立方体に外接する菱形十二面体の菱形頂点ベクトル。外接させた状態で長軸がxy面内第一象限
int
[ ] GetVectorRhombus
( double x
) {
int v
[ 4
];
v
[0
] =
newVector( x
, o
, o
) ;
v
[1
] =
newVector( x/2
, x/2
, -x/2
) ;
v
[2
] =
newVector( o
, x
, o
) ;
v
[3
] =
newVector( x/2
, x/2
, x/2
) ;
return v ;
}
// 切稜多面体の全ポリゴンをセット
void DeformRhombic12hedron
(
int rhombus
[ ][ ], int square
[ ][ ], int triangle
[ ][ ], int lectangle
[ ][ ],
double x
, double r
, int cd
[ ][ ], int parentcd
[ ], int ng
, int renderer
) {
int v
[ ] = GetVectorRhombus
( x
) ;
int g = GetVectorGravityCenter
( v
) ;
for ( int i=0; i<
length( v
); i++
) {
v
[i
] = GetVectorDifference
( v
[i
], g
) ;
scaleVector( v
[i
], r
, r
, r
);
v
[i
] = GetVectorSum
( g
, v
[i
] ) ;
}
for ( int i=0; i<S12; i++
) {
setPolygonVector( rhombus
[ng
][i
], v
[0
], v
[1
], v
[2
], v
[3
] );
}
SetSquare
( square
, v
, cd
, parentcd
, ng
, renderer
);
SetTriangle
( triangle
, v
, cd
, parentcd
, ng
, renderer
);
SetLectangle
( lectangle
, v
, cd
, parentcd
, ng
, renderer
);
}
void SetSquare
(
int square
[ ][ ], int v
[ ], int cd
[ ][ ], int parentcd
[ ], int ng
, int renderer
) {
int u
[ S4
];
u
[0
] = GetTransformedVector
( v
[0
], renderer
, cd
[ng
][0
], parentcd
[ng
] ) ;
for ( int i=1; i<S4; i++
) {
u
[i
] = GetRotXVector
( u
[0
], PI/2 * i
) ;
}
for ( int i=0; i<S6; i++
) {
setPolygonVector( square
[ng
][i
], u
[0
], u
[1
], u
[2
], u
[3
] );
if ( ( i >= 1
) &&
( i <= 3
) ) {
rotYPolygon( square
[ng
][i
], PI/2 * i
);
} else if ( i >= 4
) {
rotZPolygon( square
[ng
][i
], PI/2 * Parity
( i
) );
}
}
}
void SetTriangle
(
int triangle
[ ][ ], int v
[ ], int cd
[ ][ ], int parentcd
[ ], int ng
, int renderer
) {
int u
[ S3
];
u
[0
] = GetTransformedVector
( v
[3
], renderer
, cd
[ng
][0
], parentcd
[ng
] ) ;
int ax =
newVector( a
, a
, a
) ;
for ( int i=1; i<S3; i++
) {
u
[i
] = GetRotVector
( u
[0
], 2*PI/3 * i
, ax
, O
) ;
}
for ( int i=0; i<S8; i++
) {
setPolygonVector( triangle
[ng
][i
], u
[0
], u
[1
], u
[2
] );
rotYPolygon( triangle
[ng
][i
], PI/2 *
( i % 4
) );
rotZPolygon( triangle
[ng
][i
], PI *
( i / 4
) );
}
}
void SetLectangle
(
int lectangle
[ ][ ], int v
[ ], int cd
[ ][ ], int parentcd
[ ], int ng
, int renderer
) {
int u
[ S4
];
u
[0
] = GetTransformedVector
( v
[0
], renderer
, cd
[ng
][0
], parentcd
[ng
] ) ;
u
[1
] = GetTransformedVector
( v
[3
], renderer
, cd
[ng
][0
], parentcd
[ng
] ) ;
u
[2
] = GetTransformedVector
( v
[1
], renderer
, cd
[ng
][4
], parentcd
[ng
] ) ;
u
[3
] = GetTransformedVector
( v
[0
], renderer
, cd
[ng
][4
], parentcd
[ng
] ) ;
for ( int i=0; i<S24; i++
) {
setPolygonVector( lectangle
[ng
][i
], u
[0
], u
[1
], u
[2
], u
[3
] );
rotXPolygon( lectangle
[ng
][i
], PI/2 *
( i % 4
) );
if ( ( i >= 4
) &&
( i <= 15
) ) {
rotYPolygon( lectangle
[ng
][i
], PI/2 *
( i / 4
) );
} else if ( i >= 16
) {
rotZPolygon( lectangle
[ng
][i
], PI/2 * Parity
( i / 4
) );
}
}
}
int COLOR
[ 4
][ 3
], OPACITY
[ ] =
{ 255
, 175
} ;
{
float r
, g
, b ;
for ( int i=0; i<4; i++
) {
if ( i == 0
) {
r = 3*a/4 ; g = o ; b = a ;
} else if ( i == 1
) {
r = a ; g = o ; b = a/4 ;
} else if ( i == 2
) {
r = o ; g = o ; b = a ;
} else if ( i == 3
) {
r = a/1.5 ; g = a ; b = a/5 ;
}
for ( int j=0; j<3; j++
) {
COLOR
[i
][j
] = Color
( r
, g
, b
)[j
] ;
}
}
}
float OPTION0
[ 6
], OPTION1
[ 6
];
{
float emissive = o ;
float diffractive = 0.4 ;
float diffuse = 0.8 ;
float ambient = o ;
float specularintensity = 0.8
, specularangle = PI/3.7;
OPTION0
[0
] = emissive ;
OPTION0
[1
] = diffractive ;
OPTION0
[2
] = diffuse ;
OPTION0
[3
] = ambient ;
OPTION0
[4
] = specularintensity ; OPTION0
[5
] = specularangle ;
OPTION1 = OPTION0 ;
OPTION1
[0
] = 0.3 ;
OPTION1
[3
] = 0.3 ;
OPTION1
[4
] = 1.0 ; OPTION1
[5
] = 1.5 ;
}
void SetElementOptions
() {
for ( int ng=0; ng<NG; ng++
) {
SetPolygonCull
( R
, ng
, false
, false
) ;
SetPolygonSurface
( R
, ng
, OPTION0
) ;
SetPolygonCull
( S
, ng
, false
, false
) ;
SetPolygonSurface
( S
, ng
, OPTION0
) ;
SetPolygonCull
( D
, ng
, false
, false
) ;
SetPolygonSurface
( D
, ng
, OPTION0
) ;
SetPolygonCull
( L
, ng
, false
, false
) ;
SetPolygonSurface
( L
, ng
, OPTION0
) ;
}
}
void AddElements
() {
int n =
length( COORD
);
addLight( LIGHT1
, RENDERER
, COORD
[n-1
] ) ;
addLight( LIGHT0
, RENDERER
, COORD
[n-1
] ) ;
for ( int ng=0; ng<NG; ng++
) {
AddPolygons
( R
, ng
, RENDERER
, C
, ng
) ;
AddPolygons
( S
, ng
, RENDERER
, CD
[ng
] );
AddPolygons
( D
, ng
, RENDERER
, CD
[ng
] );
AddPolygons
( L
, ng
, RENDERER
, CD
[ng
] );
}
}
/* set coordinates */
int COORD
[ 4
];
int CD
[ NG
];
int C
[ NG
][ S12
];
for ( int i=0; i<
length( COORD
); i++
) {
COORD
[i
] =
newCoordinate() ;
}
for ( int ng=0; ng<NG; ng++
) {
CD
[ng
] =
newCoordinate() ;
for ( int i=0; i<S12; i++
) {
C
[ng
][i
] =
newCoordinate() ;
}
}
void SetCoordinates
() {
PileCoordinate
( COORD
, RENDERER
);
for ( int ng=0; ng<NG; ng++
) {
addCoordinate( CD
[ng
], RENDERER
, COORD
[0
] );
for ( int i=0; i<S12; i++
) {
addCoordinate( C
[ng
][i
], RENDERER
, CD
[ng
] );
}
}
}
void SetCoordinateSymmetry12
( int cd
[ ][ ], int ng
, double x
) {
for ( int i=0; i<S12; i++
) {
SetCoordinateLocationAttitude
( cd
[ng
][i
], O
, O
);
rotXCoordinate( cd
[ng
][i
], PI/2 *
( i / 4
) );
rotYCoordinate( cd
[ng
][i
], PI/2 *
( i % 4
) );
walkCoordinate( cd
[ng
][i
], x - l
, x - l
, o
);
}
}
/* set axes */
int AXIS
[ 10
];
{
int n =
length( AXIS
) ;
float x
, y
, z ;
for ( int i=0; i<n; i++
) {
x =
( 5*l - 0.5*l*i
) * l ; y = x ; z = x ;
AXIS
[i
] =
newAxisModel( x
, y
, z
) ;
}
}
void SetAxes
() {
addModel( AXIS
[0
], RENDERER
, COORD
[0
] );
addModel( AXIS
[4
], RENDERER
, CD
[0
] );
}
/* prepare stage */
double CAMERA_ORIGIN_Z = 3.5 * 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
(ただし、ForwardMotion
() と CreateGuiElements
() 以外
) */
bool KEEP_LOOP = true ;
bool SAVE_A_PICTURE = false ;
bool PICTURE_ALERT = true ;
bool PICTURE_SAVED = false ;
int COUNT = 0 ;
int FPS = 20 ; // frames / 1sec
int PICTURE_NUMBER = 0 ;
int PICTURE_SAVE_ID = 0 ;
int PICTURE_END_NUMBER = 5000 ;
double T = o
, T0 = -1000.0 ;
double STEP
, TIME_FLOW ;
{
TIME_FLOW = 1.0 ;
STEP = TIME_FLOW / FPS ;
}
/* create GUI elements */
int SETTING_WINDOW ;
int LABEL_SLIDER
[ 1
] ;
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 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 MOTION_START = false ;
bool MOTION_END = true ;
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
] = "多面体の回転" ;
SLIDER_TEXT
[0
] = "切稜" ;
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 = 180 ;
int lh = 15 ;
int lyspace = 25 ;
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 initial_ly = 25;
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 ;
}
for ( int i=0; i<nsld; i++
) {
sliderlabely
[i
] = selecty
[nsel-1
] + lh + 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
] + 85 ;
{
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
) ;
// 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 ;
SLIDER
[i
] =
newHorizontalSlider(
sliderx
, slidery
[i
], sliderw
, sliderh
, inivalue
) ;
addComponent( SLIDER
[i
], SETTING_WINDOW
) ;
}
}
paintComponent( SETTING_WINDOW
) ;
}
/* event handlers */
void onSliderMove( int id
, double value
) {
P
[0
] = 1 - value ;
DeformRhombic12hedron
( R
, S
, D
, L
, l
, P
[0
], C
, CD
, 0
, RENDERER
);
}
void onCheckBoxClick( int id
, bool state
){
if ( MOTION_END
) {
if ( id == CHECK_BOX
[0
] ) {
SPIN = state ;
} else {
}
}
}
void onSelectFieldClick( int id
, string text
){
if ( MOTION_END
) {
for ( int i=0; i<
length( SELECT_TEXT
)[0
]; i++
) {
if ( text == SELECT_TEXT
[0
][i
] ) {
if ( i != FORMER_OPACITY_INDEX
) {
OPACITY_INDEX = i ;
MOTION_START = true ;
MOTION_END = false ;
}
}
}
}
}
/* forward motion */
bool CREATE_GUI = false ;
bool GUI_CREATED = 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 ( !GUI_CREATED || !MOTION_END
) {
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
) ;
} else {
KEEP_LOOP = false ;
}
}
int SO
[ NG
]; //
system origin point
int SA
[ NG
]; //
system Euler Angle
int RC
[ NG
]; // rotation center vector
int AX
[ NG
]; // rotation axis vector
for ( int ng=0; ng<NG; ng++
) {
SO
[ng
] =
newVector() ;
SA
[ng
] =
newVector() ;
RC
[ng
] =
newVector() ;
AX
[ng
] =
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 / 1 ; // 時間の単位
SetTRangeAbsolutely
( v
, start_t
, start_t + STEP
) ;
if ( Motion
( v
) ) {
SetPolygonColors
( R
, 0
, COLOR
, 0
, OPACITY
[0
] ) ;
SetPolygonColors
( S
, 0
, COLOR
, 1
, OPACITY
[0
] ) ;
SetPolygonColors
( D
, 0
, COLOR
, 2
, OPACITY
[0
] ) ;
SetPolygonColors
( L
, 0
, COLOR
, 3
, OPACITY
[0
] ) ;
SetCoordinateSymmetry12
( C
, 0
, l
);
DeformRhombic12hedron
( R
, S
, D
, L
, l
, a
, C
, CD
, 0
, RENDERER
);
}
SetTRange
( v
, o
, 2*unit
) ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
double s = Slope
( t
, o
, 3 * a/4
) ;
setLightBrightness( LIGHT0
, 0.8 * s
) ;
s = Slope
( t
, a/2
, a/2
) ;
setLightBrightness( LIGHT1
, 0.2 * s
) ;
}
int stop =
newVector( v
) ;
if ( MOTION_START
) {
T0 = T ;
MOTION_START = false ;
}
SetTRangeAbsolutely
( v
, T0
, T0 + unit
) ;
if ( FORMER_OPACITY_INDEX != OPACITY_INDEX
) {
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
float r0 =
( 4 - FORMER_OPACITY_INDEX^2
) / 4 ;
float r1 =
( 4 - OPACITY_INDEX^2
) / 4 ;
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 ;
float option
[ ] =
{
emissive
, OPTION0
[1
], OPTION0
[2
], ambient
, sref
, sangle
} ;
SetPolygonColors
( R
, 0
, COLOR
, 0
, opacity
) ;
SetPolygonSurface
( R
, 0
, option
) ;
SetPolygonColors
( S
, 0
, COLOR
, 1
, opacity
) ;
SetPolygonSurface
( S
, 0
, option
) ;
SetPolygonColors
( D
, 0
, COLOR
, 2
, opacity
) ;
SetPolygonSurface
( D
, 0
, option
) ;
SetPolygonColors
( L
, 0
, COLOR
, 3
, opacity
) ;
SetPolygonSurface
( L
, 0
, option
) ;
if ( t == a
) {
FORMER_OPACITY_INDEX = OPACITY_INDEX ;
MOTION_END = true ;
}
}
}
setVector( v
, stop
) ;
}