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

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


encode Shift_JIS ;


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




void main( string args[] ){


    TITLE = " 二十・十二面体の星型化" ; 

    hide();
    Set3DGraphics( a );
    SetLights();
    SetCoordinates();
    //SetAxes();
    SetElements();
    PrepareStage();


/* animation loop  */

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

    while ( KEEP_LOOP ){ 

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

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

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

        PaintGraphics( loop_periodic_time );

        if ( SAVE_A_PICTURE ) {
            SavePicture( picture_save_number );
        }

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


    exit();


}




/* import ここから */


/* NUMERIC */

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

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


/* set_3D_graphics_upleft */

string TITLE = "1110_cuboctahedron_stellation_00" ;
int MAIN_GRAPHICS, MAIN_WINDOW, MAIN_DISPLAY_LABEL, RENDERER ;
int WIDTH, HEIGHT, WINDOW_POSITION_X ;
{
    int n = 256 ;
    WIDTH = n * 2.5 ;
    HEIGHT = n * 2.5 ;
    WINDOW_POSITION_X = 70 ;
}

void Set3DGraphics() {

    int backgroundcolor = 255 * a ;
    int bgred = backgroundcolor ;
    int bggreen = backgroundcolor ;
    int bgblue = backgroundcolor ;
    int framewidth_x = 14 ;
    int framewidth_y = 39 ;
    int bgalpha = 255 ;

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

void Set3DGraphics( float color ) {

    int backgroundcolor = 255 * color ;
    int bgred = backgroundcolor ;
    int bggreen = backgroundcolor ;
    int bgblue = backgroundcolor ;
    int framewidth_x = 14 ;
    int framewidth_y = 39 ;
    int bgalpha = 255 ;

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


/* GUICOMPONENTS */


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

void onKeyDown( int id, string key ){

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

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

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

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


/* FUNCTIONS */


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

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

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

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

// 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 ;
}

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

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

// vectorの差を返す
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の定数倍を返す
int GetScaleVector( int v, double x ) {

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

int GetCoordinateOriginVector( int cd ) {

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

// 重心を取得
int GetCenterOfGravityVector( int v[ ] ) {

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

double[ ] getCenterOfGravity( int v[ ] ) {

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

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

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

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

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

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

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

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

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

void SetCoordinateEulerAngleVector( int cd, int v ) {

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

double[ ] GetCoordinateEulerAngle( int cd ) {

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

int GetCoordinateEulerAngleVector( int cd ) {

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

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

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

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

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

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

void SetSphereSize( int sp, double rad ) {

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


/* 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 ;
}


/* 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 ;
}


/* import ここまで */




/* set lights */


int LIGHT1 = newLight( o, o, o, o ) ;
int LIGHT2 = newLight( o, o, o, o ) ;
int AMBIENT_LIGHT;

void SetLights() {
    float power = 0.4 ;
    SetParallelLight( LIGHT1, 4.0, 10.0, 10.0, power, RENDERER );
    power = 0.7 ;
    SetParallelLight( LIGHT2, -8.0, -12.0, 6.0, power, RENDERER );
    power = 0.3 ;
    SetAmbientLight ( AMBIENT_LIGHT, o, o, o, power, RENDERER );
}




/* create elements (polygnのみ) */


void SetElements() {

//    SetElementColors();
    SetElementOptions();
    AddElements();
}


int NG = 1 ; // number of polygon groups
int SD = 12 ; // dodecahderon symmetry
int SI = 20 ; // icosahedron symmetry
int SP = 5 ; // pentagon symmetry
int ST = 3 ; // triangle symmetry


int TP[ SD ][ SP ]; // 二十・十二面体正五角形の1/5
for ( int sd=0; sd<SD; sd++ ) {
    for ( int sp=0; sp<SP; sp++ ) {
        TP[sd][sp] = newTrianglePolygon( O, O, O ) ;
    }
}


int QP[ SD ][ SP ]; // TP拡張部分
for ( int sd=0; sd<SD; sd++ ) {
    for ( int sp=0; sp<SP; sp++ ) {
        QP[sd][sp] = newQuadranglePolygon( O, O, O, O ) ;
    }
}


int TT[ SI ][ 1 ]; // 二十・十二面体正三角形の1/3
for( int si=0; si<SI; si++ ) {
    TT[si][0] = newTrianglePolygon( O, O, O ) ;
}


int QT[ SI ][ ST ]; // TT拡張部分
for( int si=0; si<SI; si++ ) {
    for ( int st=0; st<ST; st++ ) {
        QT[si][st] = newQuadranglePolygon( O, O, O, O ) ;
    }
}


void SetTrianglesForPentagons2012( int triangle[ ][ ], double y ) {

    int u[ ] = GetVectorsPentagon2012( y ) ;
    for ( int sd=0; sd<SD; sd++ ) {
        for ( int sp=0; sp<SP; sp++ ) {
            int i = sp ;
            int j = sp + 1 ; if ( i == SP - 1 ) { j = 0 ; }
            setPolygonVector( triangle[sd][sp], O, u[i], u[j] );
        }
    }
}


void AppendTrianglesToPentagons2012( int triangle[ ][ ], double y, double h ) {

    int u[ ] = GetVectors5Triangles( y, h ) ;
    for ( int sd=0; sd<SD; sd++ ) {
        for ( int sp=0; sp<SP; sp++ ) {
            int i = sp ;
            int j = sp + 1 ; if ( i == SP - 1 ) { j = 0 ; }
            setPolygonVector( triangle[sd][sp], u[SP+sp], u[j], u[i] );
        }
    }
}


void AppendTrapeziumsToPentagons2012( int quadrangle[ ][ ], double y, double h ) {

    int u[ ] = GetVectors5Trapeziums( y, h ) ;
    for ( int sd=0; sd<SD; sd++ ) {
        for ( int sp=0; sp<SP; sp++ ) {
            int i1 = sp + 1 ; if ( i1 == SP ) { i1 = 0 ; }
            int i2 = sp  ;
            int i3 = SP + 2*sp ;
            int i4 = i3 + 1 ;
            setPolygonVector( quadrangle[sd][sp], u[i1], u[i2], u[i3], u[i4] );
        }
    }
}


void SetTriangles2012( int triangle[ ][ ], double y ) {

    int u[ ] = GetVectorsTriangle2012( y ) ;
    for ( int si=0; si<SI; si++ ) {
        setPolygonVector( triangle[si][0], u[0], u[1], u[2] );
    }
}


void AppendTrianglesToTriangles2012( int triangle[ ][ ], double y, double h ) {

    int u[ ] = GetVectors3Triangles( y, h ) ;
    for ( int si=0; si<SI; si++ ) {
        for ( int st=0; st<ST; st++ ) {
            int i = st ;
            int j = st + 1 ; if ( i == ST - 1 ) { j = 0 ; }
            setPolygonVector( triangle[si][st], u[ST+st], u[j], u[i] );
        }
    }
}


void AppendTrapeziumsToTriangles2012( int quadrangle[ ][ ], double y, double h ) {

    int u[ ] = GetVectors3Trapeziums( y, h ) ;
    for ( int si=0; si<SI; si++ ) {
        for ( int st=0; st<ST; st++ ) {
            int i1 = st + 1 ; if ( i1 == ST ) { i1 = 0 ; }
            int i2 = st  ;
            int i3 = ST + 2*st ;
            int i4 = i3 + 1 ;
            setPolygonVector( quadrangle[si][st], u[i1], u[i2], u[i3], u[i4] );
        }
    }
}


// 正五角形面心が(o, y, o)である二十・十二面体の正五角形頂点の面心を始点とする位置ベクトルを計算
int[ ] GetVectorsPentagon2012( double y ) {

    int v[ SP ];
    int v0 = newVector( o, o, ( Gld - a ) * y ) ;
    v[0] = newVector( v0 ) ;
    for ( int sp=1; sp<SP; sp++ ) {
        v[sp] = newVector( v0 );
        rotYVector( v[sp], 2*PI/SP * sp );
    }
    return v ;
}


// inrad y の二十・十二面体正五角形に付け足す高さhの三角形の頂点
int[ ] GetVectors5Triangles( double y, double h ) {

    int w[ SP + SP ];
    int v0 = newVector( o, o, ( Gld - a ) * y ) ;
    double r = y/2 + h ; // 正五角形面心から付け足す二等辺三角形天頂点への距離
    int v1 = newVector( ( 3 - Gld )^0.5/2 * r, o, Gld/2 * r );
    w[0] = newVector( v0 ) ;
    w[SP] = newVector( v1 );
    for ( int sp=1; sp<SP; sp++ ) {
        w[sp] = newVector( v0 );
        rotYVector( w[sp], 2*PI/SP * sp );
        w[SP+sp] = newVector( v1 );
        rotYVector( w[SP+sp], 2*PI/SP * sp );
    }
    return w ;
}


// inrad y の二十・十二面体正五角形に付け足す高さhの台形の頂点
int[ ] GetVectors5Trapeziums( double y, double h ) {

    int w[ SP + 2*SP ];
    int v0 = newVector( o, o, ( Gld - a ) * y ) ; // 2012pentagonの第0頂点
    int v1 = newVector( h * 2 * ( 3 - Gld )^(-0.5), o, ( Gld - a ) * y );
    int v2 = newVector( -h * 2 * ( 3 - Gld )^(-0.5), o, ( Gld - a ) * y );
    rotYVector( v2, 2*PI/SP );
    w[0] = newVector( v0 ) ;
    w[SP] = newVector( v1 );
    w[SP+1] = newVector( v2 );
    for ( int sp=1; sp<SP; sp++ ) {
        w[sp] = newVector( v0 );
        rotYVector( w[sp], 2*PI/SP * sp );
        w[SP+2*sp] = newVector( v1 );
        rotYVector( w[SP+2*sp], 2*PI/SP * sp );
        w[SP+2*sp+1] = newVector( v2 );
        rotYVector( w[SP+2*sp+1], 2*PI/SP * sp );
    }
    return w ;
}


// 正五角形面心が(o, y, o)である二十・十二面体の正三角形頂点の面心を始点とする位置ベクトルを計算
int[ ] GetVectorsTriangle2012( double y ) {

    int v[SI];
    double outr = ( Gld - a ) * y * ( ( 3 - Gld ) / 3 )^0.5 ;
    int v0 = newVector( o, o, outr ) ;
    v[0] = newVector( v0 ) ;
    for ( int st=1; st<ST; st++ ) {
        v[st] = newVector( v0 );
        rotYVector( v[st], 2*PI/ST * st );
    }
    return v ;
}


// inrad y の二十・十二面体正三角形に付け足す高さhの三角形の頂点
int[ ] GetVectors3Triangles( double y, double h ) {

    int w[ ST + ST ];
    double outr = ( Gld - a ) * y * ( ( 3 - Gld ) / 3 )^0.5 ;
    int v0 = newVector( o, o, outr ) ;
    double r = outr/2 + h ; // 正三角形面心から付け足す二等辺三角形天頂点への距離
    int v1 = newVector( Plt/2 * r, o, r/2 );
    w[0] = newVector( v0 ) ;
    w[ST] = newVector( v1 );
    for ( int st=1; st<ST; st++ ) {
        w[st] = newVector( v0 );
        rotYVector( w[st], 2*PI/ST * st );
        w[ST+st] = newVector( v1 );
        rotYVector( w[ST+st], 2*PI/ST * st );
    }
    return w ;
}


// inrad y の二十・十二面体正三角形に付け足す高さhの台形の頂点
int[ ] GetVectors3Trapeziums( double y, double h ) {

    int w[ ST + 2*ST ];
    double outr = ( Gld - a ) * y * ( ( 3 - Gld ) / 3 )^0.5 ;
    int v0 = newVector( o, o, outr ) ; // 2012triangleの第0頂点
    int v1 = newVector( h * 2 * IPlt, o, outr );
    int v2 = newVector( -h * 2 * IPlt, o, outr );
    rotYVector( v2, 2*PI/ST );
    w[0] = newVector( v0 ) ;
    w[ST] = newVector( v1 );
    w[ST+1] = newVector( v2 );
    for ( int st=1; st<ST; st++ ) {
        w[st] = newVector( v0 );
        rotYVector( w[st], 2*PI/ST * st );
        w[ST+2*st] = newVector( v1 );
        rotYVector( w[ST+2*st], 2*PI/ST * st );
        w[ST+2*st+1] = newVector( v2 );
        rotYVector( w[ST+2*st+1], 2*PI/ST * st );
    }
    return w ;
}


int[ ] ColorD( int sd ) {

    int c[ 3 ];
    if ( ( sd == 0 ) || ( sd == 8 ) || ( sd == 10 ) ) {
        c = Color( 255, 5, 20 ) ;
    } else if ( ( sd == 1 ) || ( sd == 7 ) || ( sd == 9 ) ) {
        c = Color( 255, 200, 5 ) ;
    } else if ( ( sd == 2 ) || ( sd == 4 ) || ( sd == 11 ) ) {
        c = Color( 230, 255, 20 ) ;
    } else if ( ( sd == 3 ) || ( sd == 5 ) || ( sd == 6 ) ) {
        c = Color( 20, 255, 20 ) ;
    }
    return c ;
}

int[ ] ColorI( int si ) {

    int c[ 3 ];
    if ( ( si == 0 ) || ( si == 8 ) || ( si == 12 ) || ( si == 15 ) ) {
        c = Color( 20, 255, 200 ) ;
    } else if ( ( si == 1 ) || ( si == 9 ) || ( si == 13 ) || ( si == 16 ) ) {
        c = Color( 20, 80, 255 ) ;
    } else if ( ( si == 2 ) || ( si == 5 ) || ( si == 14 ) || ( si == 17 ) ) {
        c = Color( 100, 20, 255 ) ;
    } else if ( ( si == 3 ) || ( si == 6 ) || ( si == 10 ) || ( si == 18 ) ) {
        c = Color( 200, 10, 255 ) ;
    } else if ( ( si == 4 ) || ( si == 7 ) || ( si == 11 ) || ( si == 19 ) ) {
        c = Color( 255, 5, 125 ) ;
    }
    return c ;
}

int CL1[ 3 ] = Color( 20, 60, 255 ) ;
int CL2[ 3 ] = Color( 200, 250, 240 ) ;
int CL3[ 3 ] = Color( 60, 200, 255 ) ;
int CL4[ 3 ] = Color( 255, 40, 160 ) ;
int CL5[ 3 ] = Color( 20, 255, 20 ) ;
int CL6[ 3 ] = Color( 230, 230, 20 ) ;
int CL7[ 3 ] = Color( 255, 40, 160 ) ;

N = 2 ; int OPACITY[ N ] = 255 ;
OPACITY[ 1 ] = 50 ;

void SetElementColors( int polygon[ ][ ], int n, int color[ ], int opacity ) {

    int len[ ] = length( polygon ) ;
    for( int i=0; i<len[0]; i++ ) {
        SetPolygonColor( polygon[n][i], color, opacity );
    }
}


float OPTION[ 6 ];
{
    float emissive = o ; 
    float diffractive = 0.6 ; 
    float diffuse = 0.9 ; 
    float ambient = 0.3 ;
    float specularintensity = 0.7 , specularangle = 0.5 ; 

    OPTION[0] = emissive ;
    OPTION[1] = diffractive ;
    OPTION[2] = diffuse ;
    OPTION[3] = ambient ;
    OPTION[4] = specularintensity ; OPTION[5] = specularangle ;
}

void SetElementOptions() {

    for ( int sd=0; sd<SD; sd++ ) {
        for ( int sp=0; sp<SP; sp++ ) {
            setPolygonCull( TP[sd][sp], false, false );
            SetPolygonSurface( TP[sd][sp], OPTION );
            setPolygonCull( QP[sd][sp], false, false );
            setPolygonSortOffset( QP[sd][sp], 0.1*l );
            SetPolygonSurface( QP[sd][sp], OPTION );
        }
    } 
    for ( int si=0; si<SI; si++ ) {
        setPolygonCull( TT[si][0], false, false );
        SetPolygonSurface( TT[si][0], OPTION );
        for ( int st=0; st<ST; st++ ) {
            setPolygonCull( QT[si][st], false, false );
            setPolygonSortOffset( QT[si][st], 0.1*l );
            SetPolygonSurface( QT[si][st], OPTION );
        }
    } 
}


void AddElements() {

    for ( int sd=0; sd<SD; sd++ ) {
        for ( int sp=0; sp<SP; sp++ ) {
            addPolygon( TP[sd][sp], RENDERER, CD[sd] );
            addPolygon( QP[sd][sp], RENDERER, CD[sd] );
        }
    } 
    for ( int si=0; si<SI; si++ ) {
        addPolygon( TT[si][0], RENDERER, CI[si] );
        for ( int st=0; st<ST; st++ ) {
            addPolygon( QT[si][st], RENDERER, CI[si] );
        }
    } 
}




/* set coordinates */


int COORD[ 4 ];
int CD[ SD ];
int CI[ SI ];
for ( int i=0; i<length( COORD ); i++ ) {
    COORD[i] = newCoordinate() ;
}
for ( int sd=0; sd<SD; sd++ ) {
    CD[sd] = newCoordinate() ;
}
for ( int si=0; si<SI; si++ ) {
    CI[si] = newCoordinate() ;
}

void SetCoordinates() {

    PileCoordinate( COORD, RENDERER );
    for ( int sd=0; sd<SD; sd++ ) {
        addCoordinate( CD[sd], RENDERER, COORD[0] );
    }
    for ( int si=0; si<SI; si++ ) {
        addCoordinate( CI[si], RENDERER, COORD[0] );
    }
}

// y軸がnormal vector方向、z軸上にv[0]
void SetCoordinateSymmetry12( int cd[ ], double inrad ) {

    int ov[ SD/2 ] , av[ SD/2 ] ;
    int ax = newVector( o, Gld, a ) ;
    int n;
    for ( int sd=0; sd<SD/2; sd++ ) {
        ov[sd] = newVector() ;
        av[sd] = newVector() ;
        SetCoordinateEulerAngleVector( cd[sd], O );
        setCoordinateOrigin( cd[sd], o, inrad, o );
        if ( sd >= 1 ) {
            rotCoordinate( cd[sd], PI, ax );
            if ( sd >=2 ) {
                rotYCoordinate( cd[sd], 2*PI/SP * ( sd - 1 ) );
            }
        }
        GetCoordinateLocationAttitude( ov[sd], av[sd], cd[sd] );
        if ( sd == 0 ) {
            n = SD-1 ;
        } else if ( sd == 3 ) {
            n = 6 ;
        } else if ( sd == 2 ) {
            n = 7 ;
        } else if ( sd == 1 ) {
            n = 8 ;
        } else if ( sd == 5 ) {
            n = 9 ;
        } else {
            n = 10 ;
        }
        SetCoordinateLocationAttitude( cd[n], ov[sd], av[sd] );
        rotXCoordinate( cd[n], PI );
    }
}


// y軸がnormal vector方向、z軸上にv[0]。inradはdodecahedronの
void SetCoordinateSymmetry20( int cd[ ], double inrad ) {

    double r = inrad * ( ( Gld + 2 ) / 3 )^0.5 ;
    double rotangle = -atan( 2 * ( 2 - Gld ) ) ;
    int ov[ SI/2 ] , av[ SI/2 ] ;
    int ax = newVector( o, a, 2*a ) ;
    int n;
    for ( int si=0; si<SI/2; si++ ) {
        ov[si] = newVector() ;
        av[si] = newVector() ;
        SetCoordinateLocationAttitude( cd[si], O, O );
        rotYCoordinate( cd[si], -PI/3 );
        rotXCoordinate( cd[si], rotangle );
        walkCoordinate( cd[si], o, r, o );
        if ( si <= SP-1 ) {
            rotYCoordinate( cd[si], 2*PI/SP * ( si - 2 ) );
        } else {
            rotYCoordinate( cd[si], -2*PI/SP * 2 );
            rotCoordinate( cd[si], -2*PI/SP, ax );
            if ( si >= SP+1 ) {
                rotYCoordinate( cd[si], 2*PI/SP * ( si - SP ) );
            }
        }
        GetCoordinateLocationAttitude( ov[si], av[si], cd[si] );
        if ( si == 2 ) {
            n = 15 ;
        } else if ( si == 1 ) {
            n = 16 ;
        } else if ( si == 0 ) {
            n = 17 ;
        } else if ( si == 4 ) {
            n = 18 ;
        } else if ( si == 3 ) {
            n = 19 ; 
        } else if ( si == 7 ) {
            n = 10 ;
        } else if ( si == 6 ) {
            n = 11 ;
        } else if ( si == 5 ) {
            n = 12 ;
        } else if ( si == 9 ) {
            n = 13 ;
        } else if ( si == 8 ) {
            n = 14 ;
        }
        SetCoordinateLocationAttitude( cd[n], ov[si], av[si] );
        rotXCoordinate( cd[n], PI );
    }
}




/* set axes */


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

void SetAxes() {

    addModel( AXIS[0], RENDERER, COORD[0] );
//    addModel( AXIS[2], RENDERER, CI[0] );
//    addModel( AXIS[4], RENDERER, CI[1] );
//    addModel( AXIS[6], RENDERER, CI[2] );
    addModel( AXIS[8], RENDERER, CI[0] );
}




/* prepare stage */


double CAMERA_ORIGIN_Z = 5.6 * 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 ;

int COUNT = 0 ;
int PAINT_FREQUENCY = 20 ;
int PICTURE_NUMBER = 0 ; 
int PICTURE_END_NUMBER = 2000 ;

double T = o ;
double STEP, TIME_FLOW ;
{
    TIME_FLOW = 1.0 ;
    STEP = TIME_FLOW / PAINT_FREQUENCY ;
}




/* create GUI elements */


int SETTING_WINDOW; 

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

int CHECK_BOX[ 1 ];
N = length( CHECK_BOX ) ; string CHECK_TEXT[ N ] ;
bool HALF_INVISIBLE;

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 lensetx[ ] = length( SELECT_TEXT ) ;
    N = lensetx[0] ;
}
// color pattern [ ], 2,9
bool COLOR_PATTERN[ N ] = false ; COLOR_PATTERN[0] = true ; // 初期値
bool TURN[ N ] = false ; TURN[0] = true ;

{
    SELECT_TITLE[0] = "色パターン選択" ;
    SELECT_TEXT[0][0] = "多角形の種類毎の塗り分け" ;
    SELECT_TEXT[0][1] = "9色で塗り分け" ;
    SELECT_TEXT[0][2] = "二十・十二面体と星型化部分の塗り分け" ;
    CHECK_TEXT[0] = "芯以外を透明化" ;
    SLIDER_TEXT[0] = "二十・十二面体の正五角形を広げる" ; 
    SLIDER_TEXT[1] = "二十・十二面体の正三角形を広げる" ; 
}

void CreateGuiElements() {

    int nsell = length( SELECT ) ; int nsel = nsell ;
    int nsldl = length( SLIDER ) ; int nsld = nsldl ;
    int lx = 15 , lw = 350 ; 
    int lh = 15 ; int lyspace = 15 ;
    int sliderx = lx , sliderw = lw, sliderh = lh , slideryspace = 5 ;
    int sliderlabely[ nsldl ] ; int slidery[ nsld ] ;
    int selectx = lx , selectw = lw/2 + 50 , selecth = 20 , selectyspace = 5 ;
    int selectlabely[ nsell ] ; int selecty[ nsel ] ;

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

    int wx = WINDOW_POSITION_X + WIDTH + 12 ;
    int wy = 0 ; int framewidth_y = 39 ;
    int ww = lw + 40 ;
    int wh = slidery[nsld-1] + 70 ;

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

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

        // check box (select field の直ぐ横)
        CHECK_BOX[0] = newCheckBox ( 
                            selectw + 20, selecty[0], lw - selectw, selecth, 
                            CHECK_TEXT[0], false
                        ) ;
        addComponent( CHECK_BOX[0], SETTING_WINDOW );

        // slider
        for ( int i=0; i<nsld; i++ ) {
            LABEL_SLIDER[i] = newTextLabel( 
                                    lx, sliderlabely[i], lw, lh, SLIDER_TEXT[i] 
                                );
            addComponent( LABEL_SLIDER[i], SETTING_WINDOW );
            SLIDER[i] = newHorizontalSlider( sliderx, slidery[i], sliderw, sliderh, o );
            addComponent( SLIDER[i], SETTING_WINDOW );
        }
    }

    paintComponent( SETTING_WINDOW );
}




/* event handlers */


void onSliderMove( int id, double value ) {

    double h0pentagon = l/2 ;
    double h0triangle = ( Gld - 1 ) * l * ( ( 3 - Gld ) / 3 )^0.5 / 2 ;
    double h12hedron = ( 7.0/2 - 2*Gld ) * l ;
    double h20hedron = 3*h0triangle ;

    if ( id == SLIDER[0] ) {

        int n = 0 ;
        P[n] = value;
        AppendTrapeziumsToPentagons2012( QP, l, h12hedron * P[n] );
        if ( P[n] < a/100 ) {
            SLIDER_TEXT[n] = "二十・十二面体の正五角形を広げる" ; 
        } else if ( P[n] < 99*a/100 ) {
            int p = 100*P[n] ;
            SLIDER_TEXT[n] = "星型化" + p + "%" ; 
        } else {
            SLIDER_TEXT[n] = "正十二面体(星型化100%)" ; 
        }
        setComponentText( LABEL_SLIDER[n], SLIDER_TEXT[n] );
        paintComponent( LABEL_SLIDER[n] );

    } else if ( id == SLIDER[1] ) {

        int n = 1 ;
        P[n] = value ;
        AppendTrapeziumsToTriangles2012( QT, l, h20hedron * P[n] );
        if ( P[n] < a/100 ) {
            SLIDER_TEXT[n] = "二十・十二面体の正三角形を広げる" ; 
        } else if ( P[n] < 99*a/100 ) {
            int p = 100*P[n] ;
            SLIDER_TEXT[n] = "星型化" + p + "%" ; 
        } else {
            SLIDER_TEXT[n] = "正二十面体(星型化100%)" ; 
        }
        setComponentText( LABEL_SLIDER[n], SLIDER_TEXT[n] );
        paintComponent( LABEL_SLIDER[n] );
    }
}


void onSelectFieldClick( int id, string text ){

    if ( id == SELECT[0] ) {

        if ( text == SELECT_TEXT[0][0] ) {

            if ( !TURN[0] ) {
                TURN = false ;
                COLOR_PATTERN[0] = true ;
                TURN[0] = true ;
                GET_TIME = true ;
                TURN_GET_TIME = true ;
            }

        } else if ( text == SELECT_TEXT[0][1] ) {

            if ( !TURN[1] ) {
                TURN = false ;
                COLOR_PATTERN[1] = true ;
                TURN[1] = true ;
                GET_TIME = true ;
                TURN_GET_TIME = true ;
            }

        } else if ( text == SELECT_TEXT[0][2] ) {

            if ( !TURN[2] ) {
                TURN = false ;
                COLOR_PATTERN[2] = true ;
                TURN[2] = true ;
                GET_TIME = true ;
                TURN_GET_TIME = true ;
            }
        }
    }
}


void onCheckBoxClick( int id , bool state ) {

    if ( id == CHECK_BOX[0] ) {

        HALF_INVISIBLE = state ;
        int opacity ;
        float ref, angle ;
        if ( HALF_INVISIBLE ) {
            opacity = OPACITY[1] ;
            ref = 0.1 ;
            angle = 1.5 ;
        } else {
            opacity = OPACITY[0] ;
            ref = OPTION[4] ;
            angle = OPTION[5] ;
        }
        int colorqd[ 3 ] , colorqi[ 3 ] ;
        for ( int i=0; i<SI; i++ ) {
            if ( COLOR_PATTERN[0] ) {
                colorqd = CL3 ;
                colorqi = CL4 ;
            }
            if ( COLOR_PATTERN[1] ) {
                colorqd = ColorD( i ) ;
                colorqi = ColorI( i ) ;
            }
            if ( COLOR_PATTERN[2] ) {
                colorqd = CL2 ;
                colorqi = CL2 ;
            }
            if ( i < SD ) {
                SetElementColors( QP, i, colorqd, opacity );
                SetElementColors( QT, i, colorqi, opacity );
                for ( int sp=0; sp<SP; sp++ ) {
                    setPolygonSpecular( QP[i][sp], ref, angle );
                }
                for ( int st=0; st<ST; st++ ) {
                    setPolygonSpecular( QT[i][st], ref, angle );
                }
            } else {
                SetElementColors( QT, i, colorqi, opacity );
                for ( int st=0; st<ST; st++ ) {
                    setPolygonSpecular( QT[i][st], ref, angle );
                }
            }
        }
    }
}



/* forward motion */


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

void ForwardMotion() {

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

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

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


int SO[ SD+SI ]; // system origin point
int SA[ SD+SI ]; // system Euler Angle
int RC[ SD+SI ]; // rotation center vector
int AX[ SD+SI ]; // rotation axis vector
for ( int i=0; i<SD+SI; i++ ) {
    SO[i] = newVector() ;
    SA[i] = newVector() ;
    RC[i] = newVector() ;
    AX[i] = newVector() ;
}
int G = newVector() ; // center of gravity
double T0 = -100.0 ;

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 d = 1.0 / 3 ; // 時間の単位
    double h0pentagon = l/2 ;
    double h0triangle = ( Gld - 1 ) * l * ( ( 3 - Gld ) / 3 )^0.5 / 2 ;
    double h12hedron = ( 7.0/2 - 2*Gld ) * l ;
    double h20hedron = 3*h0triangle ;

    setCoordinateEulerAngle( COORD[3], o, PI/2 -2*atan( Gld-1 ), o );

    SetTRangeAbsolutely( v, start_t, start_t + STEP );
    if ( Moment( v ) ) {
        SetCoordinateSymmetry12( CD, l );
        SetCoordinateSymmetry20( CI, l );
        for ( int sd=0; sd<SD; sd++ ) {
            SetElementColors( TP, sd, CL1, OPACITY[0] );
            SetElementColors( QP, sd, CL2, OPACITY[1] );
        }
        for ( int si=0; si<SI; si++ ) {
            SetElementColors( TT, si, CL1, OPACITY[0] );
            SetElementColors( QT, si, CL2, OPACITY[1] );
        }
        SetTrianglesForPentagons2012( TP, l );
        AppendTrapeziumsToPentagons2012( QP, l, o );
        SetTriangles2012( TT, l );
        AppendTrapeziumsToTriangles2012( QT, l, o );
    }

    SetTRange( v, o, d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendTrapeziumsToPentagons2012( QP, l, h12hedron * t );        
    }

    SetTRange( v, d, d );
    if ( Motion( v ) ) {
        double t =GetLinearTime( v ) ;
        int opacity = OPACITY[1] * ( 1 - t ) + OPACITY[0] * t ;
        for ( int sd=0; sd<SD; sd++ ) {
            SetElementColors( TP, sd, CL1, OPACITY[0] );
            SetElementColors( QP, sd, CL2, opacity );
        }
        for ( int si=0; si<SI; si++ ) {
            SetElementColors( TT, si, CL1, OPACITY[0] );
            SetElementColors( QT, si, CL2, opacity );
        }
    }

    SetTRange( v, d, d );
    if ( Motion( v ) ) {
        double t =GetLinearTime( v ) ;
        int color[ 3 ];
        for ( int sd=0; sd<SD; sd++ ) {
            color = CL1 * ( 1 - t ) + ColorD( sd ) * t ;
            SetElementColors( TP, sd, color, OPACITY[0] );
            color = CL2 * ( 1 - t ) + ColorD( sd ) * t ;
            SetElementColors( QP, sd, color, OPACITY[0] );
        }
        for ( int si=0; si<SI; si++ ) {
            color = CL1 * ( 1 - t ) + ColorI( si ) * t ;
            SetElementColors( TT, si, color, OPACITY[0] );
            color = CL2 * ( 1 - t ) + ColorI( si ) * t ;
            SetElementColors( QT, si, color, OPACITY[0] );
        }
    }

    SetTRange( v, d, d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendTrapeziumsToTriangles2012( QT, l, h20hedron * t );
    }

    SetTRange( v, d, d );
    if ( Motion( v ) ) {
        double t =GetLinearTime( v ) ;
        int color[ 3 ];
        for ( int sd=0; sd<SD; sd++ ) {
            color = ColorD( sd ) * ( 1 - t ) + CL3 * t ;
            SetElementColors( TP, sd, CL3, OPACITY[0] );
            SetElementColors( QP, sd, color, OPACITY[0] );
        }
        for ( int si=0; si<SI; si++ ) {
            color = ColorI( si ) * ( 1 - t ) + CL4 * t ;
            SetElementColors( TT, si, CL4, OPACITY[0] );
            SetElementColors( QT, si, color, OPACITY[0] );
        }
    }

    SetTRange( v, 1*d, 2*d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendTrapeziumsToPentagons2012( QP, l, h12hedron * ( 1 - t ) );
    }


    SetTRange( v, d, d );
    if ( Motion( v ) ) {
        double t =GetLinearTime( v ) ;
        int color[ 3 ];
        for ( int sd=0; sd<SD; sd++ ) {
            color = CL3 * ( 1 - t ) + ColorD( sd ) * t ;
            SetElementColors( TP, sd, color, OPACITY[0] );
            SetElementColors( QP, sd, color, OPACITY[0] );
        }
        for ( int si=0; si<SI; si++ ) {
            color = CL4 * ( 1 - t ) + ColorI( si ) * t ;
            SetElementColors( TT, si, color, OPACITY[0] );
            SetElementColors( QT, si, color, OPACITY[0] );
        }
    }

    SetTRange( v, 1*d, 2*d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendTrapeziumsToTriangles2012( QT, l, h20hedron * ( 1 - t ) );
    }

    SetTRange( v, d, d );
    if ( Motion( v ) ) {
        double t =GetLinearTime( v ) ;
        int color[ 3 ];
        for ( int sd=0; sd<SD; sd++ ) {
            color = ColorD( sd ) * ( 1 - t ) + CL3 * t ;
            SetElementColors( TP, sd, color, OPACITY[0] );
            SetElementColors( QP, sd, color, OPACITY[0] );
        }
        for ( int si=0; si<SI; si++ ) {
            color = ColorI( si ) * ( 1 - t ) + CL4 * t ;
            SetElementColors( TT, si, color, OPACITY[0] );
            SetElementColors( QT, si, color, OPACITY[0] );
        }
    }

    int stop = newVector( v ) ;

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

    SetTRangeAbsolutely( v, T0, T0 + 3*d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        int colortd[ 3 ] , colorqd[ 3 ] , colorti[ 3 ] , colorqi[ 3 ] ;
        int colorinitd[ 3 ] , coloriniqd[ 3 ] , coloriniti[ 3 ] , coloriniqi[ 3 ] ;
        int colorfintd[ 3 ] , colorfinqd[ 3 ] , colorfinti[ 3 ] , colorfinqi[ 3 ] ;
        int opacity;
        if ( HALF_INVISIBLE ) {
            opacity = OPACITY[1] ;
        } else {
            opacity = OPACITY[0] ;
        }
        for ( int i=0; i<SI; i++ ) {
            if ( COLOR_PATTERN[0] && COLOR_PATTERN[1] ) {
                if ( TURN[0] ) {
                    colorinitd = ColorD( i ) ;
                    coloriniqd = ColorD( i ) ;
                    coloriniti = ColorI( i ) ;
                    coloriniqi = ColorI( i ) ;
                    colorfintd = CL3 ;
                    colorfinqd = CL3 ;
                    colorfinti = CL4 ;
                    colorfinqi = CL4 ;
                }
                if ( TURN[1] ) {
                    colorinitd = CL3 ;
                    coloriniqd = CL3 ;
                    coloriniti = CL4 ;
                    coloriniqi = CL4 ;
                    colorfintd = ColorD( i ) ;
                    colorfinqd = ColorD( i ) ;
                    colorfinti = ColorI( i ) ;
                    colorfinqi = ColorI( i ) ;
                }
            }
            if ( COLOR_PATTERN[1] && COLOR_PATTERN[2] ) {
                if ( TURN[1] ) {
                    colorinitd = CL1 ;
                    coloriniqd = CL2 ;
                    coloriniti = CL1 ;
                    coloriniqi = CL2 ;
                    colorfintd = ColorD( i ) ;
                    colorfinqd = ColorD( i ) ;
                    colorfinti = ColorI( i ) ;
                    colorfinqi = ColorI( i ) ;
                }
                if ( TURN[2] ) {
                    colorinitd = ColorD( i ) ;
                    coloriniqd = ColorD( i ) ;
                    coloriniti = ColorI( i ) ;
                    coloriniqi = ColorI( i ) ;
                    colorfintd = CL1 ;
                    colorfinqd = CL2 ;
                    colorfinti = CL1 ;
                    colorfinqi = CL2 ;
                }
            }
            if ( COLOR_PATTERN[2] && COLOR_PATTERN[0] ) {
                if ( TURN[2] ) {
                    colorinitd = CL3 ;
                    coloriniqd = CL3 ;
                    coloriniti = CL4 ;
                    coloriniqi = CL4 ;
                    colorfintd = CL1 ;
                    colorfinqd = CL2 ;
                    colorfinti = CL1 ;
                    colorfinqi = CL2 ;
                }
                if ( TURN[0] ) {
                    colorinitd = CL1 ;
                    coloriniqd = CL2 ;
                    coloriniti = CL1 ;
                    coloriniqi = CL2 ;
                    colorfintd = CL3 ;
                    colorfinqd = CL3 ;
                    colorfinti = CL4 ;
                    colorfinqi = CL4 ;
                }
            }
            colortd = colorinitd * ( 1 - t ) + colorfintd * t ;
            colorqd = coloriniqd * ( 1 - t ) + colorfinqd * t ;
            colorti = coloriniti * ( 1 - t ) + colorfinti * t ;
            colorqi = coloriniqi * ( 1 - t ) + colorfinqi * t ;
            if ( i < SD ) {
                SetElementColors( TP, i, colortd, OPACITY[0] );
                SetElementColors( QP, i, colorqd, opacity );
                SetElementColors( TT, i, colorti, OPACITY[0] );
                SetElementColors( QT, i, colorqi, opacity );
            } else {
                SetElementColors( TT, i, colorti, OPACITY[0] );
                SetElementColors( QT, i, colorqi, opacity );
            }
        }
        if ( t == 1.0 ) {
            TURN_GET_TIME = false ;
            for ( int i=0; i<length( TURN ); i++ ) {
                if ( !TURN[i] ) {
                    COLOR_PATTERN[i] = false ;
                }
            }
        }
    }

    setVector( v, stop ) ;

}

inserted by FC2 system