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 = 90
, c = o ;
int bgcolor
[ ] = Color
( c
, c
, c
) ;
hide() ;
Set3DGraphics
( winw
, winh
, winx
, bgcolor
) ;
SetLights
() ;
SetCoordinates
() ;
SetElements
() ;
PrepareStage
() ;
int loop_periodic_time = 1000 / FPS ;
bool loop_termination = false ;
while ( KEEP_LOOP
){
if ( KEEP_MOTION
) {
if ( DECREASE_TIME
) {
T -= STEP ;
if ( T < o
) {
T = o ;
DECREASE_TIME = false ;
}
} else {
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
) ;
}
}
}
exit();
}
// import
/* LIB000 NUMERIC */
double o = 0.0
, a = 1.0
, d = 10.0 ;
double Slv = 2*
cos( PI/4
) , ISlv =
cos( PI/4
) ;
double Gld = 2*
cos( PI/5
) , IGld = Gld - 1.0 ;
double Plt = 2*
cos( PI/6
) , IPlt =
tan( PI/6
) ;
int O =
newVector( o
, o
, o
) ;
double l = 1.0 ; // 長さに用いる単位
int N ;
// symmetry
int S24 = 24
, S12 = 12
, S8 = 8
, S6 = 6
, S5 = 5
, S4 = 4
, S3 = 3
, S2 = 2 ;
int R3 = 3
, R4 = 4
, R5 = 5
, R6 = 6
, R8 = 8 ;
/* 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 ;
}
} else if ( key == "ENTER"
) {
if ( KEEP_MOTION
) {
KEEP_MOTION = false ;
} else {
KEEP_MOTION = true ;
}
} else if ( key == "R"
) {
if ( DECREASE_TIME
) {
DECREASE_TIME = false ;
} else {
DECREASE_TIME = true ;
}
}
}
void PaintGraphics
( int sleeptime
) {
sleep( sleeptime
);
paintGraphics3D( RENDERER
);
paintComponent( MAIN_DISPLAY_LABEL
);
paintComponent( MAIN_WINDOW
);
}
void SaveImagePNG
( int picid
) {
int picnumber = 0 ;
PICTURE_NUMBER = PICTURE_NUMBER + 1 ;
picnumber = picid + PICTURE_NUMBER ;
exportGraphics(
MAIN_GRAPHICS
, "./movie/a" + picnumber + ".png"
, "PNG"
) ;
}
void SaveImageJPEG
( int picid
) {
int picnumber = 0 ;
PICTURE_NUMBER = PICTURE_NUMBER + 1 ;
picnumber = picid + PICTURE_NUMBER ;
exportGraphics(
MAIN_GRAPHICS
, "./movie/a" + picnumber + ".jpg"
, "JPEG"
) ;
}
void ExitLoopOverImageLimit
() {
alert(
"画像の保存が上限
( "
+ PICTURE_END_NUMBER
+ " 枚
) に達したため、CGアニメーションを終了します。"
);
KEEP_LOOP = false ;
}
/* 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 opacity
) {
for ( int i=0; i<
length( polygon
)[1
]; i++
) {
for ( int j=0; j<
length( polygon
)[0
]; j++
) {
SetPolygonColor
( polygon
[ng
][i
][j
], color
, opacity
) ;
}
}
}
void SetPolygonColors
(
int polygon
[ ][ ], int ng
, int color
[ ][ ], int nc
, int opacity
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
setPolygonColor(
polygon
[ng
][i
], color
[nc
][0
], color
[nc
][1
], color
[nc
][2
], opacity
) ;
}
}
// polygonのcullingをまとめて指定
void SetPolygonCull
( int polygon
[ ][ ], int ng
, bool cullout
, bool cullin
) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
setPolygonCull( polygon
[ng
][i
], cullout
, cullin
) ;
}
}
void SetPolygonCull
( int polygon
[ ][ ][ ], int ng
, bool cullout
, bool cullin
) {
for ( int i=0; i<
length( polygon
)[1
]; i++
) {
for ( int j=0; j<
length( polygon
)[0
]; j++
) {
setPolygonCull( polygon
[ng
][i
][j
], cullout
, cullin
) ;
}
}
}
// polygonの光学性質をもとめて指定
void SetPolygonSurface
( int polygon
[ ][ ], int ng
, float option
[ ] ) {
for ( int i=0; i<
length( polygon
)[0
]; i++
) {
SetPolygonSurface
( polygon
[ng
][i
], option
) ;
}
}
void SetPolygonSurface
( int polygon
[ ][ ][ ], int ng
, float option
[ ] ) {
for ( int i=0; i<
length( polygon
)[1
]; i++
) {
for ( int j=0; j<
length( polygon
)[0
]; j++
) {
SetPolygonSurface
( polygon
[ng
][i
][j
], option
) ;
}
}
}
void SetModelColor
( int id
, int c
[ ], int opc
) {
setModelColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
void SetLightColor
( int id
, int c
[ ], int opc
) {
setLightColor( id
, c
[0
], c
[1
], c
[2
], opc
);
}
void PileCoordinate
( int cd
[ ] , int renderer
) {
int n =
length( cd
) ;
for ( int i=0; i<n; i++
) {
if ( i == 0
) {
addCoordinate( cd
[n-1-i
], renderer
);
} else {
addCoordinate( cd
[n-1-i
], renderer
, cd
[n-i
] );
}
}
}
// vectorの和を返す
int GetVectorSum
( int v1
, int v2
) {
int v =
newVector() ;
double vx =
getVectorX( v1
) +
getVectorX( v2
) ;
double vy =
getVectorY( v1
) +
getVectorY( v2
) ;
double vz =
getVectorZ( v1
) +
getVectorZ( v2
) ;
setVector( v
, vx
, vy
, vz
);
return v ;
}
// moveVectorの結果を返す
int GetMoveVector
( int v
, double x
, double y
, double z
) {
int u =
newVector( v
);
moveVector( u
, x
, y
, z
);
return u ;
}
// vectorの差を求めて代入する
void VectorDifference
( int v
, int v1
, int v2
) {
double vx =
getVectorX( v1
) -
getVectorX( v2
) ;
double vy =
getVectorY( v1
) -
getVectorY( v2
) ;
double vz =
getVectorZ( v1
) -
getVectorZ( v2
) ;
setVector( v
, vx
, vy
, vz
);
}
// vectorの差を返す
int GetVectorDifference
( int v1
, int v2
) {
double vx =
getVectorX( v1
) -
getVectorX( v2
) ;
double vy =
getVectorY( v1
) -
getVectorY( v2
) ;
double vz =
getVectorZ( v1
) -
getVectorZ( v2
) ;
int v =
newVector( vx
, vy
, vz
) ;
return v ;
}
// vectorを定数倍する
void ScaleVector
( int v
, double x
) {
scaleVector( v
, x
, x
, x
) ;
}
// vectorの定数倍を返す
int GetScaleVector
( int v
, double x
) {
int u =
newVector( v
) ;
scaleVector( u
, x
, x
, x
) ;
return u ;
}
// vectorの回転を求めて返す
int GetRotXVector
( int v
, double angle
) {
int u =
newVector( v
) ;
rotXVector( u
, angle
);
return u ;
}
int GetRotYVector
( int v
, double angle
) {
int u =
newVector( v
) ;
rotYVector( u
, angle
);
return u ;
}
int GetRotZVector
( int v
, double angle
) {
int u =
newVector( v
) ;
rotZVector( u
, angle
);
return u ;
}
int GetRotVector
( int v
, double angle
, int ax
, int rc
) {
int u =
newVector( v
) ;
rotVector( u
, angle
, ax
, rc
);
return u ;
}
// 内分点を求める。P1V ; VP2 = t : 1-t
int GetInternallyDividingVector
(
double x1
, double y1
, double z1
,
double x2
, double y2
, double z2
,
double t
) {
double vx =
( 1.0 - t
)*x1 + t*x2 ;
double vy =
( 1.0 - t
)*y1 + t*y2 ;
double vz =
( 1.0 - t
)*z1 + t*z2 ;
int v =
newVector ( vx
, vy
, vz
) ;
return v ;
}
int GetInternallyDividingVector
( int v1
, int v2
, double t
) {
double vx =
( 1.0 - t
)*
getVectorX( v1
) + t*
getVectorX( v2
) ;
double vy =
( 1.0 - t
)*
getVectorY( v1
) + t*
getVectorY( v2
) ;
double vz =
( 1.0 - t
)*
getVectorZ( v1
) + t*
getVectorZ( v2
) ;
int v =
newVector ( vx
, vy
, vz
) ;
return v ;
}
int GetMiddlePointVector
( int v1
, int v2
) {
double x =
( getVectorX( v1
) +
getVectorX( v2
) ) / 2 ;
double y =
( getVectorY( v1
) +
getVectorY( v2
) ) / 2 ;
double z =
( getVectorZ( v1
) +
getVectorZ( v2
) ) / 2 ;
int mid =
newVector( x
, y
, z
) ;
return mid ;
}
// vをcdに配置してCDへ変換したものを求める
int GetTransformedVector
( int v
, int renderer
, int cd
, int CD
) {
int u =
newVector( v
) ;
addVector( v
, renderer
, cd
);
transformVector( v
, u
, CD
);
removeVector
( v
, renderer
, cd
);
return u ;
}
void TransformVector
( int v
, int renderer
, int cd
, int u
, int CD
) {
addVector( v
, renderer
, cd
);
transformVector( v
, u
, CD
);
removeVector
( v
, renderer
, cd
);
}
void SetCoordinateOrigin
( int cd
, double x
[ ] ) {
setCoordinateOrigin( cd
, x
[0
], x
[1
], x
[2
] );
}
int GetVectorCoordinateOrigin
( int cd
) {
int v =
newVector(
getCoordinateOriginX( cd
),
getCoordinateOriginY( cd
),
getCoordinateOriginZ( cd
)
);
return v ;
}
// 重心を返す
int GetVectorGravityCenter
( int v
[ ] ) {
int g =
newVector( v
[0
] ) ;
for ( int i=1; i<
length( v
); i++
) {
moveVector( g
, v
[i
] );
}
double s = 1.0 /
length( v
) ;
scaleVector( g
, s
, s
, s
);
return g ;
}
double
[ ] getCenterOfGravity
( int v
[ ] ) {
int g =
newVector( v
[0
] ) ;
int lenv =
length( v
) ;
for ( int i=1; i<lenv; i++
) {
moveVector( g
, v
[i
] );
}
double s = 1.0 / lenv ;
scaleVector( g
, s
, s
, s
);
double x
[ 3
];
x
[0
] =
getVectorX( g
) ;
x
[1
] =
getVectorY( g
) ;
x
[2
] =
getVectorZ( g
) ;
return x ;
}
// normal vectorを返す
int GetNormalVectorQuadrangle
( int v
[ ] ) {
int v1 = GetVectorDifference
( v
[2
], v
[0
] ) ;
int v2 = GetVectorDifference
( v
[3
], v
[1
] ) ;
int normalv =
newVector() ;
getVectorCrossProduct( v1
, v2
, normalv
);
double length =
getVectorLength( normalv
) ;
if ( !
( length == o
) ) {
setVectorLength( normalv
, 1.0
);
} else {
alert( "error
( GetNormalVectorQuadrangle
)"
) ;
}
return normalv ;
}
// 2枚の面の作る角の余弦を返す
double GetAngleFaceFace
( int v1
[ ], int v2
[ ] ) {
int n1 = GetNormalVectorQuadrangle
( v1
) ;
int n2 = GetNormalVectorQuadrangle
( v2
) ;
double costh =
getVectorInnerProduct( n1
, n2
) ;
return costh ;
}
void SetVectorsCoordinateLocationAttitude
( int vo
, int va
, int cd
) {
double x =
getCoordinateOriginX( cd
) ;
double y =
getCoordinateOriginY( cd
) ;
double z =
getCoordinateOriginZ( cd
) ;
double a =
getCoordinateEulerAngleAlpha( cd
) ;
double b =
getCoordinateEulerAngleBeta( cd
) ;
double g =
getCoordinateEulerAngleGamma( cd
) ;
setVector( vo
, x
, y
, z
);
setVector( va
, a
, b
, g
);
}
void SetVectorsCoordinateLocationAttitude
( int so
[ ], int sa
[ ], int cd
[ ] ) {
double x
, y
, z
, a
, b
, g ;
for ( int i=0; i<
length( cd
); i++
) {
x =
getCoordinateOriginX( cd
[i
] ) ;
y =
getCoordinateOriginY( cd
[i
] ) ;
z =
getCoordinateOriginZ( cd
[i
] ) ;
a =
getCoordinateEulerAngleAlpha( cd
[i
] ) ;
b =
getCoordinateEulerAngleBeta( cd
[i
] ) ;
g =
getCoordinateEulerAngleGamma( cd
[i
] ) ;
setVector( so
[i
], x
, y
, z
) ;
setVector( sa
[i
], a
, b
, g
) ;
}
}
void SetCoordinateLocationAttitude
( int cd
, int vo
, int va
) {
double x =
getVectorX( vo
) ;
double y =
getVectorY( vo
) ;
double z =
getVectorZ( vo
) ;
double a =
getVectorX( va
) ;
double b =
getVectorY( va
) ;
double g =
getVectorZ( va
) ;
setCoordinateOrigin( cd
, x
, y
, z
);
setCoordinateEulerAngle( cd
, a
, b
, g
);
}
void SetCoordinateEulerAngle
( int cd
, int v
) {
setCoordinateEulerAngle( cd
,
getVectorX( v
), getVectorY( v
), getVectorZ( v
)
);
}
double
[ ] GetArryCoordinateEulerAngle
( int cd
) {
double ea
[ 3
];
ea
[0
] =
getCoordinateEulerAngleAlpha( cd
) ;
ea
[1
] =
getCoordinateEulerAngleBeta( cd
) ;
ea
[2
] =
getCoordinateEulerAngleGamma( cd
) ;
return ea ;
}
int GetVectorCoordinateEulerAngle
( int cd
) {
double ea
[ 3
];
ea
[0
] =
getCoordinateEulerAngleAlpha( cd
) ;
ea
[1
] =
getCoordinateEulerAngleBeta( cd
) ;
ea
[2
] =
getCoordinateEulerAngleGamma( cd
) ;
int v =
newVector( ea
) ;
return v ;
}
// リセットなしの回転
void RotateCoordinate
(
int cd
, int so
, int sa
, double angle
, int ax
, int rc
, int renderer
, int Cd
) {
int dummycd =
newCoordinate() ;
addCoordinate( dummycd
, renderer
, Cd
) ;
SetCoordinateLocationAttitude
( dummycd
, so
, sa
) ;
rotCoordinate( dummycd
, angle
, ax
, rc
) ;
int sovalue =
newVector() ;
int savalue =
newVector();
SetVectorsCoordinateLocationAttitude
( sovalue
, savalue
, dummycd
) ;
SetCoordinateLocationAttitude
( cd
, sovalue
, savalue
) ;
removeCoordinate( dummycd
, renderer
, Cd
) ;
}
// O から dist 離れた地点へresetなしに移す
, y-direction
void SetCoordinateLocationYdirection
( int cd
, double dist
) {
int dummycd =
newCoordinate() ;
int v =
newVector() ;
CopyCoordinateAttitude
( dummycd
, cd
) ;
walkCoordinate( dummycd
, o
, dist
, o
) ;
v = GetVectorCoordinateOrigin
( dummycd
) ;
setCoordinateOrigin( cd
, v
) ;
}
// 座標系の姿勢をコピー
(座標系原点はコピーせず O とする
)
void CopyCoordinateAttitude
( int cd
, int originalcd
) {
int sa = GetVectorCoordinateEulerAngle
( originalcd
) ;
SetCoordinateLocationAttitude
( cd
, O
, sa
) ;
}
// y軸及びz軸が引数ベクトルと平行な姿勢にする
void SetCoordinateAttitudeYZ
( int cd
, int vy
, int vz
) {
int uy =
newVector( vy
) ;
int uz =
newVector( vz
) ;
setVectorLength( uy
, 1.0
);
setVectorLength( uz
, 1.0
);
int ux =
newVector() ;
getVectorCrossProduct( uy
, uz
, ux
);
setCoordinateBaseX( cd
, ux
);
setCoordinateBaseY( cd
, uy
);
setCoordinateBaseZ( cd
, uz
);
}
// 原点が v2
, cylinder 端点が v1
, v2 となるように cd を set する
void SetCoordinateCylinder
( int cyl
, double rad
, int v1
, int v2
, int cd
) {
double x
[ 3
];
x
[0
] =
getVectorX( v1
) -
getVectorX( v2
) ;
x
[1
] =
getVectorY( v1
) -
getVectorY( v2
) ;
x
[2
] =
getVectorZ( v1
) -
getVectorZ( v2
) ;
int v21 =
newVector( x
) ;
double length =
getVectorLength( v21
) ; // シリンダーの長さ
if ( length != 0.0
) {
int xyprojection =
newVector( x
[0
], x
[1
], 0.0
) ;
setVectorLength( xyprojection
, 1.0
) ;
double cos1 =
getVectorY( xyprojection
) ; // xy射影がy軸となす角の余弦
double th1; // xy射影がy軸となす角度
if ( x
[1
] == 0.0
) {
if ( x
[0
] >= 0.0
) {
th1 = PI/2 ;
} else {
th1 = -PI/2 ;
}
} else if( x
[0
] < 0.0
) {
th1 = -
acos( cos1
) ;
} else {
th1 =
acos( cos1
) ;
}
setVectorLength( v21
, 1.0
);
double sin2 =
getVectorZ( v21
); // 射影と元のベクトルのなす角の正弦
double th2 =
asin( sin2
) ;
double alpha = -th1 ;
double beta = th2 - PI/2 ;
double gamma = 0.0 ;
if ( th1 < 0.0
) { gamma = PI ;
}
setCoordinateOrigin( cd
, v2
);
setCoordinateEulerAngle( cd
, alpha
, beta
, gamma
);
setModelSize( cyl
, rad
, rad
, length );
}
}
void SetSphereSize
( int sp
, double rad
) {
setModelSize( sp
, rad
, rad
, rad
);
}
// n 番目の多面体のすべての面の頂点を vector で指定する
void SetTriangleVector
( int p
[ ][ ], int n
, int v
[ ][ ] ) {
for ( int i=0; i<
length( p
); i++
) {
setPolygonVector( p
[n
][i
], v
[i
][0
], v
[i
][1
], v
[i
][2
] ) ;
}
}
void SetTriangleVector
( int p
[ ][ ][ ], int n
, int v
[ ][ ] ) {
for ( int i=0; i<
length( p
)[1
]; i++
) {
for ( int j=0; j<
length( p
)[0
]; j++
) {
setPolygonVector( p
[n
][i
][j
], v
[i
][j
][0
], v
[i
][j
][1
], v
[i
][j
][2
] ) ;
}
}
}
// polygon をまとめて配置する
void AddPolygons
( int p
[ ][ ], int 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
[ ] RV2_1
( int v
[ ][ ], int n
) { // ベクトルの2次元配列からベクトルの1次元配列を作る
int m =
length( v
)[0
] ;
int u
[ m
] ;
for ( int i=0; i<m; i++
) {
u
[i
] =
newVector( v
[n
][i
] ) ;
}
return u ;
}
int
[ ] RV2_0
( int v
[ ][ ], int n
) { // ベクトルの2次元配列からベクトルの1次元配列を作る
int m =
length( v
)[1
] ;
int u
[ m
] ;
for ( int i=0; i<m; i++
) {
u
[i
] =
newVector( v
[i
][n
] ) ;
}
return u ;
}
int
[ ] RA2_0
( int arry
[ ][ ], int n
) { // 整数型2次元配列から整数型1次元配列を作る
int m =
length( arry
)[0
] ;
int rarry
[ m
] ;
for ( int i=0; i<m; i++
) {
rarry
[i
] = arry
[n
][i
] ;
}
return rarry ;
}
/* LIB051 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 BLINDER =
newQuadranglePolygon( 2*l
,2*l
,o
, -2*l
,2*l
,o
, -2*l
,-2*l
,o
, 2*l
,-2*l
,o
) ;
setPolygonEmissive( BLINDER
, 1.0
);
setPolygonSpecular( BLINDER
, o
, 0.01
);
int TEXT = NewTextPolygonLowLeft
( TEXT_RUSEN
, GRAPHIC_MAGNIFICATION
, -0.5
) ;
int NewTextPolygonLowLeft
( string text
, double magnification
, double z
) {
int framewidth_x = 14 ;
int framewidth_y = 39 ;
double size = -50 * z / magnification ;
double x = -size *
( WIDTH - framewidth_x
) / 100 ;
double y = -size *
( HEIGHT - framewidth_y
) / 100 ;
int txtpolygon =
newTextPolygon( x
, y
, 1.0 + z
, 0.9 * size
, text
) ;
return txtpolygon ;
}
void OpenTextWhite
( int v
, double t0
, double t1
) {
SetTRangeAbsolutely
( v
, t0
, t1
);
VisualizePolygon
( BLINDER
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, o
, 3.0
);
if ( Moment
( v
) ) {
COUNT = -1 ;
}
RemovePolygonAfterUnvisualize
( BLINDER
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, -4.0
, 4.0
);
VisualizePolygon
( TEXT
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, 3.0
, 8.0
);
UnvisualezePolygon
( TEXT
, 255
, 255
, 255
, 5
, v
);
SetTRange
( v
, -14.0
, o
);
}
void OpenBlindBlack
( int v
, double t0
, double t1
) {
SetTRangeAbsolutely
( v
, t0
, t1
);
VisualizePolygon
( BLINDER
, RENDERER
, 0
, 0
, 0
, v
);
SetTRange
( v
, o
, 3.0
);
if ( Moment
( v
) ) {
COUNT = -1 ;
}
RemovePolygonAfterUnvisualize
( BLINDER
, RENDERER
, 0
, 0
, 0
, v
);
SetTRange
( v
, -3.0
, 5.0
);
VisualizePolygon
( TEXT
, RENDERER
, 255
, 255
, 255
, v
);
SetTRange
( v
, 8.0
, 5.0
);
UnvisualezePolygon
( TEXT
, 255
, 255
, 255
, 5
, v
);
SetTRange
( v
, -18.0
, o
);
}
void CloseTextWhite
( int v
, double dt1
, double dt0
) {
SetTRange
( v
, dt1
, dt0
);
if ( Motion
( v
) ) {
double t = 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 ;
}
int
[ ] MixedColor
(
float r1
, float g1
, float b1
,
float r2
, float g2
, float b2
,
double p
) {
int color
[ 3
] ;
float c1
[ ] =
{ r1
, g1
, b1
} ;
float c2
[ ] =
{ r2
, g2
, b2
} ;
for ( int i=0; i<
length( color
); i++
) {
color
[i
] = 255 *
( c1
[i
] *
( 1 - p
) + c2
[i
] * p
) ;
}
return color ;
}
int
[ ] MixedColor
( int color1
[ ], int color2
[ ], double p
){
int color
[ 3
] ;
for ( int i=0; i<
length( color
); i++
) {
color
[i
] = color1
[i
] *
( 1 - p
) + color2
[i
] * p ;
}
return color ;
}
/* LIB070 GEOMETRY */
double GetHeightAntiprismByConnectionName
(
int nside
, double rad
, string polyhedronname
) {
double delta = rad *
( 1 -
cos( PI/nside
) ) ;
double antiprismdhangle ; // 底面と側面の normal vector の作る角
if ( polyhedronname == "cube"
) {
antiprismdhangle = 3*PI/4 ;
} else if ( polyhedronname == "octahedron"
) {
antiprismdhangle = PI/2 +
acos( Slv*IPlt
) ;
} else {
alert( "error
( GetHeightAntiprismByName
)"
) ;
}
double antiprismheight = delta *
tan( PI - antiprismdhangle
) ;
return antiprismheight ;
}
int
[ ] Get3Vectors4sideAntiprismCubeConnection
( double baserad
) {
int v
[ 3
] ;
v
[0
] =
newVector( o
, o
, baserad
) ;
v
[1
] = GetRotYVector
( v
[0
], PI/2
) ;
double h = GetHeightAntiprismByConnectionName
( 4
, baserad
, "cube"
) ;
v
[2
] =
newVector( o
, h
, o
) ;
return v ;
}
// dodecahedron の inradiusを返す
double GetInradiusDodecahedron
( double prad
) {
return prad *
( Gld + 1
) / 2 ;
}
// 原点中心、zx平面内、regular n-gonのz軸上の点
(z>0
)とその反時計回り隣の点
int
[ ] Get3VectorsNGon
( int n
, double rad
) {
int u
[ 3
] ;
u
[0
] =
newVector( o
, o
, o
) ;
u
[1
] =
newVector( o
, o
, rad
) ;
u
[2
] = GetRotYVector
( u
[1
], 2*PI/n
) ;
return u ;
}
// square cupola の頂点ベクトルを返す
int
[ ] Get12VectorsSquareCupola
( double baserad
) {
int v
[ 12
] ;
// 7 - 0 底面頂点
v
[0
] =
newVector( baserad*
sin(PI/8
), o
, baserad*
cos(PI/8
) ) ; // 底面の edge は z軸に直交する
for ( int i=1; i<=7; i++
) {
v
[i
] = GetRotYVector
( v
[0
], PI/4 * i
) ;
}
// 11 - 8 天井
double edge = 2 * baserad *
sin( PI/8
) ;
double h = edge * ISlv ;
v
[8
] =
newVector( edge/2
, h
, edge/2
) ;
for( int i=9; i<=11; i++
) {
v
[i
] = GetRotYVector
( v
[8
], PI/2 * i
) ;
}
return v ;
}
int
[ ] Get2VectorsSquareCupola
( double baserad
) {
int v
[ 2
] ;
v
[0
] =
newVector( baserad*
sin(PI/8
), o
, baserad*
cos(PI/8
) ) ; // 底面の edge は z軸に直交する
double edge = 2 * baserad *
sin( PI/8
) ;
double h = edge * ISlv ;
v
[1
] =
newVector( edge/2
, h
, edge/2
) ; // 天井の edge はx軸に平行
return v ;
}
// diamond space filler の頂点ベクトルを返す
int
[ ][ ][ ] GetVectorsDiamondSpaceFiller
( double x
) { // vertex
( x
, 0
, 0
)
int v
[ S4
][ R3*2
][ R3
] ;
v
[0
][0
][0
] =
newVector( o
, x
, o
) ;
v
[0
][0
][1
] =
newVector( -x/2
, x/2
, x/2
) ;
v
[0
][0
][2
] =
newVector( x/4
, x/4
, x/4
) ;
v
[0
][1
][0
] =
newVector( v
[0
][0
][1
] ) ;
v
[0
][1
][1
] =
newVector( o
, o
, x
) ;
v
[0
][1
][2
] =
newVector( v
[0
][0
][2
] ) ;
int ax0 =
newVector( a
, a
, a
) ;
int ax1 =
newVector( a
, o
, a
) ;
for ( int i=1; i<R3; i++
) {
for ( int j=0; j<R3; j++
) {
v
[0
][2*i
][j
] = GetRotVector
( v
[0
][0
][j
], 2*PI/3 * i
, ax0
, O
) ;
v
[0
][2*i+1
][j
] = GetRotVector
( v
[0
][1
][j
], 2*PI/3 * i
, ax0
, O
) ;
}
}
for ( int i=1; i<S4; i++
) {
for ( int j=0; j<R3*2; j++
) {
for ( int k=0; k<R3; k++
) {
v
[i
][j
][k
] = GetRotYVector
( v
[0
][j
][k
], PI/2 * i
) ;
if ( i%2 == 1
) {
rotVector( v
[i
][j
][k
], PI
, ax1
) ;
}
}
}
}
return v ;
}
// octahedron の頂点ベクトルを返す
int
[ ][ ] GetVectorsOctahedron
( double x
) { // vertex
( x
, 0
, 0
)
int v
[ S8
][ R3
] ;
v
[0
][0
] =
newVector( x
, o
, o
) ;
v
[0
][1
] =
newVector( o
, x
, o
) ;
v
[0
][2
] =
newVector( o
, o
, x
) ;
for ( int i=1; i<S8; i++
) {
for ( int j=0; j<R3; j++
) {
if ( i <= 3
) {
v
[i
][j
] = GetRotYVector
( v
[0
][j
], PI/2 *
( i%4
) ) ;
} else {
v
[i
][j
] = GetRotZVector
( v
[0
][j
], PI
) ;
rotYVector( v
[i
][j
], PI/2 *
( ( i - 3
) % 4
) ) ;
}
}
}
return v ;
}
int
[ ] GetVectors4FacesSymmetry
( double x
) { //
( x
, x
, x
)
int v
[ 4
] ;
v
[0
] =
newVector( x
, x
, x
) ;
v
[1
] = GetRotYVector
( v
[0
], PI
) ;
v
[2
] = GetRotXVector
( v
[0
], PI
) ;
v
[3
] = GetRotZVector
( v
[0
], PI
) ;
return v ;
}
int
[ ] GetVectors6FacesSymmetry
( double x
) { //
( o
, x
, o
)
int v
[ 6
] ;
v
[0
] =
newVector( o
, x
, o
) ;
v
[1
] = GetRotZVector
( v
[0
], PI/2
) ;
for ( int i=2; i<=4; i++
) {
v
[i
] = GetRotYVector
( v
[1
], PI/2 *
( i - 1
) ) ;
}
v
[5
] = GetRotZVector
( v
[0
], PI
) ;
return v ;
}
int
[ ] GetVectors8FacesSymmetry
( double x
) { //
( x
, x
, x
)
int v
[ 8
] ;
v
[0
] =
newVector( x
, x
, x
) ;
v
[4
] =
newVector( x
, -x
, x
) ;
for ( int i=1; i<4; i++
) {
v
[i
] = GetRotYVector
( v
[0
], PI/2 * i
) ;
v
[4+i
] = GetRotYVector
( v
[4
], PI/2 * i
) ;
}
return v ;
}
int
[ ] GetEulerAngleVectors8FacesSymmetry
() { // y軸が normal vector
int sa
[8
] ;
int cd =
newCoordinate() ;
int ax =
newVector( a
, o
, -a
) ;
rotXCoordinate( cd
, -
atan( Slv
) ) ;
rotYCoordinate( cd
, -3*PI/4
) ;
sa
[0
] = GetVectorCoordinateEulerAngle
( cd
) ;
for ( int i=1; i<4; i++
) {
rotYCoordinate( cd
, PI/2
) ;
sa
[i
] = GetVectorCoordinateEulerAngle
( cd
) ;
}
setCoordinateEulerAngle( cd
, o
, o
, o
) ;
rotXCoordinate( cd
, PI/2 +
atan( ISlv
) ) ;
rotYCoordinate( cd
, PI/4
) ;
sa
[4
] = GetVectorCoordinateEulerAngle
( cd
) ;
for ( int i=5; i<8; i++
) {
rotYCoordinate( cd
, PI/2
) ;
sa
[i
] = GetVectorCoordinateEulerAngle
( cd
) ;
}
return sa ;
}
int
[ ][ ] GetTransformedVectors6FacesSymmetry
(
int v
[ ], double y
, double spiny
) {
int n =
length( v
) ;
int u
[ 6
][ n
] ;
int dely =
newVector( o
, y
, o
) ;
for ( int i=0; i<=5; i++
) {
for ( int j=0; j<n; j++
) {
if ( i == 0
) {
u
[i
][j
] =
newVector( v
[j
] ) ;
moveVector( u
[i
][j
], dely
) ;
rotYVector( u
[i
][j
], spiny
) ;
} else if ( i == 1
) {
u
[i
][j
] = GetRotZVector
( u
[0
][j
], -PI/2
) ;
} else if ( i <= 4
) {
u
[i
][j
] = GetRotYVector
( u
[1
][j
], PI/2 *
( i - 1
) ) ;
} else {
u
[i
][j
] = GetRotZVector
( u
[0
][j
], PI
) ;
}
}
}
return u ;
}
//
import end
/* set lights */
int AMBIENT_LIGHT = newAmbientLight
( o
, o
, o
, 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.5 ;
SetAmbientLight
( AMBIENT_LIGHT
, o
, o
, o
, power
, RENDERER
);
}
/* create elements */
void SetElements
() {
SetElementOptions
();
AddElements
();
}
int NG = 8 ; // group の数
int TR00
[ NG
][ R6
][ 1+1
] ; // base
, roof
, center
, hexagon
int TR01
[ NG
][ R3
][ 1+1
] ; // base
, roof
, center
, vertex
int TR10
[ NG
][ R6
][ R3+R3
] ; // lateral
, center
, hexagon
int TR11
[ NG
][ R3
][ R3+R3
] ; // lateral
, vertex
for ( int i=0; i<NG; i++
) {
for ( int j=0; j<R6; j++
) {
for ( int k=0; k<R3+R3; k++
) {
if ( j < R3
) {
if ( k < 1+1
) {
TR01
[i
][j
][k
] =
newTrianglePolygon( O
, O
, O
) ;
}
TR11
[i
][j
][k
] =
newTrianglePolygon( O
, O
, O
) ;
}
if ( k < 1+1
) {
TR00
[i
][j
][k
] =
newTrianglePolygon( O
, O
, O
) ;
}
TR10
[i
][j
][k
] =
newTrianglePolygon( O
, O
, O
) ;
}
}
}
void SetPolygons3SideAntiprismOctahedronConnection
(
double x
,
int t00
[ ][ ][ ], int t01
[ ][ ][ ], int t10
[ ][ ][ ], int t11
[ ][ ][ ],
int ng
) {
int v3
[ ] = Get3VectorsNGon
( 3
, x
) ;
int base3
[ 3
], roof3
[ 3
] ;
base3
[0
] =
newVector( v3
[1
] ) ;
base3
[1
] =
newVector( v3
[2
] ) ;
base3
[2
] = GetRotYVector
( v3
[1
], -2*PI/3
) ;
double hexrad = x * IPlt ;
int v6
[ ] = Get3VectorsNGon
( 6
, hexrad
) ;
double h = GetHeightAntiprismByConnectionName
( 3
, x
, "octahedron"
) ;
int base6
[ 6
], roof6
[ 6
], dely =
newVector( o
, h
, o
) ;
for ( int i=0; i<R3; i++
) {
roof3
[i
] = GetRotYVector
( base3
[i
], PI/3
) ;
moveVector( roof3
[i
], o
, h
, o
) ;
}
for ( int i=0; i<R6; i++
) {
base6
[i
] = GetRotYVector
( v6
[1
], PI/6 + PI/3 * i
) ;
roof6
[i
] =
newVector( base6
[i
] ) ;
moveVector( roof6
[i
], o
, h
, o
) ;
}
int lateral6
[ R6
][ R3+R3
], lateral3
[ R3
][ R3+R3
], g
[ R6
] ;
for ( int i=0; i<R3; i++
) {
lateral3
[0
][i
] = GetRotYVector
( base3
[0
], 2*PI/3 * i
) ;
lateral3
[1
][i
] = GetRotYVector
( base3
[1
], 2*PI/3 * i
) ;
lateral3
[2
][i
] = GetRotYVector
( roof3
[0
], 2*PI/3 * i
) ;
lateral3
[0
][R3+i
] = GetRotYVector
( roof3
[1
], 2*PI/3 * i
) ;
lateral3
[1
][R3+i
] = GetRotYVector
( roof3
[0
], 2*PI/3 * i
) ;
lateral3
[2
][R3+i
] = GetRotYVector
( base3
[1
], 2*PI/3 * i
) ;
g
[i
] = GetVectorGravityCenter
( RV2_0
( lateral3
, i
) ) ;
g
[R3+i
] = GetVectorGravityCenter
( RV2_0
( lateral3
, R3+i
) ) ;
}
for ( int i=0; i<R3+R3; i++
) {
for ( int j=0; j<R3; j++
) {
int k = j + 1 ;
if ( k >= R3
) { k = k - R3 ;
}
lateral6
[2*j
][i
] = GetInternallyDividingVector
(
lateral3
[j
][i
], lateral3
[k
][i
], a/3
) ;
lateral6
[2*j+1
][i
] = GetInternallyDividingVector
(
lateral3
[j
][i
], lateral3
[k
][i
], 2*a/3
) ;
}
}
for ( int i=0; i<R6; i++
) {
int j;
if ( i < R3
) {
j = 2*i - 1 ;
if ( j < 0
) { j = j + R6 ;
}
setPolygonVector(
t01
[ng
][i
][0
], base3
[i
], base6
[j
], base6
[2*i
]
) ;
setPolygonVector(
t01
[ng
][i
][1
], roof3
[i
], roof6
[2*i+1
], roof6
[2*i
]
) ;
}
j = i + 1 ;
if ( j >= R6
) { j = j - R6 ;
}
setPolygonVector( t00
[ng
][i
][0
], O
, base6
[j
], base6
[i
] ) ;
setPolygonVector( t00
[ng
][i
][1
], dely
, roof6
[i
], roof6
[j
] ) ;
for ( int m=0; m<R6; m++
) {
int m1 = m + 1 ;
if ( m1 >= R6
) { m1 = m1 - R6 ;
}
setPolygonVector( t10
[ng
][m
][i
],
g
[i
], lateral6
[m
][i
], lateral6
[m1
][i
]
) ;
}
for ( int m=0; m<R3; m++
) {
int m1 = 2*m ;
int m2 = m1 - 1 ;
if ( m2 < 0
) { m2 = m2 + R6 ;
}
if ( i < R3
) {
setPolygonVector( t11
[ng
][m
][i
],
lateral3
[m
][i
], lateral6
[m1
][i
], lateral6
[m2
][i
]
) ;
} else {
setPolygonVector( t11
[ng
][m
][i
],
lateral3
[m
][i
], lateral6
[m1
][i
], lateral6
[m2
][i
]
) ;
}
}
}
}
int OPACITY
[ ] =
{ 255
, 175
} ;
float OPTION0
[ 6
], OPTION1
[ 6
];
{
float emissive = o ;
float diffractive = 0.5 ;
float diffuse = 0.6 ;
float ambient = 0.2 ;
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
() {
double offset = -0.12*l ;
for ( int i=0; i<NG; i++
) {
SetPolygonSurface
( TR00
, i
, OPTION0
) ;
SetPolygonSurface
( TR01
, i
, OPTION0
) ;
SetPolygonSurface
( TR10
, i
, OPTION0
) ;
SetPolygonSurface
( TR11
, i
, OPTION0
) ;
for ( int j=0; j<R6; j++
) {
for ( int k=0; k<R6; k++
) {
if ( k < R3
) {
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
}
if ( k == 0
) { // base center
SetPolygonColor
(
TR00
[i
][j
][k
], Color
( a
, o
, a
) , OPACITY
[0
]
) ;
}
if ( k == 1
) { // roof center
SetPolygonColor
(
TR00
[i
][j
][k
], Color
( o
, o
, a
) , OPACITY
[0
]
) ;
}
if ( k < R3
) { // lateral center base-side
SetPolygonColor
(
TR10
[i
][j
][k
], Color
( a
, o
, a
) , OPACITY
[0
]
) ;
}
if ( k >= R3
) { // lateral center roof-side
SetPolygonColor
(
TR10
[i
][j
][k
], Color
( o
, o
, a
) , OPACITY
[0
]
) ;
}
if ( j < R3
) { // base vertex
if ( k == 0
) {
SetPolygonColor
(
TR01
[i
][j
][k
], Color
( a
, o
, o
) , OPACITY
[0
]
) ;
}
if ( k == 1
) { // roof vertex
SetPolygonColor
(
TR01
[i
][j
][k
], Color
( o
, a/2
, a
) , OPACITY
[0
]
) ;
}
if ( k < R3
) { // lateral vertex base-side
SetPolygonColor
(
TR11
[i
][j
][k
], Color
( a
, o
, o
) , OPACITY
[0
]
) ;
}
if ( k >= R3
) { // lateral vertex roof-side
SetPolygonColor
(
TR11
[i
][j
][k
], Color
( o
, a/2
, a
) , OPACITY
[0
]
) ;
}
}
}
}
}
}
void AddElements
() {
int n =
length( COORD
);
addLight( LIGHT1
, RENDERER
, COORD
[n-1
] ) ;
addLight( LIGHT2
, RENDERER
, COORD
[n-1
] ) ;
for ( int i=0; i<NG; i++
) {
AddPolygons
( TR00
, i
, RENDERER
, CD
) ;
AddPolygons
( TR01
, i
, RENDERER
, CD
) ;
AddPolygons
( TR10
, i
, RENDERER
, CD
) ;
AddPolygons
( TR11
, i
, RENDERER
, CD
) ;
}
}
/* set coordinates */
int COORD
[ 4
];
int CD
[ NG
];
for ( int i=0; i<
length( COORD
); i++
) {
COORD
[i
] =
newCoordinate() ;
}
for ( int i=0; i<NG; i++
) {
CD
[i
] =
newCoordinate() ;
}
void SetCoordinates
() {
PileCoordinate
( COORD
, RENDERER
);
for ( int i=0; i<NG; i++
) {
addCoordinate( CD
[i
], RENDERER
, COORD
[0
] );
}
}
/* set axes */
int AXIS
[ 10
];
{
int n =
length( AXIS
) ;
float x
, y
, z ;
for ( int i=0; i<n; i++
) {
x =
( 5*l - 0.5*l*i
) * l ; y = x ; z = x ;
AXIS
[i
] =
newAxisModel( x
, y
, z
) ;
}
}
void SetAxes
() {
addModel( AXIS
[0
], RENDERER
, CD
[0
] ) ;
addModel( AXIS
[2
], RENDERER
, CD
[1
] ) ;
addModel( AXIS
[4
], RENDERER
, CD
[2
] ) ;
addModel( AXIS
[6
], RENDERER
, CD
[3
] ) ;
addModel( AXIS
[8
], RENDERER
, CD
[4
] ) ;
}
/* prepare stage */
double CAMERA_ORIGIN_Z = 12 * 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 ;
bool KEEP_MOTION = true ;
bool DECREASE_TIME = 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 ;
int LABEL_SELECT
[ 1
] ;
N =
length( LABEL_SELECT
) ;
int SELECT
[ N
] ;
string SELECT_TITLE
[ N
] ;
string SELECT_TEXT
[ N
][ 4
] ;
bool MOTION_START = false ;
bool MOTION_END = true ;
int SELECTED_INDEX = 0 ;
int FORMER_SELECTED_INDEX = 0 ;
SELECT_TITLE
[0
] = "色パターン選択" ;
SELECT_TEXT
[0
][0
] = "4色幾何学模様" ;
SELECT_TEXT
[0
][1
] = "隣合う三角反柱が別の色になるように2色で塗り分ける" ;
SELECT_TEXT
[0
][2
] = "三角反柱ごとに異なる色を塗る" ;
SELECT_TEXT
[0
][3
] = "三角反柱の側面と底面を塗り分ける" ;
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 = 320 ;
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
) {
ReverseCuboctahedron
( value
, ISlv*Plt/2*l
) ;
}
void onCheckBoxClick( int id
, bool state
){
if ( MOTION_END
) {
if ( id == CHECK_BOX
[0
] ) {
SPIN = state ;
}
}
}
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_SELECTED_INDEX
) {
SELECTED_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 = 2/180.0 * PI ;
} else {
toprotrate = o ;
}
if ( !GUI_CREATED || !MOTION_END
) {
DesignMotion
( t
, toprotrate
) ; // アニメーション
STOP_TIME =
getVectorY( t
) ; // motion終了時刻
GUI_UPTIME = STOP_TIME + 0.5 ;
CREATE_GUI =
( T >= GUI_UPTIME
) &&
( T < GUI_UPTIME + STEP
) ;
}
if ( T < GUI_UPTIME + 1000.0
) {
rotYCoordinate( COORD
[2
], toprotrate
) ;
} else {
show() ;
println( linefeed
()
+ linefeed
()
+ "*************************************************************************"
+ linefeed
()
+ "**************** アニメーションの既定時間を超過しました *****************"
+ linefeed
()
+ "*************************************************************************"
+ linefeed
()
+ "*********** 安全のため、このプログラムは自動的に閉じられます ************"
+ linefeed
()
+ "*************************************************************************"
) ;
sleep ( 10000
) ;
KEEP_LOOP = false ;
}
}
int SO
[ 4
], SO0
[ NG
], SO1
[NG
], SO2
[NG
], SO3
[NG
] ; //
system origin point
int SA0
[ NG
], SA1
[NG
], SA2
[NG
], SA3
[NG
] ; //
system Euler Angle
for ( int i=0; i<NG; i++
) {
if ( i < 4
) {
SO
[i
] =
newVector() ;
}
SO0
[i
] =
newVector() ;
SO1
[i
] =
newVector() ;
SO2
[i
] =
newVector() ;
SO3
[i
] =
newVector() ;
SA0
[i
] =
newVector() ;
SA1
[i
] =
newVector() ;
SA2
[i
] =
newVector() ;
SA3
[i
] =
newVector() ;
}
void DesignMotion
( int v
, double yrotation
) {
double start_t = STEP ;
double unit = 1.0/3 ; // 時間の単位
double x = ISlv*Plt/2*l ; // cuboctahedron の正方形面心と cuboctahedron 重心の距離
SetTRangeAbsolutely
( v
, start_t
, start_t + STEP
) ;
if ( Motion
( v
) ) {
setGraphics3DColor( RENDERER
, 0
, 0
, 0
, 255
);
SA0 = GetEulerAngleVectors8FacesSymmetry
() ;
SO0 = GetVectors8FacesSymmetry
( ISlv*IPlt*l
) ;
setVector( SO
[0
], O
) ;
for ( int i=0; i<8; i++
) {
SetCoordinateLocationAttitude
( CD
[i
], SO0
[i
], SA0
[i
] ) ;
SetPolygons3SideAntiprismOctahedronConnection
(
l
, TR00
, TR01
, TR10
, TR11
, i
) ;
}
}
SetTRange
( v
, o
, 2 * unit
) ;
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
int c = 255*t ;
setGraphics3DColor( RENDERER
, c
, c
, c
, 255
);
setLightBrightness( LIGHT1
, 0.3*t
) ;
setLightBrightness( LIGHT2
, 0.8*t
) ;
}
SetTRange
( v
, 2 * unit
, 3 * unit
) ;
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
setVector( SO
[1
], o
, -3*x
, o
) ;
}
double t = GetSmoothTime
( v
, o
) ;
Fold_00
( t
, x
) ;
}
SetTRange
( v
, 2 * unit
, 3 * unit
) ;
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
SetVectorsCoordinateLocationAttitude
( SO1
, SA1
, CD
) ;
setVector( SO
[2
], o
, -3*x
, -2*x
) ;
}
double t = GetSmoothTime
( v
, o
) ;
Fold_01
( t
, x
) ;
}
SetTRange
( v
, 2 * unit
, 3 * unit
) ;
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
SetVectorsCoordinateLocationAttitude
( SO2
, SA2
, CD
) ;
setVector( SO
[3
], o
, -4*x
, -2*x
) ;
}
double t = GetSmoothTime
( v
, o
) ;
Fold_02
( t
, x
) ;
}
SetTRange
( v
, 2 * unit
, 3 * unit
) ;
if ( Motion
( v
) ) {
if ( Moment
( v
) ) {
SetVectorsCoordinateLocationAttitude
( SO3
, SA3
, CD
) ;
}
double t = GetSmoothTime
( v
, o
) ;
Fold_03
( t
, x
) ;
}
int stop =
newVector( v
) ;
if ( MOTION_START
) {
T0 = T ;
MOTION_START = false ;
}
SetTRangeAbsolutely
( v
, T0
, T0 + 5 * unit
) ;
if ( FORMER_SELECTED_INDEX != SELECTED_INDEX
) {
if ( Motion
( v
) ) {
double t = GetLinearTime
( v
) ;
int color00bs
[ 3
], color01bs
[ 3
], color10bs
[ 3
], color11bs
[ 3
] ;
int color00rf
[ 3
], color01rf
[ 3
], color10rf
[ 3
], color11rf
[ 3
] ;
int color1
[ 3
], color2
[ 3
] ;
for ( int i=0; i<NG; i++
) {
if ( FORMER_SELECTED_INDEX == 0
) {
if ( SELECTED_INDEX == 1
) {
if ( ( i == 0
) ||
( i == 2
) ||
( i == 5
) ||
( i == 7
) ) {
color2 = Color
( a
, a
, o
) ;
} else {
color2 = Color
( o
, a
, o
) ;
}
} else if ( SELECTED_INDEX == 2
) {
if ( i == 0
) {
color2 = Color
( a
, o
, o
) ;
} else if ( i == 1
) {
color2 = Color
( a
, 3*a/4
, o
) ;
} else if ( i == 2
) {
color2 = Color
( 3*a/4
, a
, o
) ;
} else if ( i == 3
) {
color2 = Color
( o
, a
, a/2
) ;
} else if ( i == 4
) {
color2 = Color
( o
, a
, a
) ;
} else if ( i == 5
) {
color2 = Color
( o
, a/4
, a
) ;
} else if ( i == 6
) {
color2 = Color
( a/2
, o
, a
) ;
} else if ( i == 7
) {
color2 = Color
( a
, o
, 3*a/4
) ;
}
}
if ( SELECTED_INDEX != 3
) {
color00bs = MixedColor
( Color
( a
, o
, a
), color2
, t
) ;
color00rf = MixedColor
( Color
( o
, o
, a
), color2
, t
) ;
color10bs = MixedColor
( Color
( a
, o
, a
), color2
, t
) ;
color10rf = MixedColor
( Color
( o
, o
, a
), color2
, t
) ;
color01bs = MixedColor
( Color
( a
, o
, o
), color2
, t
) ;
color01rf = MixedColor
( Color
( o
, a/2
, a
), color2
, t
) ;
color11bs = MixedColor
( Color
( a
, o
, o
), color2
, t
) ;
color11rf = MixedColor
( Color
( o
, a/2
, a
), color2
, t
) ;
} else {
color2 = Color
( a
, o
, o
) ;
color00bs = MixedColor
( Color
( a
, o
, a
), color2
, t
) ;
color01bs = MixedColor
( Color
( a
, o
, o
), color2
, t
) ;
color2 = Color
( o
, o
, a
) ;
color00rf = MixedColor
( Color
( o
, o
, a
), color2
, t
) ;
color01rf = MixedColor
( Color
( o
, a/2
, a
), color2
, t
) ;
color2 = Color
( a
, o
, a
) ;
color10bs = MixedColor
( Color
( a
, o
, a
), color2
, t
) ;
color10rf = MixedColor
( Color
( o
, o
, a
), color2
, t
) ;
color11bs = MixedColor
( Color
( a
, o
, o
), color2
, t
) ;
color11rf = MixedColor
( Color
( o
, a/2
, a
), color2
, t
) ;
}
} else if ( FORMER_SELECTED_INDEX == 1
) {
if ( ( i == 0
) ||
( i == 2
) ||
( i == 5
) ||
( i == 7
) ) {
color1 = Color
( a
, a
, o
) ;
} else {
color1 = Color
( o
, a
, o
) ;
}
if ( SELECTED_INDEX == 0
) {
color00bs = MixedColor
( color1
, Color
( a
, o
, a
), t
) ;
color00rf = MixedColor
( color1
, Color
( o
, o
, a
), t
) ;
color10bs = MixedColor
( color1
, Color
( a
, o
, a
), t
) ;
color10rf = MixedColor
( color1
, Color
( o
, o
, a
), t
) ;
color01bs = MixedColor
( color1
, Color
( a
, o
, o
), t
) ;
color01rf = MixedColor
( color1
, Color
( o
, a/2
, a
), t
) ;
color11bs = MixedColor
( color1
, Color
( a
, o
, o
), t
) ;
color11rf = MixedColor
( color1
, Color
( o
, a/2
, a
), t
) ;
} else if ( SELECTED_INDEX == 2
) {
if ( i == 0
) {
color2 = Color
( a
, o
, o
) ;
} else if ( i == 1
) {
color2 = Color
( a
, 3*a/4
, o
) ;
} else if ( i == 2
) {
color2 = Color
( 3*a/4
, a
, o
) ;
} else if ( i == 3
) {
color2 = Color
( o
, a
, a/2
) ;
} else if ( i == 4
) {
color2 = Color
( o
, a
, a
) ;
} else if ( i == 5
) {
color2 = Color
( o
, a/4
, a
) ;
} else if ( i == 6
) {
color2 = Color
( a/2
, o
, a
) ;
} else if ( i == 7
) {
color2 = Color
( a
, o
, 3*a/4
) ;
}
color00bs = MixedColor
( color1
, color2
, t
) ;
color00rf = MixedColor
( color1
, color2
, t
) ;
color10bs = MixedColor
( color1
, color2
, t
) ;
color10rf = MixedColor
( color1
, color2
, t
) ;
color01bs = MixedColor
( color1
, color2
, t
) ;
color01rf = MixedColor
( color1
, color2
, t
) ;
color11bs = MixedColor
( color1
, color2
, t
) ;
color11rf = MixedColor
( color1
, color2
, t
) ;
} else {
color2 = Color
( a
, o
, o
) ;
color00bs = MixedColor
( color1
, color2
, t
) ;
color01bs = MixedColor
( color1
, color2
, t
) ;
color2 = Color
( o
, o
, a
) ;
color00rf = MixedColor
( color1
, color2
, t
) ;
color01rf = MixedColor
( color1
, color2
, t
) ;
color2 = Color
( a
, o
, a
) ;
color10bs = MixedColor
( color1
, color2
, t
) ;
color10rf = MixedColor
( color1
, color2
, t
) ;
color11bs = MixedColor
( color1
, color2
, t
) ;
color11rf = MixedColor
( color1
, color2
, t
) ;
}
} else if ( FORMER_SELECTED_INDEX == 2
) {
if ( i == 0
) {
color1 = Color
( a
, o
, o
) ;
} else if ( i == 1
) {
color1 = Color
( a
, 3*a/4
, o
) ;
} else if ( i == 2
) {
color1 = Color
( 3*a/4
, a
, o
) ;
} else if ( i == 3
) {
color1 = Color
( o
, a
, a/2
) ;
} else if ( i == 4
) {
color1 = Color
( o
, a
, a
) ;
} else if ( i == 5
) {
color1 = Color
( o
, a/4
, a
) ;
} else if ( i == 6
) {
color1 = Color
( a/2
, o
, a
) ;
} else if ( i == 7
) {
color1 = Color
( a
, o
, 3*a/4
) ;
}
if ( SELECTED_INDEX == 0
) {
color00bs = MixedColor
( color1
, Color
( a
, o
, a
), t
) ;
color00rf = MixedColor
( color1
, Color
( o
, o
, a
), t
) ;
color10bs = MixedColor
( color1
, Color
( a
, o
, a
), t
) ;
color10rf = MixedColor
( color1
, Color
( o
, o
, a
), t
) ;
color01bs = MixedColor
( color1
, Color
( a
, o
, o
), t
) ;
color01rf = MixedColor
( color1
, Color
( o
, a/2
, a
), t
) ;
color11bs = MixedColor
( color1
, Color
( a
, o
, o
), t
) ;
color11rf = MixedColor
( color1
, Color
( o
, a/2
, a
), t
) ;
} else if ( SELECTED_INDEX == 1
) {
if ( ( i == 0
) ||
( i == 2
) ||
( i == 5
) ||
( i == 7
) ) {
color2 = Color
( a
, a
, o
) ;
} else {
color2 = Color
( o
, a
, o
) ;
}
color00bs = MixedColor
( color1
, color2
, t
) ;
color00rf = MixedColor
( color1
, color2
, t
) ;
color10bs = MixedColor
( color1
, color2
, t
) ;
color10rf = MixedColor
( color1
, color2
, t
) ;
color01bs = MixedColor
( color1
, color2
, t
) ;
color01rf = MixedColor
( color1
, color2
, t
) ;
color11bs = MixedColor
( color1
, color2
, t
) ;
color11rf = MixedColor
( color1
, color2
, t
) ;
} else {
color2 = Color
( a
, o
, o
) ;
color00bs = MixedColor
( color1
, color2
, t
) ;
color01bs = MixedColor
( color1
, color2
, t
) ;
color2 = Color
( o
, o
, a
) ;
color00rf = MixedColor
( color1
, color2
, t
) ;
color01rf = MixedColor
( color1
, color2
, t
) ;
color2 = Color
( a
, o
, a
) ;
color10bs = MixedColor
( color1
, color2
, t
) ;
color10rf = MixedColor
( color1
, color2
, t
) ;
color11bs = MixedColor
( color1
, color2
, t
) ;
color11rf = MixedColor
( color1
, color2
, t
) ;
}
} else {
if ( SELECTED_INDEX == 0
) {
color1 = Color
( a
, o
, o
) ;
color00bs = MixedColor
( color1
, Color
( a
, o
, a
), t
) ;
color01bs = MixedColor
( color1
, Color
( a
, o
, o
), t
) ;
color1 = Color
( o
, o
, a
) ;
color00rf = MixedColor
( color1
, Color
( o
, o
, a
), t
) ;
color01rf = MixedColor
( color1
, Color
( o
, a/2
, a
), t
) ;
color1 = Color
( a
, o
, a
) ;
color10bs = MixedColor
( color1
, Color
( a
, o
, a
), t
) ;
color10rf = MixedColor
( color1
, Color
( o
, o
, a
), t
) ;
color11bs = MixedColor
( color1
, Color
( a
, o
, o
), t
) ;
color11rf = MixedColor
( color1
, Color
( o
, a/2
, a
), t
) ;
} else if ( SELECTED_INDEX == 1
) {
if ( ( i == 0
) ||
( i == 2
) ||
( i == 5
) ||
( i == 7
) ) {
color2 = Color
( a
, a
, o
) ;
} else {
color2 = Color
( o
, a
, o
) ;
}
} else if ( SELECTED_INDEX == 2
) {
if ( i == 0
) {
color2 = Color
( a
, o
, o
) ;
} else if ( i == 1
) {
color2 = Color
( a
, 3*a/4
, o
) ;
} else if ( i == 2
) {
color2 = Color
( 3*a/4
, a
, o
) ;
} else if ( i == 3
) {
color2 = Color
( o
, a
, a/2
) ;
} else if ( i == 4
) {
color2 = Color
( o
, a
, a
) ;
} else if ( i == 5
) {
color2 = Color
( o
, a/4
, a
) ;
} else if ( i == 6
) {
color2 = Color
( a/2
, o
, a
) ;
} else if ( i == 7
) {
color2 = Color
( a
, o
, 3*a/4
) ;
}
}
if ( SELECTED_INDEX != 0
) {
color1 = Color
( a
, o
, o
) ;
color00bs = MixedColor
( color1
, color2
, t
) ;
color01bs = MixedColor
( color1
, color2
, t
) ;
color1 = Color
( o
, o
, a
) ;
color00rf = MixedColor
( color1
, color2
, t
) ;
color01rf = MixedColor
( color1
, color2
, t
) ;
color1 = Color
( a
, o
, a
) ;
color10bs = MixedColor
( color1
, color2
, t
) ;
color10rf = MixedColor
( color1
, color2
, t
) ;
color11bs = MixedColor
( color1
, color2
, t
) ;
color11rf = MixedColor
( color1
, color2
, t
) ;
}
}
for ( int j=0; j<R6; j++
) {
for ( int k=0; k<R6; k++
) {
if ( k == 0
) { // base center
SetPolygonColor
(
TR00
[i
][j
][k
], color00bs
, OPACITY
[0
]
) ;
}
if ( k == 1
) { // roof center
SetPolygonColor
(
TR00
[i
][j
][k
], color00rf
, OPACITY
[0
]
) ;
}
if ( k < R3
) { // lateral center base-side
SetPolygonColor
(
TR10
[i
][j
][k
], color10bs
, OPACITY
[0
]
) ;
}
if ( k >= R3
) { // lateral center roof-side
SetPolygonColor
(
TR10
[i
][j
][k
], color10rf
, OPACITY
[0
]
) ;
}
if ( j < R3
) { // base vertex
if ( k == 0
) {
SetPolygonColor
(
TR01
[i
][j
][k
], color01bs
, OPACITY
[0
]
) ;
}
if ( k == 1
) { // roof vertex
SetPolygonColor
(
TR01
[i
][j
][k
], color01rf
, OPACITY
[0
]
) ;
}
if ( k < R3
) { // lateral vertex base-side
SetPolygonColor
(
TR11
[i
][j
][k
], color11bs
, OPACITY
[0
]
) ;
}
if ( k >= R3
) { // lateral vertex roof-side
SetPolygonColor
(
TR11
[i
][j
][k
], color11rf
, OPACITY
[0
]
) ;
}
}
}
}
}
if ( t == a
) {
FORMER_SELECTED_INDEX = SELECTED_INDEX ;
MOTION_END = true ;
}
}
}
setVector( v
, stop
) ;
}
// cuboctaheron を終始の状態として裏返す操作
void ReverseCuboctahedron
( double p
, double x
) {
double s
[ 4
] ;
double dels = a /
length( s
) ;
double s0 = dels / 8 ;
for ( int i=0; i<
length( s
); i++
) {
s
[i
] = VelvetySlope
( p
, dels * i + s0
, dels - s0
) ;
}
if ( p < dels
) {
Fold_03
( 1-s
[0
], x
) ;
} else if ( p < 2 * dels
) {
Fold_02
( 1-s
[1
], x
) ;
} else if ( p < 3 * dels
) {
Fold_01
( 1-s
[2
], x
) ;
} else {
Fold_00
( 1-s
[3
], x
) ;
}
}
void Fold_00
( double p
, double x
) { //
( x
, o
, o
)
int origin = GetInternallyDividingVector
( SO
[0
], SO
[1
], p
) ;
setCoordinateOrigin( COORD
[0
], origin
) ;
int ax =
newVector( o
, o
, a
), rc =
newVector( o
, 2*x
, o
) ;
double offset ;
for ( int i=0; i<NG; i++
) {
for( int j=0; j<R6; j++
) {
for ( int k=0; k<R6; k++
) {
if (
( ( ( i == 0
) ||
( i == 2
) ||
( i == 5
) ||
( i == 7
) )
&&
( k == 0
) )
||
( ( ( i == 1
) ||
( i == 3
) ||
( i == 4
) ||
( i == 6
) )
&&
( k == 2
) )
) {
offset = -0.12*l *
( 1 - Slope
( p
, o
, a/2
) ) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
if (
( ( i == 0
) ||
( i == 1
) ||
( i == 2
) ||
( i == 3
) )
&&
( k == 5
)
) {
offset = -0.12*l * Slope
( p
, a/2
, a/2
) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
}
}
}
double angle ;
for ( int i=0; i<NG; i++
) {
if ( ( i == 0
) ||
( i == 1
) ||
( i == 4
) ||
( i == 5
) ) {
angle = PI/2 * p ;
} else {
angle = -PI/2 * p ;
}
RotateCoordinate
(
CD
[i
], SO0
[i
], SA0
[i
], angle
, ax
, rc
, RENDERER
, COORD
[0
]
) ;
}
}
void Fold_01
( double p
, double x
) {
int origin = GetInternallyDividingVector
( SO
[1
], SO
[2
], p
) ;
setCoordinateOrigin( COORD
[0
], origin
) ;
int ax =
newVector( o
, a
, o
), rc =
newVector() ;
double offset ;
for ( int i=0; i<NG; i++
) {
for( int j=0; j<R6; j++
) {
for ( int k=0; k<R6; k++
) {
if (
( ( i == 0
) &&
( ( k == 1
) ||
( k == 2
) ) )
||
( ( i == 1
) &&
( ( k == 0
) ||
( k == 5
) ) )
||
( ( i == 2
) &&
( ( k == 2
) ||
( k == 5
) ) )
||
( ( i == 3
) &&
( ( k == 0
) ||
( k == 1
) ) )
||
( ( i == 4
) &&
( k == 1
) )
||
( ( i == 7
) &&
( k == 1
) )
) {
offset = -0.12*l *
( 1 - Slope
( p
, o
, a/2
) ) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
if (
( ( i == 0
) &&
( k == 3
) )
||
( ( i == 3
) &&
( k == 4
) )
||
( ( i == 4
) &&
( ( k == 4
) ||
( k == 5
) ) )
||
( ( i == 5
) &&
( k == 5
) )
||
( ( i == 6
) &&
( k == 5
) )
||
( ( i == 7
) &&
( ( k == 3
) ||
( k == 5
) ) )
) {
offset = -0.12*l * Slope
( p
, a/2
, a/2
) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
}
}
}
double angle ;
for ( int i=0; i<NG; i++
) {
if ( ( i == 0
) ||
( i == 3
) ) {
} else {
if ( ( i == 1
) ||
( i == 4
) ||
( i == 5
) ) {
angle = -PI * p ;
setVector( rc
, 2*x
, o
, 2*x
) ;
} else {
angle = PI * p ;
setVector( rc
, -2*x
, o
, 2*x
) ;
}
RotateCoordinate
(
CD
[i
], SO1
[i
], SA1
[i
], angle
, ax
, rc
, RENDERER
, COORD
[0
]
) ;
}
}
}
void Fold_02
( double p
, double x
) {
int origin = GetInternallyDividingVector
( SO
[2
], SO
[3
], p
) ;
setCoordinateOrigin( COORD
[0
], origin
) ;
int ax =
newVector( a
, o
, o
), rc =
newVector( o
, 4*x
, 4*x
) ;
double offset ;
for ( int i=0; i<NG; i++
) {
for( int j=0; j<R6; j++
) {
for ( int k=0; k<R6; k++
) {
if (
( ( ( i == 4
) ||
( i == 6
) ) &&
( k == 0
) )
||
( ( ( i == 5
) ||
( i == 7
) ) &&
( k == 2
) )
) {
offset = -0.12*l *
( 1 - Slope
( p
, o
, a/2
) ) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
if (
( ( ( i == 4
) ||
( i == 6
) ) &&
( k == 3
) )
||
( ( ( i == 5
) ||
( i == 7
) ) &&
( k == 4
) )
) {
offset = -0.12*l * Slope
( p
, a/2
, a/2
) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
}
}
}
double angle ;
for ( int i=0; i<NG; i++
) {
if ( ( i == 0
) ||
( i == 3
) ||
( i == 4
) ||
( i == 7
) ) {
} else {
angle = -PI * p ;
RotateCoordinate
(
CD
[i
], SO2
[i
], SA2
[i
], angle
, ax
, rc
, RENDERER
, COORD
[0
]
) ;
}
}
}
void Fold_03
( double p
, double x
) {
int ax =
newVector( o
, a
, o
), rc =
newVector() ;
double offset ;
for ( int i=0; i<NG; i++
) {
for( int j=0; j<R6; j++
) {
for ( int k=0; k<R6; k++
) {
if (
( ( i == 1
) ||
( i == 2
) ||
( i == 5
) ||
( i == 6
) )
&&
( k == 1
)
) {
offset = -0.12*l *
( 1 - Slope
( p
, o
, a/2
) ) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
if (
( ( ( i == 0
) ||
( i == 6
) ) &&
( k == 4
) )
||
( ( ( i == 1
) ||
( i == 2
) )
&&
( ( k == 3
) ||
( k == 4
) ||
( k == 5
) ) )
||
( ( ( i == 3
) ||
( i == 5
) ) &&
( k == 3
) )
) {
offset = -0.12*l * Slope
( p
, a/2
, a/2
) ;
if ( j < R3
) {
setPolygonSortOffset( TR11
[i
][j
][k
], offset
) ;
}
setPolygonSortOffset( TR10
[i
][j
][k
], offset
) ;
}
}
}
}
double angle ;
for ( int i=0; i<NG; i++
) {
if ( ( i != 1
) &&
( i != 2
) ) {
} else {
if ( i == 1
) {
angle = PI * p ;
setVector( rc
, 2*x
, o
, 2*x
) ;
} else {
angle = -PI * p ;
setVector( rc
, -2*x
, o
, 2*x
) ;
}
RotateCoordinate
(
CD
[i
], SO3
[i
], SA3
[i
], angle
, ax
, rc
, RENDERER
, COORD
[0
]
) ;
}
}
}