「 プログラムをコピー 」に続いて「 プレイヤーを起動 」をクリックし、プレイヤー画面に貼り付けると、WEBブラウザ上でそのままプログラムを実行できます。

>> プレイヤーを起動できない場合はこちら

encode Shift_JIS ;


import Graphics ; 
import Graphics3D ; 
import GUI ; 
import Math ; 


void main( string args[] ){


    TITLE = "ペンタグラムと小星型十二面体" ;
    int winw = 256*2.75, winh = 256*2.75, winx = 70 ;
    int bgcolor[ ] = Color( a ) ;

    hide();
    Set3DGraphics( winw, winh, winx, bgcolor ) ;
    SetLights();
    SetCoordinates();
    SetElements();
    PrepareStage();


/* animation loop  */

    int picture_save_number = 1 * 10000 ;
    int loop_periodic_time = 1000 / FPS ;
    bool loop_termination = false ;

    while ( KEEP_LOOP ){ 

        T += STEP ;
        COUNT ++ ;
        if ( COUNT % 100 == 0 ) {
            print( (COUNT/100) + ", " );
        }

        ForwardMotion(); // アニメーション

        if ( CREATE_GUI ) {
            CreateGuiElements();
            CREATE_GUI = false ;
            TURN_GUI = true ;
        }

        PaintGraphics( loop_periodic_time );

        if ( SAVE_A_PICTURE ) {
            SaveImagePNG( picture_save_number );
        }

        loop_termination = ( PICTURE_NUMBER == PICTURE_END_NUMBER ) ;
        if ( loop_termination ) {
            ExitLoopOverImageLimit();
        }
    }


    exit();


}




/* import */


/* NUMERIC */

double o = 0.0, a = 1.0 ;
double d = 0.1 ;
double Slv = 2*cos( PI/4 ) , ISlv = cos( PI/4 ) ;
double Gld = 2*cos( PI/5 ) , IGld = Gld - 1.0 ;
double Plt = 2*cos( PI/6 ) , IPlt = tan( PI/6 ) ;
int O = newVector( o, o, o ) ; 

double l = 1.0 ; // 長さに用いる単位
int N ;

// symmetry
int S24 = 24, S12 = 12, S8 = 8, S6 = 6, S5 = 5, S4 = 4, S3 = 3, S2 = 2 ; 
int R3 = 3, R4 = 4, R5 = 5, R8 = 8 ;


/* 3DGRAPHICS */

string TITLE;
int MAIN_GRAPHICS, MAIN_WINDOW, MAIN_DISPLAY_LABEL, RENDERER ;
int WIDTH, HEIGHT, WINDOW_POSITION_X ;
{
    int n = 256 ;
    WIDTH = n * 2.75 ; WIDTH = n * 4 ; 
    HEIGHT = n * 2.75 ; HEIGHT = n * 3 ; 
    WINDOW_POSITION_X = 70 ; WINDOW_POSITION_X = 1910 - WIDTH ;
}

void Set3DGraphics( int w, int h, int x, int bgcolor[ ] ) {

    WIDTH = w ;
    HEIGHT = h ;
    WINDOW_POSITION_X = x ;
    int bgred = bgcolor[0] ;
    int bggreen = bgcolor[1] ;
    int bgblue = bgcolor[2] ;
    int framewidth_x = 14 ;
    int framewidth_y = 39 ;
    int bgalpha = 255 ;

    MAIN_GRAPHICS = newGraphics()
    RENDERER = newGraphics3DRenderer( WIDTH, HEIGHT, MAIN_GRAPHICS ) ;
    MAIN_WINDOW = newWindow( 
        WINDOW_POSITION_X, 0, WIDTH + framewidth_x, HEIGHT + framewidth_y, TITLE 
    ) ;
    MAIN_DISPLAY_LABEL = newGraphicsLabel( 0, 0, WIDTH, HEIGHT, MAIN_GRAPHICS ) ;
    addComponent( MAIN_DISPLAY_LABEL, MAIN_WINDOW );
    setGraphics3DDefaultEventHandler( RENDERER, MAIN_DISPLAY_LABEL );
    setGraphics3DColor( RENDERER, bgred, bggreen, bgblue, bgalpha );
}


/* GUI */

void onWindowClose( int id ) { 
    KEEP_LOOP = false ; 
}

void onKeyDown( int id, string key ){

    if ( key == "SPACE" ) {
        if ( SAVE_A_PICTURE ) {
            SAVE_A_PICTURE = false ;
            alert( PICTURE_NUMBER + " 枚目までで画像の保存を中止しました。" );
        } else {
            alert( ( PICTURE_NUMBER+1 ) + " 枚目以降の画像を保存します。" );
            SAVE_A_PICTURE = true ;
        }
    }
}

void PaintGraphics( int sleeptime ) {
    sleep( sleeptime );
    paintGraphics3D( RENDERER );
    paintComponent( MAIN_DISPLAY_LABEL );
    paintComponent( MAIN_WINDOW );
}

void SavePicture( int picid ) {
    int picnumber = 0 ;
    PICTURE_NUMBER = PICTURE_NUMBER + 1 ; 
    picnumber = picid + PICTURE_NUMBER ; 
    exportGraphics(
        MAIN_GRAPHICS, "./movie/0" + picnumber + ".png", "PNG" 
    ) ;
}

void SaveImagePNG( int picid ) {
    int picnumber = 0 ;
    PICTURE_NUMBER = PICTURE_NUMBER + 1 ; 
    picnumber = picid + PICTURE_NUMBER ; 
    exportGraphics(
        MAIN_GRAPHICS, "./movie/a" + picnumber + ".png", "PNG" 
    ) ;
}

void SaveImageJPEG( int picid ) {
    int picnumber = 0 ;
    PICTURE_NUMBER = PICTURE_NUMBER + 1 ; 
    picnumber = picid + PICTURE_NUMBER ; 
    exportGraphics(
        MAIN_GRAPHICS, "./movie/a" + picnumber + ".jpg", "JPEG" 
    ) ;
}

void ExitLoopOverImageLimit() {
    alert( 
        "画像の保存が上限 ( " 
        + PICTURE_END_NUMBER 
        + " 枚 ) に達したため、CGアニメーションを終了します。"
    );
    KEEP_LOOP = false ;
}


/* FUNCTIONS */

// 等式評価
bool Equality( double x1, double x2, double infinitesimal ) {

    double dif = x1 - x2 ;
    return abs( dif ) < infinitesimal ;
}

// permuation
int Permuation( int n[ ] ) {
}

// unit step function
double Step( double x ) {

    double value;
    if ( x < 0.0 ) {
        value = 0.0 ;
    } else {
        value = 1.0 ;
    }
    return value ;
}

double Slope( double x, double x0, double deltax ) {

    double value;
    if ( x < x0 ) {
        value = 0.0 ;
    } else if ( x < ( x0 + deltax ) ) {
        value = ( x - x0 ) / deltax ;
    } else {
        value = 1.0 ;
    }
    return value ;
}

// eyeteeth ( teeth of saw )
double Eyeteeth( double x, double width ) {
// 0 <= x <=1
    double s = x ;
    if ( ( x < 0.0 ) || ( x > 1.0 ) ) {
        alert( "Error ( out of range, eyeteeth ) " );
    } else {
        while ( s > width ) {
        s = s - width ;
        }
    }
    return s / width ;
}

// pulsar
double Pulsar( double x, double cycle, double upslope, double top, double downslope ) {
// 0 <= x <=1
    double value;
    double s = Eyeteeth( x, cycle ) ;
    double ups = upslope / cycle ;
    double tops = top / cycle ;
    double downs = downslope / cycle ;
    if ( s < ups ) {
        value = Bump( s / ups * 0.5 ) ; 

    } else if ( s < ups + tops ) {
        value = 1.0 ;
    } else if ( s < ups + tops + downs ) {
            value = Bump( 0.5 + ( ( s - ( ups + tops ) ) / downs ) * 0.5 ) ;
    } else {
        value = 0.0 ;
    }
    return value ;
}

// unit bump function
double Bump( double x ) {

    return ( sin( 2*PI * x - PI/2 ) + 1.0 ) / 2 ;
}


double TurnBump( double x ) {

    return 1.0 - Bump( x ) ;
}

int Parity( int i ) {

    int p;
    if ( i % 2 == 0 ) {
        p = 1 ;
    } else {
        p = -1 ;
    }
    return p ;
}

double[ ] SolveQuadraticEquation( double a, double b, double c ) {

    double D = b^2 - 4 * a * c ;
    double solution[2];
    solution[0] = ( -b - D^0.5 ) / ( 2*a ) ;
    solution[1] = ( -b + D^0.5 ) / ( 2*a ) ;
    return solution ;
}


/* ROUTINE */

void PrintVectorln( int v, string s ) {
    println( "Vector " + s + " = "
        + getVectorX( v ) + ", "
        + getVectorY( v ) + ", "
        + getVectorZ( v )
    );
}

void PrintDoubleArray( double a[ ], string s ) {

    int n = length( a ) ;
    for ( int i=0; i<n; i++ ) {
        println( "s ( " + i + " ) = " + a[i] );
    }
}

void SetParallelLight(
    int light, float x, float y, float z, float power, int renderer
) {

    light = newLight( x, y, z, power ) ; 
    addLight( light, renderer );
}

void SetAmbientLight(
    int light, float x, float y, float z, float power, int renderer
) {

    light = newAmbientLight( x, y, z, power ) ; 
    addLight( light, renderer );
}

void SetPointLight(
    int light, float x, float y, float z, float power, int renderer
) {

    light = newPointLight( x, y, z, power ) ; 
    addLight( light, renderer );
}

void SetPolygonSurface( int id, float x[ ] ) {

    setPolygonEmissive( id, x[0] );
    setPolygonDiffractive( id, x[1] );
    setPolygonDiffuse( id, x[2] );
    setPolygonAmbient( id, x[3] );
    setPolygonSpecular( id, x[4], x[5] );
}

void SetModelSurface( int id, float x[ ] ) {

    setModelEmissive( id, x[0] );
    setModelDiffractive( id, x[1] );
    setModelDiffuse( id, x[2] );
    setModelAmbient( id, x[3] );
    setModelSpecular( id, x[4], x[5] );
}

void SetPolygonColor( int id, int c[ ], int opc ) {

    setPolygonColor( id, c[0], c[1], c[2], opc );
}

void SetModelColor( int id, int c[ ], int opc ) {

    setModelColor( id, c[0], c[1], c[2], opc );
}

void SetLightColor( int id, int c[ ], int opc ) {

    setLightColor( id, c[0], c[1], c[2], opc );
}

void PileCoordinate( int cd[ ] , int renderer ) {

    int n = length( cd ) ;
    for ( int i=0; i<n; i++ ) {
        if ( i == 0 ) {
            addCoordinate( cd[n-1-i], renderer );
        } else {
            addCoordinate( cd[n-1-i], renderer, cd[n-i] );
        }
    }
}

// vectorの和を返す
int GetVectorSum( int v1, int v2 ) {

    int v = newVector() ;
    double vx = getVectorX( v1 ) + getVectorX( v2 ) ;
    double vy = getVectorY( v1 ) + getVectorY( v2 ) ;
    double vz = getVectorZ( v1 ) + getVectorZ( v2 ) ;
    setVector( v, vx, vy, vz );
    return v ;
}

// moveVectorの結果を返す
int GetMoveVector( int v, double x, double y, double z ) {

    int u = newVector( v );
    moveVector( u, x, y, z );
    return u ;
}

// vectorの差を求めて代入する
void VectorDifference( int v, int v1, int v2 ) {

    double vx = getVectorX( v1 ) - getVectorX( v2 ) ;
    double vy = getVectorY( v1 ) - getVectorY( v2 ) ;
    double vz = getVectorZ( v1 ) - getVectorZ( v2 ) ;
    setVector( v, vx, vy, vz );
}

// vectorの差を返す
int GetVectorDifference( int v1, int v2 ) {

    double vx = getVectorX( v1 ) - getVectorX( v2 ) ;
    double vy = getVectorY( v1 ) - getVectorY( v2 ) ;
    double vz = getVectorZ( v1 ) - getVectorZ( v2 ) ;
    int v = newVector( vx, vy, vz ) ;
    return v ;
}

// vectorの定数倍する
void ScaleVector( int v, double x ) {

    scaleVector( v, x, x, x ) ;
}

// vectorの定数倍を返す
int GetScaleVector( int v, double x ) {

    int u = newVector( v ) ;
    scaleVector( u, x, x, x ) ;
    return u ;
}

// vectorの回転を求めて返す
int GetRotXVector( int v, double angle ) {

    int u = newVector( v ) ;
    rotXVector( u, angle );
    return u ;
}
int GetRotYVector( int v, double angle ) {

    int u = newVector( v ) ;
    rotYVector( u, angle );
    return u ;
}
int GetRotZVector( int v, double angle ) {

    int u = newVector( v ) ;
    rotZVector( u, angle );
    return u ;
}
int GetRotVector( int v, double angle, int ax, int rc ) {

    int u = newVector( v ) ;
    rotVector( u, angle, ax, rc );
    return u ;
}

// 内分点を求める。P1V ; VP2 = t : 1-t
int GetInternallyDividingVector(
    double x1, double y1, double z1,
    double x2, double y2, double z2,
    double t
) {

    double vx = ( 1.0 - t )*x1 + t*x2 ;
    double vy = ( 1.0 - t )*y1 + t*y2 ;
    double vz = ( 1.0 - t )*z1 + t*z2 ;
    int v = newVector ( vx, vy, vz ) ;
    return v ;
}

int GetInternallyDividingVector( int v1, int v2, double t ) {

    double vx = ( 1.0 - t )*getVectorX( v1 ) + t*getVectorX( v2 ) ;
    double vy = ( 1.0 - t )*getVectorY( v1 ) + t*getVectorY( v2 ) ;
    double vz = ( 1.0 - t )*getVectorZ( v1 ) + t*getVectorZ( v2 ) ;
    int v = newVector ( vx, vy, vz ) ;
    return v ;
}

int GetMiddlePointVector( int v1, int v2 ) {

    double x = ( getVectorX( v1 ) + getVectorX( v2 ) ) / 2 ;
    double y = ( getVectorY( v1 ) + getVectorY( v2 ) ) / 2 ;
    double z = ( getVectorZ( v1 ) + getVectorZ( v2 ) ) / 2 ;
    int mid = newVector( x, y, z ) ;
    return mid ;
}

// vをcdに配置してCDへ変換したものを求める
int GetTransformedVector( int v, int renderer, int cd, int CD ) {

    int u = newVector( v ) ;
    addVector( v, renderer, cd );
    transformVector( v, u, CD );
    removeVector( v, renderer, cd );
    return u ;
}

void TransformVector( int v, int renderer, int cd, int u, int CD ) {

    addVector( v, renderer, cd );
    transformVector( v, u, CD );
    removeVector( v, renderer, cd );
}

void SetCoordinateOrigin( int cd, double x[ ] ) {

    setCoordinateOrigin( cd, x[0], x[1], x[2] );
}

int GetVectorCoordinateOrigin( int cd ) {

    int v = newVector(
        getCoordinateOriginX( cd ),
        getCoordinateOriginY( cd ),
        getCoordinateOriginZ( cd )
    );
    return v ;
}

// 重心を返す
int GetVectorGravityCenter( int v[ ] ) {

    int g = newVector( v[0] ) ;
    int lenv = length( v ) ;
    for ( int i=1; i<lenv; i++ ) {
        moveVector( g, v[i] );
    }
    double s = 1.0 / lenv ;
    scaleVector( g, s, s, s);
    return g ;
}

double[ ] getCenterOfGravity( int v[ ] ) {

    int g = newVector( v[0] ) ;
    int lenv = length( v ) ;
    for ( int i=1; i<lenv; i++ ) {
        moveVector( g, v[i] );
    }
    double s = 1.0 / lenv ;
    scaleVector( g, s, s, s);
    double x[ 3 ];
    x[0] = getVectorX( g ) ;
    x[1] = getVectorY( g ) ;
    x[2] = getVectorZ( g ) ;
    return x ;
}

// normal vectorを返す
int GetNormalVectorQuadrangle( int v[ ] ) {

    int v1 = GetVectorDifference( v[2], v[0] ) ;
    int v2 = GetVectorDifference( v[3], v[1] ) ;
    int normalv = newVector() ;
    getVectorCrossProduct( v1, v2, normalv );
    double length = getVectorLength( normalv ) ;
    if ( !( length == o ) ) {
        setVectorLength( normalv, 1.0 );
    } else {
        alert( "error( GetNormalVectorQuadrangle )) ;
    }
    return normalv ;
}

// 2枚の面の作る角の余弦を返す
double GetAngleFaceFace ( int v1[ ], int v2[ ] ) {

    int n1 = GetNormalVectorQuadrangle( v1 ) ;
    int n2 = GetNormalVectorQuadrangle( v2 ) ;
    double costh = getVectorInnerProduct( n1, n2 ) ;
    return costh ;
}

void SetVectorsCoordinateLocationAttitude( int vo, int va, int cd ) {

    double x = getCoordinateOriginX( cd ) ;
    double y = getCoordinateOriginY( cd ) ;
    double z = getCoordinateOriginZ( cd ) ;
    double a = getCoordinateEulerAngleAlpha( cd ) ;
    double b = getCoordinateEulerAngleBeta( cd ) ;
    double g = getCoordinateEulerAngleGamma( cd ) ; 

    setVector( vo, x, y, z );
    setVector( va, a, b, g );
}

void SetCoordinateLocationAttitude( int cd, int vo, int va ) {

    double x = getVectorX( vo ) ;
    double y = getVectorY( vo ) ;
    double z = getVectorZ( vo ) ;
    double a = getVectorX( va ) ;
    double b = getVectorY( va ) ;
    double g = getVectorZ( va ) ; 

    setCoordinateOrigin( cd, x, y, z );
    setCoordinateEulerAngle( cd, a, b, g );
}

/*
void SetCoordinateEulerAngle( int cd, double ea[ ] ) {

    setCoordinateEulerAngle( cd, ea[0], ea[1], ea[2] );
}
*/

void SetCoordinateEulerAngle( int cd, int v ) {

    setCoordinateEulerAngle( cd, 
        getVectorX( v ), getVectorY( v ), getVectorZ( v ) 
    );
}

double[ ] GetArryCoordinateEulerAngle( int cd ) {

    double ea[ 3 ];
    ea[0] = getCoordinateEulerAngleAlpha( cd ) ;
    ea[1] = getCoordinateEulerAngleBeta( cd ) ;
    ea[2] = getCoordinateEulerAngleGamma( cd ) ;
    return ea ;
}

int GetVectorCoordinateEulerAngle( int cd ) {

    double ea[ 3 ];
    ea[0] = getCoordinateEulerAngleAlpha( cd ) ;
    ea[1] = getCoordinateEulerAngleBeta( cd ) ;
    ea[2] = getCoordinateEulerAngleGamma( cd ) ;
    int v = newVector( ea ) ;
    return v ;
}

// リセットなしの回転
void RotateCoordinate( 
    int cd, int so, int sa, double angle, int ax, int rc, int renderer, int Cd 
) {

    int dummycd = newCoordinate() ;
    addCoordinate( dummycd, renderer, Cd ) ;
    SetCoordinateLocationAttitude( dummycd, so, sa ) ;
    rotCoordinate( dummycd, angle, ax, rc ) ;
    int sovalue = newVector() ;
    int savalue = newVector();
    SetVectorsCoordinateLocationAttitude( sovalue, savalue, dummycd ) ;
    SetCoordinateLocationAttitude( cd, sovalue, savalue ) ;
    removeCoordinate( dummycd, renderer, Cd ) ;
}

// O から dist 離れた地点へresetなしに移す, y-direction
void SetCoordinateLocationYdirection( int cd, double dist ) {

    int dummycd = newCoordinate() ;
    int v = newVector() ;
    CopyCoordinateAttitude( dummycd, cd ) ;
    walkCoordinate( dummycd, o, dist, o ) ;
    v = GetVectorCoordinateOrigin( dummycd ) ;
    setCoordinateOrigin( cd, v ) ;
}

// 座標系の姿勢をコピー(座標系原点はコピーせず O とする)
void CopyCoordinateAttitude( int cd, int originalcd ) {

    int sa = GetVectorCoordinateEulerAngle( originalcd ) ;
    SetCoordinateLocationAttitude( cd, O, sa ) ;
}

// y軸及びz軸が引数ベクトルと平行な姿勢にする
void SetCoordinateAttitudeYZ( int cd, int vy, int vz ) {

    int uy = newVector( vy ) ;
    int uz = newVector( vz ) ;
    setVectorLength( uy, 1.0 );
    setVectorLength( uz, 1.0 );
    int ux = newVector() ;
    getVectorCrossProduct( uy, uz, ux );
    setCoordinateBaseX( cd, ux );
    setCoordinateBaseY( cd, uy );
    setCoordinateBaseZ( cd, uz );
}

// 原点が v2, cylinder 端点が v1, v2 となるように cd を set する
void SetCoordinateCylinder( int cyl, double rad, int v1, int v2, int cd ) {

    double x[ 3 ];
    x[0] = getVectorX( v1 ) - getVectorX( v2 ) ; 
    x[1] = getVectorY( v1 ) - getVectorY( v2 ) ;
    x[2] = getVectorZ( v1 ) - getVectorZ( v2 ) ;
    int v21 = newVector( x ) ;
    double length = getVectorLength( v21 ) ; // シリンダーの長さ

    if ( length != 0.0 ) {
        int xyprojection = newVector( x[0], x[1], 0.0 ) ;
        setVectorLength( xyprojection, 1.0 ) ;
        double cos1 = getVectorY( xyprojection ) ; // xy射影がy軸となす角の余弦
        double th1; // xy射影がy軸となす角度
        if ( x[1] == 0.0 ) {
            if ( x[0] >= 0.0 ) {
                th1 = PI/2 ;
            } else {
                th1 = -PI/2 ;
            }
        } else if( x[0] < 0.0 ) { 
            th1 = -acos( cos1 ) ; 
        } else {
            th1 = acos( cos1 ) ;
        }

        setVectorLength( v21, 1.0 );
        double sin2 = getVectorZ( v21 ); // 射影と元のベクトルのなす角の正弦
        double th2 = asin( sin2 ) ;

        double alpha = -th1 ;
        double beta = th2 - PI/2 ;
        double gamma = 0.0 ; if ( th1 < 0.0 ) { gamma = PI ; }
        setCoordinateOrigin( cd, v2 );
        setCoordinateEulerAngle( cd, alpha, beta, gamma );
         setModelSize( cyl, rad, rad, length );
    }
}

void SetSphereSize( int sp, double rad ) {

    setModelSize( sp, rad, rad, rad );
}

// n 番目の多面体のすべての面の頂点を vector で指定する
void SetTriangleVector( int p[ ][ ], int n, int v[ ][ ] ) {

    for ( int i=0; i<length( p ); i++ ) {
        setPolygonVector( p[n][i], v[i][0], v[i][1], v[i][2] ) ;
    }
}
void SetTriangleVector( int p[ ][ ][ ], int n, int v[ ][ ] ) {

    for ( int i=0; i<length( p )[1]; i++ ) {
        for ( int j=0; j<length( p )[0]; j++ ) {
            setPolygonVector( p[n][i][j], v[i][j][0], v[i][j][1], v[i][j][2] ) ;
        }
    }
}

// polygon を配置する
void AddPolygons( int p[ ][ ][ ], int ng, int renderer, int cd[ ] ) {

    for ( int i=0; i<length( p )[1]; i++ ) {
        for ( int j=0; j<length( p )[0]; j++ ) {
            addPolygon( p[ng][i][j], renderer, cd[ng] ) ;
        }
    }
}


/* MOTION */

double GetLinearTime( int v ) {

    double t0 = getVectorX( v ) ;
    double t1 = getVectorY( v ) ;
    double t;
    if ( T < t0 ) {
        t = 0.0 ;
    } else if ( T < t1 - STEP ) {
        t = ( T - t0 ) / ( t1 - t0 - STEP ) ;
    } else {
        t = 1.0 ;
    }
    return t ;
}

double GetSmoothTime( int v, double p ) {
// p=0でsin, pはだいたい0.7くらいまで
    double t0 = getVectorX( v ) ;
    double t1 = getVectorY( v ) ;
    double t;
    if ( T < t0 ) {
        t = 0.0 ;
    } else if ( T < t1 - STEP ) {
        t = ( T - t0 ) / ( t1 - t0 - STEP ) ;
    } else {
        t = 1.0 ;
    }
    double value ;
    if ( p > 0.0 ) {
        if ( t < 0.5 ) {
            double u = 2 * ( 1.0 - t ) - 1.0 ;
            double s = ( 1.0 + p )/( 2*p ) 
                        * ( 1.0 - sqrt( 1.0 - 4*p/( ( 1.0 + p )^2 ) * u ) ) ;
            value = ( 1.0 - sin( PI/2 * s ) ) / 2 ;
        } else {
            double u = 2 * t - 1.0 ;
            double s = ( 1.0 + p )/( 2*p ) 
                        * ( 1.0 - sqrt( 1.0 - 4*p/( ( 1.0 + p )^2 ) * u ) ) ;
            value = ( 1.0 + sin( PI/2 * s ) ) / 2 ;
        }
    } else if ( p == 0.0 ) {
        if( t < 0.5 ) {
            double u = 2 * ( 1.0 - t ) - 1.0 ;
            value = ( 1.0 - sin( PI/2 * u ) ) / 2 ;
        } else {
            double u = 2 * t - 1.0 ;
            value = ( 1.0 + sin( PI/2 * u ) ) / 2 ;
        }
    }
    return value ;
}

void SetTRange( int v, double dt1, double dt0 ) {

    double t0 = getVectorY( v ) + dt1 ;
    double t1 = t0 + dt0 ;
    setVector( v, t0, t1, dt0 );
}

void SetTRangeAbsolutely( int v, double t0, double t1 ) {

    setVector( v, t0, t1, t1 - t0 );
}

bool Motion( int v ) {

    return ( T >= getVectorX( v ) ) && ( T < getVectorY( v ) ) ;
}

bool Moment( int v ) {

    double t0 = getVectorX( v ) ;
    double t1 = t0 + STEP ;
    return ( T >= t0 ) && ( T < t1 ) ;
}

// blinder
void VisualizePolygon( int polygon, int renderer, int r, int g, int b, int v ) {

    if ( Motion( v ) ) {
        if ( Moment( v ) ) {
            int screen = getScreenCoordinate( renderer ) ;
            addPolygon( polygon, renderer , screen );
            movePolygon( polygon, o, o, -1.0 );
        }
        double t = GetLinearTime( v ) ;
        int opacity = 255 * t ;
        setPolygonColor( polygon, r, g, b, opacity );
    }
}

void RemovePolygonAfterUnvisualize( 
    int polygon, int renderer, int r, int g, int b, int v 
) {

    double endtime = getVectorY( v ) ;
    int screen = getScreenCoordinate( renderer ) ;
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = 255 * ( 1.0 - t ) ;
        setPolygonColor( polygon, r, g, b, opacity );
        if ( T > endtime - STEP ) {
            removePolygon( polygon, renderer, screen );
        }
    }
}

void UnvisualezePolygon( int polygon, int r, int g, int b, int endopacity, int v ) {

    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = 255 - ( 255 - endopacity ) * t ;
        setPolygonColor( polygon, r, g, b, opacity );
    }
}

// text
string TEXT_RUSEN = "http://rusen.seesaa.net" ;

int NewTextPolygonLowLeft( string text, double magnification, double z ) {

    int framewidth_x = 14 ;
    int framewidth_y = 39 ;
    double size = -50 * z / magnification ;
    double x = -size * ( WIDTH - framewidth_x ) / 100 ; 
    double y = -size * ( HEIGHT - framewidth_y ) / 100 ;
    int txtpolygon = newTextPolygon( x, y, 1.0 + z, 0.9 * size, text ) ;
    return txtpolygon ;
}

void OpenTextWhite( int v, double t0, double t1 ) {

    SetTRangeAbsolutely( v, t0, t1 );
    VisualizePolygon( BLINDER, RENDERER, 255, 255, 255, v );
    SetTRange( v, o, 3.0 );
    if ( Moment ( v ) ) {
        COUNT = -1 ;
    }
    RemovePolygonAfterUnvisualize( BLINDER, RENDERER, 255, 255, 255, v );
    SetTRange( v, -4.0, 4.0 );
    VisualizePolygon( TEXT, RENDERER, 255, 255, 255, v );
    SetTRange( v, 3.0, 8.0 )
    UnvisualezePolygon( TEXT, 255, 255, 255, 5, v );
    SetTRange( v, -14.0, o );
}

void OpenBlindBlack( int v, double t0, double t1 ) {

    SetTRangeAbsolutely( v, t0, t1 );
    VisualizePolygon( BLINDER, RENDERER, 0, 0, 0, v );
    SetTRange( v, o, 3.0 );
    if ( Moment ( v ) ) {
        COUNT = -1 ;
    }
    RemovePolygonAfterUnvisualize( BLINDER, RENDERER, 0, 0, 0, v );
    SetTRange( v, -3.0, 5.0 );
    VisualizePolygon( TEXT, RENDERER, 255, 255, 255, v );
    SetTRange( v, 8.0, 5.0 )
    UnvisualezePolygon( TEXT, 255, 255, 255, 5, v );
    SetTRange( v, -18.0, o );
}

void CloseTextWhite( int v, double dt1, double dt0 ) {

    SetTRange( v, dt1, dt0 );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = 255*t ;
        setPolygonColor( TEXT, 255, 255, 255, opacity );
    }
    SetTRange( v, dt1, 3.0 );
    VisualizePolygon( BLINDER, RENDERER, 255, 255, 255, v );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int c = 255 * ( a - t ) ;
        setPolygonColor( TEXT, c, c, c, 255 ) ;
    }
    SetTRange( v , o, 2.0 );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = 255 * ( a - t ) ;
        setPolygonColor( TEXT, 0, 0, 0, opacity );
    }
}

void CloseBlindBlack( int v, double dt1, double dt0 ) {

    SetTRange( v, dt1, dt0 );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = 255*t ;
        setPolygonColor( TEXT, 255, 255, 255, opacity );
    }
    SetTRange( v , 5.0, 5.0 );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = 255 * ( a - t ) ;
        setPolygonColor( TEXT, 255, 255, 255, opacity );
    }
}


/* COLORS */

int[ ] Color( int i, int j, int k ) {

    int c[ 3 ] ;
    if ( ( i < 0 ) || ( j < 0 ) || ( k < 0 ) 
            || ( i > 255 ) || ( j > 255 ) || ( k > 255 ) ) {
        c = 0 ;
        alert( "Error ( Color ) " );
    } else {
        c[0] = i ;
        c[1] = j ;
        c[2] = k ;
    }
    return c ;
}

int[ ] Color( float r, float g, float b ) {

    int c[ 3 ] ;
    if ( ( r < 0.0 ) || ( g < 0.0 ) || ( b < 0.0 ) 
            || ( r > 1.0 ) || ( g > 1.0 ) || ( b > 1.0 ) ) {
        c = 0 ;
        alert( "Error ( Color ) " );
    } else {
        c[0] = 255 * r ;
        c[1] = 255 * g ;
        c[2] = 255 * b ;
    }
    return c ;
}

int[ ] Color( float x ) {

    int c[ 3 ] ;
    if ( ( x < 0.0 ) || ( x > 1.0 ) ) {
        c = 0 ;
        alert( "Error ( Color ) " );
    } else {
        c = 255 * x ;
    }
    return c ;
}


/* GEOMETRY */

// antiprism

double GetHeightAntiprismByConnectionName( 
    int nside, double rad, string polyhedronname 
) {

    double delta = rad * ( 1 - cos( PI/nside ) ) ;
    double antiprismdhangle ; // 底面と側面の normal vector の作る角
    if ( polyhedronname == "cube" ) {
        antiprismdhangle = 3*PI/4 ;
    } else {
        alert( "error( GetHeightAntiprismByName )) ;
    }
    double antiprismheight = delta * tan( PI - antiprismdhangle ) ;
    return antiprismheight ;
}

int[ ] Get3Vectors4sideAntiprismCubeConnection( double baserad ) {

    int v[ 3 ] ;
    v[0] = newVector( o, o, baserad ) ;
    v[1] = GetRotYVector( v[0], PI/2 ) ;
    double h = GetHeightAntiprismByConnectionName( 4, baserad, "cube" ) ;
    v[2] = newVector( o, h, o ) ;
    return v ;
}

// dodecahedron

// dodecahedron の inradiusを返す
double GetInradiusDodecahedron( double prad ) {

    return prad * ( Gld + 1 ) / 2 ;
}

// 原点中心、zx平面内、regular n-gonのz軸上の点(z>0)とその反時計回り隣の点

int[ ] Get3VectorsNGon( int n, double rad ) {

    int u[ 3 ] ;
    u[0] = newVector( o, o, o ) ;
    u[1] = newVector( o, o, rad ) ;
    u[2] = GetRotYVector( u[1], 2*PI/n ) ;
    return u ;
}

// diamond space filler の頂点ベクトルを返す
int[ ][ ][ ] GetVectorsDiamondSpaceFiller( double x ) { // vertex ( x, 0, 0 )

    int v[ S4 ][ R3*2 ][ R3 ] ;
    v[0][0][0] = newVector( o, x, o ) ;
    v[0][0][1] = newVector( -x/2, x/2, x/2 ) ;
    v[0][0][2] = newVector( x/4, x/4, x/4 ) ;
    v[0][1][0] = newVector( v[0][0][1] ) ;
    v[0][1][1] = newVector( o, o, x ) ;
    v[0][1][2] = newVector( v[0][0][2] ) ;
    int ax0 = newVector( a, a, a ) ;
    int ax1 = newVector( a, o, a ) ;
    for ( int i=1; i<R3; i++ ) {
        for ( int j=0; j<R3; j++ ) {
            v[0][2*i][j] = GetRotVector( v[0][0][j], 2*PI/3 * i, ax0, O ) ;
            v[0][2*i+1][j] = GetRotVector( v[0][1][j], 2*PI/3 * i, ax0, O ) ;
        }
    }
    for ( int i=1; i<S4; i++ ) {
        for ( int j=0; j<R3*2; j++ ) {
            for ( int k=0; k<R3; k++ ) {
                v[i][j][k] = GetRotYVector( v[0][j][k], PI/2 * i ) ;
                if ( i%2 == 1 ) {
                    rotVector( v[i][j][k], PI, ax1 ) ;
                }
            }
        }
    }
    return v ;
}

// octahedron の頂点ベクトルを返す
int[ ][ ] GetVectorsOctahedron( double x ) { // vertex ( x, 0, 0 )

    int v[ S8 ][ R3 ] ;
    v[0][0] = newVector( x, o, o ) ;
    v[0][1] = newVector( o, x, o ) ;
    v[0][2] = newVector( o, o, x ) ;
    for ( int i=1; i<S8; i++ ) {
        for ( int j=0; j<R3; j++ ) {
            if ( i <= 3 ) {
                v[i][j] = GetRotYVector( v[0][j], PI/2 * ( i%4 ) ) ;
            } else {
                v[i][j] = GetRotZVector( v[0][j], PI ) ;
                rotYVector( v[i][j], PI/2 * ( ( i - 3 ) % 4 ) ) ;
            }
        }
    }
    return v ;
}

int[ ] GetVectors4FacesSymmetry( double x ) { // ( x, x, x )

    int v[ 4 ] ;
    v[0] = newVector( x, x, x ) ;
    v[1] = GetRotYVector( v[0], PI ) ;
    v[2] = GetRotXVector( v[0], PI ) ;
    v[3] = GetRotZVector( v[0], PI ) ;
    return v ;
}




/* set lights */


int AMBIENT_LIGHT = newAmbientLight( o, o, o, o ) ;
int LIGHT0 = newPointLight( o, o, o, o ) ;
int LIGHT1 = newLight( -0.48, 0.1, 0.84, o ) ; 
int LIGHT2 = newLight( 0.2, 0.52, -0.1, o ) ;

void SetLights() {
    double power = 0.8 ;
    SetAmbientLight ( AMBIENT_LIGHT, o, o, o, power, RENDERER );
}




/* create elements (polygnのみ) */


void SetElements() {

    SetElementOptions();
    AddElements();
}

int NG = 1 ; // group の数

int Q11[ NG ][ S12 ][ R5*2 ] ; // quadrangl, pentagon, 1st
int Q12[ NG ][ S12 ][ R5*2 ] ; // quadrangl, pentagon, 2nd
int Q21[ NG ][ S12 ][ R5*2 ] ; // quadrangl, star, 1st
int Q22[ NG ][ S12 ][ R5*2 ] ; // quadrangl, star, 2nd
int Q23[ NG ][ S12 ][ R5*2 ] ; // quadrangl, star, 3rd, between 1st and 2nd
int L11[ NG ][ S12 ][ R5 ][ 3 ] ; // line, star, 1st
int L12[ NG ][ S12 ][ R5 ][ 4 ] ; // line, star, 2nd

for ( int i=0; i<length( Q11 )[2]; i++ ) {
    for ( int j=0; j<length( Q11 )[1]; j++ ) {
        for ( int k=0; k<length( Q11 )[0]; k++ ) {
            Q11[i][j][k] = newQuadranglePolygon( O, O, O, O ) ;
            Q12[i][j][k] = newQuadranglePolygon( O, O, O, O ) ;
            Q21[i][j][k] = newQuadranglePolygon( O, O, O, O ) ;
            Q22[i][j][k] = newQuadranglePolygon( O, O, O, O ) ;
            Q23[i][j][k] = newQuadranglePolygon( O, O, O, O ) ;
            if ( k < R5 ) {
                for ( int l=0; l<length( L12 )[0]; l++ ) {
                    if ( l < length( L11 )[0] ) {
                        L11[i][j][k][l] = newLinePolygon( O, O, a/70 ) ;
                    }
                    L12[i][j][k][l] = newLinePolygon( O, O, a/70 ) ;
                }
            }
        }
    }
}

void RotSystems12FacesSymmetry( int cd[ ][ ], int n, double spin ) {

    int len = length( cd )[0] ;
    int dummycd[ len ], sa[ len ] ;
    for ( int i=0; i<len; i++ ) {
        dummycd[i] = newCoordinate() ;
    }
    double angleff = PI - 2 * atan( IGld ) ;
    for ( int i=0; i<S12; i++ ) {
        if ( ( i == 0 ) || ( i == 11 ) ) {
            rotXCoordinate( dummycd[i], PI ) ;
        } else {
            rotYCoordinate( dummycd[i], PI ) ;
            rotXCoordinate( dummycd[i], angleff ) ;
            double anglei = 2*PI/R5 * ( ( i -1 ) % 5 ) ;
            rotYCoordinate( dummycd[i], anglei ) ;
        }
        if ( i <= 5 ) {
            rotZCoordinate( dummycd[i], PI ) ;
        } else {
            rotYCoordinate( dummycd[i],  PI/R5 ) ;
        }
        spinYCoordinate( dummycd[i], spin ) ;
        sa[i] = GetVectorCoordinateEulerAngle( dummycd[i] ) ;
        SetCoordinateEulerAngle( cd[n][i], sa[i] ) ;
    }
}

void SetPolygons5gon( int q1[ ][ ][ ], int q2[ ][ ][ ], int n, double prad ) {

    int v[ ] = Get3VectorsNGon( 5, prad ) ;
    int mid = GetMiddlePointVector( v[1], v[2] ) ;
    int u[ R5 ][ 2 ]int m[ R5 ], um[ R5 ][ 2 ], mm[ R5 ] ;
    for ( int i=0; i<R5; i++ ) {
        u[i][0] = GetRotYVector( v[1], 2*PI/R5 * i ) ;
        u[i][1] = GetRotYVector( v[2], 2*PI/R5 * i ) ;
        m[i] = GetRotYVector( mid, 2*PI/R5 * i ) ;
        um[i][0] = GetScaleVector( u[i][0], 2*a/3 ) ;
        um[i][1] = GetScaleVector( u[i][1], 2*a/3 ) ;
        mm[i] = GetScaleVector( m[i], 2*a/3 ) ;
    }
    for ( int i=0; i<S12; i++ ) {
        for ( int j=0; j<R5; j++ ) {
            setPolygonVector( q1[n][i][2*j], O, um[j][0], mm[j], O ) ;
            setPolygonVector( q1[n][i][2*j+1], O, mm[j], um[j][1], O ) ;
            setPolygonVector( q2[n][i][2*j], mm[j], um[j][0], u[j][0], m[j] ) ;
            setPolygonVector( q2[n][i][2*j+1], m[j], u[j][1], um[j][1], mm[j] ) ;
        }
    }
}

void SetPolygons5gram( // ある星型化率の pentagon
    int l1[ ][ ][ ][ ], int l2[ ][ ][ ][ ],
    int q1[ ][ ][ ], int q2[ ][ ][ ], int q3[ ][ ][ ],
    int n, double prad, double dist, double spin, double stellation
) {

    int v[ ] = Get3VectorsNGon( 5, prad ) ;
    int mid = GetMiddlePointVector( v[1], v[2] ) ;
    int top = GetScaleVector( mid, 2 * Gld ) ;
    int u[ R5 ][ 2 ] ; int m[ R5 ], t[ R5 ] ;
    for ( int i=0; i<R5; i++ ) {
        u[i][0] = GetRotYVector( v[1], 2*PI/R5 * i ) ;
        u[i][1] = GetRotYVector( v[2], 2*PI/R5 * i ) ;
        m[i] = GetRotYVector( mid, 2*PI/R5 * i ) ;
        t[i] = GetRotYVector( top, 2*PI/R5 * i ) ;
    }
    double dssd = GetInradiusDodecahedron( prad ) ; // small stellated dodecahedron の場合
    if ( spin == o ) {
        double ds = 2*Gld * dssd ; // pentagram が dodecahedron 稜心を結んでできた形になる場合
        if ( dist > ds ) {
            if ( abs( a - stellation ) <= d^10 ) {
                for ( int i=0; i<S12; i++ ) {
                    for ( int j=0; j<R5; j++ ) {
                        setPolygonVector( q1[n][i][2*j], m[j], u[j][0], t[j], t[j] ) ;
                        setPolygonVector( q1[n][i][2*j+1], u[j][1], m[j], t[j], t[j] ) ;
                        setPolygonVector( q2[n][i][2*j], O, O, O, O ) ;
                        setPolygonVector( q2[n][i][2*j+1], O, O, O, O ) ;
                        setPolygonVector( q3[n][i][2*j], O, O, O, O ) ;
                        setPolygonVector( q3[n][i][2*j+1], O, O, O, O ) ;
                        setPolygonVector( l1[n][i][j][0], u[j][0], t[j] ) ;
                        setPolygonVector( l1[n][i][j][1], u[j][1], t[j] ) ;
                        setPolygonVector( l1[n][i][j][2], u[j][0], u[j][1] ) ;
                        for ( int k=0; k<length( l2 )[0]; k++ ) {
                            setPolygonVector( l2[n][i][j][k], O, O ) ;
                        }
                    }
                }
            } else if ( stellation < a ) {
                int stel[ R5 ][ 2 ], stelmid[ R5 ] ;
                for ( int i=0; i<R5; i++ ) {
                    stel[i][0] 
                        = GetInternallyDividingVector( u[i][0], t[i], stellation ) ;
                    stel[i][1] 
                        = GetInternallyDividingVector( u[i][1], t[i], stellation ) ;
                    stelmid[i]
                        = GetInternallyDividingVector( m[i], t[i], stellation ) ;
                }
                for ( int i=0; i<S12; i++ ) {
                    for ( int j=0; j<R5; j++ ) {
                        setPolygonVector( 
                            q1[n][i][2*j], m[j], u[j][0], stel[j][0], stelmid[j] 
                        ) ;
                        setPolygonVector( 
                            q1[n][i][2*j+1], u[j][1], m[j], stelmid[j], stel[j][1] 
                        ) ;
                        setPolygonVector( q2[n][i][2*j], O, O, O, O ) ;
                        setPolygonVector( q2[n][i][2*j+1], O, O, O, O ) ;
                        setPolygonVector( q3[n][i][2*j], O, O, O, O ) ;
                        setPolygonVector( q3[n][i][2*j+1], O, O, O, O ) ;
                        setPolygonVector( l1[n][i][j][0], u[j][0], stel[j][0] ) ;
                        setPolygonVector( l1[n][i][j][1], u[j][1], stel[j][1] ) ;
                        setPolygonVector( l1[n][i][j][2], u[j][0], u[j][1] ) ;
                        setPolygonVector( l2[n][i][j][0], stel[j][0], stel[j][1] ) ;
                        for ( int k=1; k<length( l2 )[0]; k++ ) {
                            setPolygonVector( l2[n][i][j][k], O, O ) ;
                        }
                    }
                }
            }
        } else {
            if ( dist >= dssd ) {
                double s = ( dist - ds ) / ( dssd - ds ) ; // crss section parameter
                int cross[ R5 ][ 2 ], crossmid[ R5 ], stel[ R5 ][ 2 ], stelmid[ R5 ] ;
                int crstm[ R5 ][ 2 ], mmm[ R5 ] ; // cross より上を2等分するため
                for ( int i=0; i<R5; i++ ) {
                    cross[i][0] = GetInternallyDividingVector( t[i], u[i][0], s ) ;
                    cross[i][1] = GetInternallyDividingVector( t[i], u[i][1], s ) ;
                    crossmid[i] = GetInternallyDividingVector( t[i], m[i], s ) ;
                    stel[i][0] 
                        = GetInternallyDividingVector( u[i][0], t[i], stellation ) ;
                    stel[i][1] 
                        = GetInternallyDividingVector( u[i][1], t[i], stellation ) ;
                    stelmid[i]
                        = GetInternallyDividingVector( m[i], t[i], stellation ) ;
                    crstm[i][0] 
                        = GetInternallyDividingVector( cross[i][0], stel[i][0], 0.7 ) ;
                    crstm[i][1] 
                        = GetInternallyDividingVector( cross[i][1], stel[i][1], 0.7 ) ;
                    mmm[i] 
                        = GetInternallyDividingVector( crossmid[i], stelmid[i], 0.7 ) ;
                }
                if ( stellation >= a - s ) { // 星型化内で cross する場合
                    for ( int i=0; i<S12; i++ ) {
                        for ( int j=0; j<R5; j++ ) {
                            setPolygonVector( q1[n][i][2*j],
                                m[j], u[j][0], cross[j][0], crossmid[j] 
                            ) ;
                            setPolygonVector( q1[n][i][2*j+1], 
                                u[j][1], m[j], crossmid[j], cross[j][1] 
                            ) ;
                            setPolygonVector( q2[n][i][2*j], 
                                crossmid[j], cross[j][0], crstm[j][0], mmm[j] 
                            ) ;
                            setPolygonVector( q2[n][i][2*j+1], 
                                cross[j][1], crossmid[j], mmm[j], crstm[j][1] 
                            ) ;
                            setPolygonVector( q3[n][i][2*j], 
                                mmm[j], crstm[j][0], stel[j][0], stelmid[j] 
                            ) ;
                            setPolygonVector( q3[n][i][2*j+1], 
                                crstm[j][1], mmm[j], stelmid[j], stel[j][1] 
                            ) ;
                            setPolygonVector( 
                                l1[n][i][j][0], u[j][0], cross[j][0] 
                            ) ;
                            setPolygonVector( 
                                l1[n][i][j][1], u[j][1], cross[j][1] 
                            ) ;
                            setPolygonVector( 
                                l1[n][i][j][2], u[j][0], u[j][1] 
                            ) ;
                            setPolygonVector( 
                                l2[n][i][j][0], stel[j][0], stel[j][1] 
                            ) ;
                            setPolygonVector( 
                                l2[n][i][j][1], cross[j][0], stel[j][0] 
                            ) ;
                            setPolygonVector( 
                                l2[n][i][j][2], cross[j][1], stel[j][1] 
                            ) ;
                            setPolygonVector( 
                                l2[n][i][j][3], cross[j][0], cross[j][1] 
                            ) ;
                        }
                    }
                } else if ( stellation < a - s ) { // 星型化外で cross する場合
                    int stel[ R5 ][ 2 ], stelmid[ R5 ] ;
                    for ( int i=0; i<R5; i++ ) {
                        stel[i][0] 
                            = GetInternallyDividingVector( u[i][0], t[i], stellation ) ;
                        stel[i][1] 
                            = GetInternallyDividingVector( u[i][1], t[i], stellation ) ;
                        stelmid[i]
                            = GetInternallyDividingVector( m[i], t[i], stellation ) ;
                    }
                    for ( int i=0; i<S12; i++ ) {
                        for ( int j=0; j<R5; j++ ) {
                            setPolygonVector( 
                                q1[n][i][2*j], m[j], u[j][0], stel[j][0], stelmid[j] 
                            ) ;
                            setPolygonVector( 
                                q1[n][i][2*j+1], u[j][1], m[j], stelmid[j], stel[j][1] 
                            ) ;
                            setPolygonVector( q2[n][i][2*j], O, O, O, O ) ;
                            setPolygonVector( q2[n][i][2*j+1], O, O, O, O ) ;
                            setPolygonVector( q3[n][i][2*j], O, O, O, O ) ;
                            setPolygonVector( q3[n][i][2*j+1], O, O, O, O ) ;
                            setPolygonVector( l1[n][i][j][0], u[j][0], stel[j][0] ) ;
                            setPolygonVector( l1[n][i][j][1], u[j][1], stel[j][1] ) ;
                            setPolygonVector( l1[n][i][j][2], u[j][0], u[j][1] ) ;
                            setPolygonVector( l2[n][i][j][0], stel[j][0], stel[j][1] ) ;
                            for ( int k=1; k<length( l2 )[0]; k++ ) {
                                setPolygonVector( l2[n][i][j][k], O, O ) ;
                            }
                        }
                    }
                }
            }
        }
    }
}

int OPACITY[ ] = { 255, 10, 30 } ;

float OPTION0[ 6 ], OPTION1[ 6 ];
{
    float emissive = o ; 
    float diffractive = 0.5 ; 
    float diffuse = 0.9 ; 
    float ambient = 0.15 ;
    float specularintensity = 0.6, specularangle = PI/15 ; 

    OPTION0[0] = emissive ;
    OPTION0[1] = diffractive ;
    OPTION0[2] = diffuse ;
    OPTION0[3] = ambient ;
    OPTION0[4] = specularintensity ; OPTION0[5] = specularangle ;
    OPTION1 = OPTION0 ;
    OPTION1[0] = 0.9 ;
    OPTION1[3] = 0.9 ;
    OPTION1[4] = 0.4 ; OPTION1[5] = 1.5 ;
}

int COLOR[ S12 ][ 3 ] ;

void SetElementOptions() {

    float r, g, b ;
    int color[ 3 ] ;
    for ( int i=0; i<length( Q11 )[2]; i++ ) {
        for ( int j=0; j<length( Q11 )[1]; j++ ) {
            if ( ( j == 0 ) || ( j == 7 ) || ( j == 9 ) ) {
                r = a ; g = o ; b = a/2 ;
            } else if ( ( j == 1 ) || ( j == 4 ) || ( j == 11 ) ) {
                r = o ; g = 2*a/3 ; b = a ;
            } else if ( ( j == 2 ) || ( j == 6 ) || ( j == 8 ) ) {
                r = a/2 ; g = a ; b = o ;
            } else {
                r = 1*a/3 ; g = o ; b = a ;
            }
            for ( int n=0; n<3; n++ ) {
                COLOR[j][n] = Color( r, g, b )[n] ;
            }
            color = Color( r, g, b ) ;
            for ( int k=0; k<length( Q11 )[0]; k++ ) {
                setPolygonSortOffset( Q12[i][j][k], -0.2*l ) ;
                setPolygonCull( Q11[i][j][k], false, false ) ;
                setPolygonCull( Q12[i][j][k], false, false ) ;
                setPolygonCull( Q21[i][j][k], false, false ) ;
                setPolygonCull( Q22[i][j][k], false, false ) ;
                setPolygonCull( Q23[i][j][k], false, false ) ;
                SetPolygonColor( Q11[i][j][k], color, OPACITY[0] ) ;
                SetPolygonColor( Q12[i][j][k], color, OPACITY[0] ) ;
                SetPolygonColor( Q21[i][j][k], color, OPACITY[0] ) ;
                SetPolygonColor( Q22[i][j][k], color, OPACITY[1] ) ;
                SetPolygonColor( Q23[i][j][k], color, OPACITY[1] ) ;
                if ( k < length( L11 )[1] ) {
                    for ( int l=0; l<length( L12 )[0]; l++ ) {
                        if ( l < length( L11 )[0] ) {
                            SetPolygonColor( L11[i][j][k][l], color, OPACITY[2] ) ;
                        }
                        SetPolygonColor( L12[i][j][k][l], color, OPACITY[2] ) ;
                    }
                }
                SetPolygonSurface( Q11[i][j][k], OPTION0 ) ;
                SetPolygonSurface( Q12[i][j][k], OPTION0 ) ;
                SetPolygonSurface( Q21[i][j][k], OPTION0 ) ;
                SetPolygonSurface( Q22[i][j][k], OPTION1 ) ;
                SetPolygonSurface( Q23[i][j][k], OPTION1 ) ;
            }
        }
    }
}


void AddElements() {

    int color[ 3 ];
    addLight( LIGHT1, RENDERER, COORD[length( COORD )[0]-1] ) ;
    addLight( LIGHT2, RENDERER, COORD[length( COORD )[0]-1] ) ;
    setLightBrightness( LIGHT1, 0.7 ) ;
    setLightBrightness( LIGHT2, 0.3 ) ;
    double prad = o, dist = GetInradiusDodecahedron( l ), spin = o, stellation = a ;
    for ( int i=0; i<length( Q11 )[2]; i++ ) {
        RotSystems12FacesSymmetry( CD, i, spin ) ;
        SetPolygons5gon( Q11, Q12, i, prad ) ;
        SetPolygons5gram( 
            L11, L12,
            Q21, Q22, Q23,
            i, prad, dist, spin , stellation
        ) ;
        for ( int j=0; j<length( Q11 )[1]; j++ ) {
            SetCoordinateLocationYdirection( CD[i][j], dist ) ;
            for( int k=0; k<length( Q11 )[0]; k++ ) {
                addPolygon( Q11[i][j][k], RENDERER, CD[i][j] ) ;
                addPolygon( Q12[i][j][k], RENDERER, CD[i][j] ) ;
                addPolygon( Q21[i][j][k], RENDERER, CD[i][j] ) ;
                addPolygon( Q22[i][j][k], RENDERER, CD[i][j] ) ;
                addPolygon( Q23[i][j][k], RENDERER, CD[i][j] ) ;
                if ( k < length( L11 )[1] ) {
                    for ( int l=0; l<length( L12 )[0]; l++ ) {
                        if ( l < length( L11 )[0] ) {
                            addPolygon( L11[i][j][k][l], RENDERER, CD[i][j] ) ;
                        }
                        addPolygon( L12[i][j][k][l], RENDERER, CD[i][j] ) ;
                    }
                }
            }
        }
    }
}




/* set coordinates */


int COORD[ 7 ];
int CD[ NG ][ S12 ]; // for 12 faces
for ( int i=0; i<length( COORD )[0]; i++ ) {
    COORD[i] = newCoordinate() ;
}
for ( int i=0; i<length( CD )[1]; i++ ) {
    for ( int j=0; j<length( CD )[0]; j++ ) {
        CD[i][j] = newCoordinate() ;
    }
}

void SetCoordinates() {

    PileCoordinate( COORD, RENDERER );
    for ( int i=0; i<length( CD )[1]; i++ ) {
        for ( int j=0; j<length( CD )[0]; j++ ) {
            addCoordinate( CD[i][j], RENDERER, COORD[0] );
        }
    }
}




/* set axes */


int AXIS[ 10 ];
{
    float x, y, z ;
    for ( int i=0; i<length( AXIS )[0]; i++ ) {
        x = ( 5*l - 0.5*l*i ) * l ; y = x ; z = x ;
        AXIS[i] = newAxisModel( x, y, z ) ;
    }
}

void SetAxes() {

    addModel( AXIS[0], RENDERER, COORD[0] );
    addModel( AXIS[7], RENDERER, CD[0][0] );
    addModel( AXIS[4], RENDERER, CD[0][1] );
    addModel( AXIS[1], RENDERER, CD[0][2] );
}




/* prepare stage */


double CAM_X0 = o;
double CAM_Y0 = o;
double CAM_Z0 = 16*l ;
float GRAPHIC_MAGNIFICATION = 1000.0 ;
double GRAPHIC_DISTANCE = 10.0 ;
int WORLD;

void PrepareStage() {

    setGraphics3DCenter( RENDERER, WIDTH / 2, HEIGHT / 2 );
    setGraphics3DDistance( RENDERER, GRAPHIC_DISTANCE );
    setGraphics3DMagnification( RENDERER, GRAPHIC_MAGNIFICATION );

    setGraphics3DClipFront( RENDERER, o );
    setGraphics3DClipBack( RENDERER, -10000.0 );

    WORLD = getWorldCoordinate( RENDERER );
    setCoordinateOrigin( WORLD, o, o, o )
    setCoordinateEulerAngle( WORLD, o, o, o );
    setCameraOrigin( WORLD, CAM_X0, CAM_Y0, CAM_Z0 );
    setCameraEulerAngle( WORLD, o, o, o );
}




/* animation Loop except
ただし、ForwardMotion() と CreateGuiElements() 以外 */


bool KEEP_LOOP = true ;
bool SAVE_A_PICTURE = false ;

int COUNT = 0 ;
int FPS = 20 ; // frames / 1sec
int PICTURE_NUMBER = 0 ; 
int PICTURE_END_NUMBER = 5000 ;

double T = o, T0 = -100.0 ;
double STEP, TIME_FLOW ;
{
    TIME_FLOW = 1.0 ;
    STEP = TIME_FLOW / FPS ;
}




/* create GUI elements */


int SETTING_WINDOW ; 

int LABEL_SLIDER[ 2 ] ;
N = length( LABEL_SLIDER ) ; int SLIDER[ N ] ; string SLIDER_TEXT[ N ] ; 
double P[ N ] = o, P0[ N ] ;

int CHECK_BOX[ 2 ] ;
N = length( CHECK_BOX ) ; string CHECK_TEXT[ N ] ;
bool SPIN = true, LIMIT = false ;

int LABEL_SELECT[ 1 ] ;
N = length( LABEL_SELECT ) ; int SELECT[ N ] ; string SELECT_TITLE[ N ] ;
string SELECT_TEXT[ N ][ 3 ] ;
bool GET_TIME = false ;
bool TURN_GET_TIME = false ;
int OPACITY_INDEX = 0 ;
int FORMER_OPACITY_INDEX = 0 ; 

SELECT_TITLE[0] = "星型化部分の透明度" ;
SELECT_TEXT[0][0] = "ほぼ透明" ;
SELECT_TEXT[0][1] = "半透明" ;
SELECT_TEXT[0][2] = "不透明" ;
CHECK_TEXT[0] = "多面体の回転" ;
CHECK_TEXT[1] = "操作を4面に対してのみ行う" ;
SLIDER_TEXT[0] = "面と原点の距離変更" ; 
SLIDER_TEXT[1] = "面の変形(正五角形 〜 五芒星)" ;

void CreateGuiElements() {

    // setting window
    int sidewidth = 6 ;
    int nsell = length( SELECT ) ; int nsel = nsell ;
    int nsldl = length( SLIDER ) ; int nsld = nsldl ;
    int lx = 15 , lw = 250 ; 
    int lh = 15 ; int lyspace = 20 ;
    int sliderx = lx , sliderw = lw, sliderh = 20 , slideryspace = 10 ;
    int sliderlabely[ nsldl ] ; int slidery[ nsld ] ;
    int selectx = lx , selectw = lw - sidewidth , selecth = 20 , selectyspace = 10 ;
    int selectlabely[ nsell ] ; int selecty[ nsel ] ;
    int check0x = lx, check0w = lw, check0h = lh, check0yspace = 40;
    int check0y ;
    int check1x = lx, check1w = lw, check1h = lh, check1yspace = 40 ;
    int check1y ;

    {
        int initial_ly = 20;
        check0y = initial_ly  ;
        for ( int i=0; i<nsel; i++ ) {
            selectlabely[i] = check0y + check0h + lyspace
                + ( lyspace + lh + selectyspace + selecth ) * i ;
            selecty[i] = selectlabely[i] + lh + selectyspace ;
        }
        check1y = selecty[nsel-1] + selecth + lyspace ;
        for ( int i=0; i<nsld; i++ ) {
            sliderlabely[i] = check1y + check1h + lyspace
                + ( lyspace + lh + slideryspace + sliderh ) * i ;
            slidery[i] = sliderlabely[i] + lh + slideryspace ;
        }
    }

    int wx = WINDOW_POSITION_X + WIDTH + 1 * sidewidth ;
    int wy = 0 ;
    int framewidth_y = 30 ;
    int ww = lw + 2*lx + 2*sidewidth ;
    int wh = slidery[nsld-1] + 75 ;

    {
        string wtext = "Setting Window" ;
        SETTING_WINDOW = newWindow( wx, wy, ww, wh, wtext ) ;

        // select field
        int lentex[ ] = length( SELECT_TEXT ) ; int lentex0 = lentex[0] ;
        for ( int i=0; i<nsel; i++ ) {
            LABEL_SELECT[i] = newTextLabel( 
                                    lx, selectlabely[i], lw, lh, SELECT_TITLE[i]
                                ) ;
            addComponent( LABEL_SELECT[i], SETTING_WINDOW ) ;
            setComponentFontSize( LABEL_SELECT[i], 14 ) ; // default 12
            string text[ lentex0 ] ;
            for ( int j=0; j<lentex0; j++ ) {
                text[j] = SELECT_TEXT[i][j] ;
            }
            SELECT[i] = newSelectField( selectx, selecty[i], selectw, selecth, text ) ; 
            addComponent( SELECT[i], SETTING_WINDOW ) ;
        }

        // 一番上
        CHECK_BOX[0] = newCheckBox ( 
                            lx, check0y, lw, check0h, CHECK_TEXT[0], true
                        ) ;
        setComponentFontSize( CHECK_BOX[0], 14 ) ; // default 12
        addComponent( CHECK_BOX[0], SETTING_WINDOW ) ;
        // スライダーの上
        CHECK_BOX[1] = newCheckBox ( 
                            lx, check1y, lw, check1h, CHECK_TEXT[1], false
                        ) ;
        setComponentFontSize( CHECK_BOX[1], 14 ) ; // default 12
        addComponent( CHECK_BOX[1], SETTING_WINDOW ) ;

        // slider
        for ( int i=0; i<nsld; i++ ) {
            LABEL_SLIDER[i] = newTextLabel( 
                                    lx, sliderlabely[i], lw, lh, SLIDER_TEXT[i] 
                                ) ;
            setComponentFontSize( LABEL_SLIDER[i], 14 ) ; // default 12
            addComponent( LABEL_SLIDER[i], SETTING_WINDOW ) ;
            double inivalue = o ;
            if ( i == 1 ) {
                inivalue = a ;
            }
            SLIDER[i] = newHorizontalSlider( 
                            sliderx, slidery[i], sliderw, sliderh, inivalue 
                        ) ;
            addComponent( SLIDER[i], SETTING_WINDOW ) ;
        }
        P[1] = a ;
    }

    paintComponent( SETTING_WINDOW ) ;
}




/* event handlers */


void onSliderMove( int id, double value ) {

    double prad = l ;
    double p0 = 1 + ( 2*Gld - 1 ) * getComponentValue( SLIDER[0] ) ;
    double p1 = getComponentValue( SLIDER[1] ) ;
    P[0] = p0 * GetInradiusDodecahedron( prad ) ;
    P[1] = p1 ;
    double dist = P[0], stellation = P[1], spin = o ;
    float indexslider0 = (int)( 100*p0 ) / 100.0 ;
    float indexslider1 = (int)( 1000*p1 ) / 10.0 ;
    SLIDER_TEXT[0] = "面と原点の距離" + (string)indexslider0 + "倍 " ;
    SLIDER_TEXT[1] = "面の変形" + (string)indexslider1 + " % " ;
    for ( int i=0; i<length( SLIDER_TEXT ); i++ ) {
        setComponentText( LABEL_SLIDER[i], SLIDER_TEXT[i] ) ;
        paintComponent( LABEL_SLIDER[i] ) ;
    }
    if ( ( TURN_GET_TIME && ( ! LIMIT ) ) || ( ( ! TURN_GET_TIME ) && LIMIT ) ) {
        S12 = 4 ;
    }
    for ( int i=0; i<NG; i++ ) {
        RotSystems12FacesSymmetry( CD, i, spin ) ;
        SetPolygons5gon( Q11, Q12, i, prad ) ;
        SetPolygons5gram( 
            L11, L12,
            Q21, Q22, Q23,
            i, prad, dist, spin, stellation
        ) ;
        for ( int j=0; j<S12; j++ ) {
            SetCoordinateLocationYdirection( CD[i][j], dist ) ;
        }
    }
    S12 = 12 ;

}


void onCheckBoxClick( int id, bool state ){

    if ( ! TURN_GET_TIME ) {
        if ( id == CHECK_BOX[0] ) {
            SPIN = state ;
        } else {
            LIMIT = state ;
            GET_TIME = true ;
            TURN_GET_TIME = true ;
        }
    }
}


void onSelectFieldClick( int id, string text ){

    if ( ! TURN_GET_TIME ) {
        for ( int i=0; i<length( SELECT_TEXT )[0]; i++ ) {
            if ( text == SELECT_TEXT[0][i] ) {
                if ( i != FORMER_OPACITY_INDEX ) {
                    OPACITY_INDEX = i ;
                    GET_TIME = true ;
                    TURN_GET_TIME = true ;
                }
            }
        }
    }
}


/* forward motion */


bool CREATE_GUI = false ;
bool TURN_GUI = false ;
double STOP_TIME ;
double GUI_UPTIME ;

void ForwardMotion() {

    int t = newVector( o, o, o ) ; // x,y成分がそれぞれmotion開始、終了時刻
    double toprotrate ;
    if ( SPIN ) {
        toprotrate = 4/180.0 * PI ;
    } else {
        toprotrate = o ;
    }

    if ( (!TURN_GUI) || TURN_GET_TIME ) {
        DesignMotion( t, toprotrate ) ; // アニメーション
        STOP_TIME = getVectorY( t ) ; // motion終了時刻
        GUI_UPTIME = STOP_TIME + 0.2 ;
        CREATE_GUI = ( T >= GUI_UPTIME ) && ( T < GUI_UPTIME + STEP ) ;
    }

    if ( T < GUI_UPTIME + 1000.0 ) {
        rotYCoordinate( COORD[2], toprotrate ) ;
    }
}

int SO[ NG ][ S12 ]; // system origin point
int SA[ NG ][ S12 ]; // system Euler Angle
int RC[ NG ][ S12 ]; // rotation center vector
int AX[ NG ][ S12 ]; // rotation axis vector
for ( int i=0; i<NG; i++ ) {
    for ( int j=0; j<S12; j++ ) {
        SO[i][j] = newVector() ;
        SA[i][j] = newVector() ;
        RC[i][j] = newVector() ;
        AX[i][j] = newVector() ;
    }
}
int G = newVector() ; // center of gravity

int BLINDER = newQuadranglePolygon( 2*l,2*l,o, -2*l,2*l,o, -2*l,-2*l,o, 2*l,-2*l,) ;
setPolygonEmissive( BLINDER, 1.0 );
setPolygonSpecular( BLINDER, o, 0.01 );
int TEXT = NewTextPolygonLowLeft( TEXT_RUSEN, GRAPHIC_MAGNIFICATION, -0.5 ) ;


void DesignMotion( int v, double yrotation ) {

    double start_t = 1.0 ;
    double unit = 1.0 / 2.0 ; // 時間の単位

    SetTRangeAbsolutely( v, start_t, start_t );

    SetTRange( v, o, STEP ) ;
    if ( Moment( v ) ) {
        setCoordinateEulerAngle( COORD[3], o, PI/2 - 2*atan( IGld ), o ) ;
    }

    SetTRange( v, o, 2*unit );
    if ( Motion( v ) ) {
        double prad = l ;
        int w[ ] = Get3VectorsNGon( 5, prad ) ;
        int mid = GetMiddlePointVector( w[1], w[2] ) ;
        int top = GetScaleVector( mid, 2 * Gld ) ;
        int u[ R5 ][ 2 ] ; int md[ R5 ], tp[ R5 ] ;
        for ( int i=0; i<R5; i++ ) {
            u[i][0] = GetRotYVector( w[1], 2*PI/R5 * i ) ;
            u[i][1] = GetRotYVector( w[2], 2*PI/R5 * i ) ;
            md[i] = GetRotYVector( mid, 2*PI/R5 * i ) ;
            tp[i] = GetRotYVector( top, 2*PI/R5 * i ) ;
        }
        double t = GetLinearTime( v ) ;
        int n = 0 ;
        for ( int i=0; i<S12; i++ ) {
            for ( int j=0; j<R5; j++ ) {
                int mdt = GetInternallyDividingVector( tp[j], md[j], t ) ;
                int ut0 = GetInternallyDividingVector( tp[j], u[j][0], t ) ;
                int ut1 = GetInternallyDividingVector( tp[j], u[j][1], t ) ;
                setPolygonVector( 
                    Q21[n][i][2*j], mdt, ut0, tp[j], mdt
                ) ;
                setPolygonVector( 
                    Q21[n][i][2*j+1], mdt, tp[j], ut1, mdt
                ) ;
                setPolygonVector( L11[n][i][j][0], ut0, tp[j] ) ;
                setPolygonVector( L11[n][i][j][1], ut1, tp[j] ) ;
                setPolygonVector( L11[n][i][j][2], ut0, ut1 ) ;
            }
        }
    }

    SetTRange( v, o, STEP ) ;
    if ( Motion( v ) ) {
        double prad = l ;
        for ( int i=0; i<length( Q11 )[2]; i++ ) {
            SetPolygons5gon( Q11, Q12, i, prad ) ;
        }
    }

    SetTRange( v, o, 2*unit ) ;
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int opacity = OPACITY[0] * ( 1 - t ) + OPACITY[1] * t ;
        float emissive = OPTION0[0] * ( 1 - t ) + OPTION1[0] * t ;
        float ambient = OPTION0[3] * ( 1 - t ) + OPTION1[3] * t ;
        float sref = OPTION0[4] * ( 1 - t ) + OPTION1[4] * t ;
        float sangle = OPTION0[5] * ( 1 - t ) + OPTION1[5] * t ;
        int color[ 3 ] ;
        for ( int i=0; i<length( Q21 )[2]; i++ ) {
            for ( int j=0; j<length( Q21 )[1]; j++ ) {
                for ( int n=0; n<3; n++ ) {
                    color[n] = COLOR[j][n] ;
                }
                for ( int k=0; k<length( Q21 )[0]; k++ ) {
                    SetPolygonColor( Q21[i][j][k], color, opacity ) ;
                    setPolygonEmissive( Q21[i][j][k], emissive ) ;
                    setPolygonAmbient( Q21[i][j][k], ambient ) ;
                    setPolygonSpecular( Q21[i][j][k], sref, sangle ) ;
                }
            }
        }
    }

    int stop = newVector( v ) ;

    if ( GET_TIME ) {
        T0 = T ;
        GET_TIME = false ;
    }

    SetTRangeAbsolutely( v, T0, T0 + unit ) ;

    if ( FORMER_OPACITY_INDEX != OPACITY_INDEX ) {
        if ( Motion( v ) ) {
            double t = GetLinearTime( v ) ;
            float r0 = FORMER_OPACITY_INDEX / 2.0 ;
            float r1 = OPACITY_INDEX / 2.0 ;
            int opacity0 = OPACITY[0] * r0 + OPACITY[1] * ( 1 - r0 ) ;
            int opacity1 = OPACITY[0] * r1 + OPACITY[1] * ( 1 - r1 ) ;
            int opacity = opacity0 * ( 1 - t ) + opacity1 * t ;
            float emissive0 = OPTION0[0] * r0 + OPTION1[0] * ( 1 - r0 ) ;
            float emissive1 = OPTION0[0] * r1 + OPTION1[0] * ( 1 - r1 ) ;
            float emissive = emissive0 * ( 1 - t ) + emissive1 * t ;
            float ambient0 = OPTION0[3] * r0 + OPTION1[3] * ( 1 - r0 ) ;
            float ambient1 = OPTION0[3] * r1 + OPTION1[3] * ( 1 - r1 ) ;
            float ambient = ambient0 * ( 1 - t ) + ambient1 * t ;
            float sref0 = OPTION0[4] * r0 + OPTION1[4] * ( 1 - r0 ) ;
            float sref1 = OPTION0[4] * r1 + OPTION1[4] * ( 1 - r1 ) ;
            float sref = sref0 * ( 1 - t ) + sref1 * t ;
            float sangle0 = OPTION0[5] * r0 + OPTION1[5] * ( 1 - r0 ) ;
            float sangle1 = OPTION0[5] * r1 + OPTION1[5] * ( 1 - r1 ) ;
            float sangle = sangle0 * ( 1 - t ) + sangle1 * t ;
            int color[ 3 ] ;
            for ( int i=0; i<length( Q21 )[2]; i++ ) {
                for ( int j=0; j<length( Q21 )[1]; j++ ) {
                    for ( int n=0; n<3; n++ ) {
                        color[n] = COLOR[j][n] ;
                    }
                    for ( int k=0; k<length( Q21 )[0]; k++ ) {
                        SetPolygonColor( Q21[i][j][k], color, opacity ) ;
                        SetPolygonColor( Q22[i][j][k], color, opacity ) ;
                        SetPolygonColor( Q23[i][j][k], color, opacity ) ;
                        setPolygonEmissive( Q21[i][j][k], emissive ) ;
                        setPolygonEmissive( Q22[i][j][k], emissive ) ;
                        setPolygonEmissive( Q23[i][j][k], emissive ) ;
                        setPolygonAmbient( Q21[i][j][k], ambient ) ;
                        setPolygonAmbient( Q22[i][j][k], ambient ) ;
                        setPolygonAmbient( Q23[i][j][k], ambient ) ;
                        setPolygonSpecular( Q21[i][j][k], sref, sangle ) ;
                        setPolygonSpecular( Q22[i][j][k], sref, sangle ) ;
                        setPolygonSpecular( Q23[i][j][k], sref, sangle ) ;
                    }
                }
            }
            if ( t == a ) {
                FORMER_OPACITY_INDEX = OPACITY_INDEX ;
                TURN_GET_TIME = false ;
            }
        }
    } else {
        if ( Motion( v ) ) {
            double t = GetLinearTime( v ) ;
            double p0ini, p1ini ;
            if ( Moment( v ) ) {
                p0ini = getComponentValue( SLIDER[0] ) ;
                p1ini = getComponentValue( SLIDER[1] ) ;
            }
            double p0 = p0ini * ( 1 - t ) ;
            double p1 = p1ini * ( 1 - t ) ;
            setComponentValue( SLIDER[0], p0 ) ;
            setComponentValue( SLIDER[1], p1 ) ;
            if ( t == a ) {
                TURN_GET_TIME = false ;
                int n = 0 ;
                if ( LIMIT ) {
                    for ( int i=0; i<length( L12 )[2]; i++ ) {
                        for ( int j=0; j<length( L12 )[1]; j++ ) {
                            removePolygon( L12[n][i][j][3], RENDERER, CD[n][i] ) ;
                        }
                    }
                } else {
                    for ( int i=0; i<length( L12 )[2]; i++ ) {
                        for ( int j=0; j<length( L12 )[3]; j++ ) {
                            addPolygon( L12[n][i][j][3], RENDERER, CD[n][i] ) ;
                        }
                    }
                }
            }
        }
    }

    setVector( v, stop ) ;

}

inserted by FC2 system