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

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

encode Shift_JIS ;


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




void main( string args[] ){


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

/* animation Loop  */

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

    while ( KEEP_LOOP ){ 

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

        ForwardMotion();

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

        PaintGraphics( loop_periodic_time );

        if ( SAVE_A_PICTURE ) {
            SavePicture( picture_save_number );
        }

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


    exit();


}




/* import numbers */


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

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




/* import set 3D graphics */

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

void Set3DGraphics() {

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

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




/* import event handlers */


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


void onKeyDown( int id, string key ){

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


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

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

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




/* import functions */


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

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


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

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

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

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


double TurnBump( double x ) {

    return 1.0 - Bump( x ) ;
}


int Parity( int i ) {

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


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

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




/* import routine */


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


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

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

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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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

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

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


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

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


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

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


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

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


int GetCoordinateOriginVector( int cd ) {

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


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

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


double[ ] getCenterOfGravity( int v[ ] ) {

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


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

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

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


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

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

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


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

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


void SetCoordinateEulerAngleVector( int cd, int v ) {

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


double[ ] GetCoordinateEulerAngle( int cd ) {

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


int GetCoordinateEulerAngleVector( int cd ) {

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


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

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

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

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

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


void SetSphereSize( int sp, double rad ) {

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




/* import animation */


double GetLinearTime( int v ) {

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

double GetSmoothTime( int v, double p ) {

    double t0 = getVectorX( v ) ;
    double t1 = getVectorY( v ) ;
    double t;
    if ( T < t0 ) {
        t = 0.0 ;
    } else if ( T < t1 - STEP ) {
        t = ( T - t0 ) / ( t1 - t0 - STEP ) ;
    } else {
        t = 1.0 ;
    }
    double value ;
    if ( p > 0.0 ) {
        if ( t < 0.5 ) {
            double u = 2 * ( 1.0 - t ) - 1.0 ;
            double s = ( 1.0 + p )/( 2*p ) 
                        * ( 1.0 - sqrt( 1.0 - 4*p/( ( 1.0 + p )^2 ) * u ) ) ;
            value = ( 1.0 - sin( PI/2 * s ) ) / 2 ;
        } else {
            double u = 2 * t - 1.0 ;
            double s = ( 1.0 + p )/( 2*p ) 
                        * ( 1.0 - sqrt( 1.0 - 4*p/( ( 1.0 + p )^2 ) * u ) ) ;
            value = ( 1.0 + sin( PI/2 * s ) ) / 2 ;
        }
    } else if ( p == 0.0 ) {
        if( t < 0.5 ) {
            double u = 2 * ( 1.0 - t ) - 1.0 ;
            value = ( 1.0 - sin( PI/2 * u ) ) / 2 ;
        } else {
            double u = 2 * t - 1.0 ;
            value = ( 1.0 + sin( PI/2 * u ) ) / 2 ;
        }
    }
    return value ;
}

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

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

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

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

bool Motion( int v ) {

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

bool Moment( int v ) {

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




/* set lights */


int LIGHT;
int AMBIENT_LIGHT;

void SetLights() {
    float power = 0.9 ;
    SetParallelLight( LIGHT, -4.0, 10.0, 5.0, power );
    power = 0.7 ;
    SetAmbientLight ( AMBIENT_LIGHT, o, o, o, power );
}

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

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

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

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




/* set coordinates */


int COORD[ 2 ], CD[ 1 ] ;
{
    for ( int i=0; i<length( COORD ); i++ ) {
        COORD[i] = newCoordinate() ;
    }
    for ( int i=0; i<length( CD ); i++ ) {
        CD[i] = newCoordinate() ;
    }
}

void SetCoordinates() {

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




/* set axes */


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

void SetAxes() {

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




/* create elements */


void SetElements() {

    SetElementVectors();
    SetElementColors();
    SetElementOptions();
    AddElements();

}


int NG = 1 ; // number of groups
int NQ = 6 ; int QP[ NG ][ NQ ] ; // quadrangle polygon
int NT = 8 ; int TP[ NG ][ NT ] ; // triangle polygon
{
    for ( int n3=0; n3<NG; n3++ ) {

        for ( int i=0; i<NQ; i++ ) {
            QP[0][i] = newQuadranglePolygon( O, O, O, O ) ;
        }

        for ( int i=0; i<NT; i++ ) {
            TP[0][i] = newTrianglePolygon( O, O, O ) ;
        }
    }
}

int VQ[ 4 ], VT[ 3 ] ; // vectors for a polygon
{
    for ( int i=0; i<4; i++ ) {
        VQ[i] = newVector() ;
    }
    for ( int i=0; i<3; i++ ) {
        VT[i] = newVector() ;
    }
}

void SetElementVectors() {

    SetVectors68hedronQuadrangle( VQ );

    SetVectors68hedronTriangle( VT );

    SetPolygons8hedronVertexSymmetry( QP, VQ );

    SetPolygons6hedronVertexSymmetry( TP, VT );
}

void SetVectors68hedronQuadrangle( int v[ ] ) {

    for ( int i=0; i<4; i++ ) {
        setVector( v[i], o, l, l ) ;
        rotYVector( v[i], PI/2 * i );
    }
}

void SetVectors68hedronTriangle( int v[ ] ) {

    setVector( v[0], o, l, l ) ;
    setVector( v[1], l, o, l ) ;
    setVector( v[2], l, l, o ) ;
}

void SetPolygons8hedronVertexSymmetry( int p[ ][ ], int v[ ] ) {

    int n[ ] = length( p ) ;
    for ( int i=0; i<n[0]; i++ ) {
        setPolygonVector( p[0][i], v[0], v[1], v[2], v[3] );
        if ( i == 1 ) {
            rotXPolygon( p[0][i], PI/2 );
        } else if ( i == 2 ) {
            rotZPolygon( p[0][i], -PI/2 );
        } else if ( i == 3 ) {
            rotXPolygon( p[0][i], -PI/2 );
        } else if ( i == 4 ) {
            rotZPolygon( p[0][i], PI/2 );
        } else if ( i == 5 ) {
            rotZPolygon( p[0][i], PI );
        }
    }
}

void SetPolygons6hedronVertexSymmetry( int p[ ][ ], int v[ ] ) {

    int n[ ] = length( p ) ;
    for ( int i=0; i<n[0]; i++ ) {
        setPolygonVector( p[0][i], v[0], v[1], v[2] );
        if ( ( i >= 1 ) && ( i <= 3 ) ) {
            rotYPolygon( p[0][i], PI/2 * i );
        } else if ( ( i >= 4 ) ) {
            rotZPolygon( p[0][i], PI );
            rotYPolygon( p[0][i], PI/2 * ( i - 3 ) );
        }
    }
}


int COLOR_Q[ 3 ] , COLOR_T[ 3 ] ;
{
    int sred[3] ; sred[0] = 255 ; sred[1] = 25 ; sred[2] = 50 ;
    int sblue[3] ; sblue[0] = 50 ; sblue[1] = 25 ; sblue[2] = 255 ;
    COLOR_Q = sred ;
    COLOR_T = sblue ;
}
N = 2 ; int OPACITY[ N ];
{
    OPACITY[0] = 255 ;
    OPACITY[1] = 255 ;
}

void SetElementColors() {

    for ( int i=0; i<NQ; i++ ) {
        SetPolygonColor( QP[0][i], COLOR_Q, OPACITY[0] );
            }
    for ( int i=0; i<NT; i++ ) {
        SetPolygonColor( TP[0][i], COLOR_T, OPACITY[1] );
    }
}


N = 6 ; float OPTIN[ N ];
{
    float emissive = o ; 
    float diffractive = 0.4 ; 
    float diffuse = 0.9 ; 
    float ambient = 0.4 ;
    float specularintensity = 0.5 , specularangle = 0.7 ; 

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

void SetElementOptions() {

    for ( int i=0; i<NQ; i++ ) {
        setPolygonCull( QP[0][i], false, false );
        SetPolygonSurface( QP[0][i], OPTIN );
    }
    for ( int i=0; i<NT; i++ ) {
        setPolygonCull( TP[0][i], false, false );
        SetPolygonSurface( TP[0][i], OPTIN );
    }
}


void AddElements() {

    for ( int i=0; i<NQ; i++ ){
    addPolygon( QP[0][i], RENDERER, CD[0] );
    }
    for ( int i=0; i<NT; i++){
    addPolygon( TP[0][i], RENDERER, CD[0] );
    }
}




/* prepare stage */


double CAMERA_ORIGIN_Z = 7 * l ;
float GRAPHIC_MAGNIFICATION = 1000.0 ;
double GRAPHIC_DISTANCE = 10.0 ;

void PrepareStage() {

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

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

    int w = getWorldCoordinate( RENDERER ) ;
    setCoordinateOrigin( w, o, o, o )
    setCoordinateEulerAngle( w, o, o, o );
    setCameraOrigin( w, o, o, CAMERA_ORIGIN_Z );
    setCameraEulerAngle( w, o, o, o );
}




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


bool KEEP_LOOP = true ;
bool SAVE_A_PICTURE = false ;

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

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




/* create GUI elements */


int SETTING_WINDOW; 
int LABEL[ 2 ];
N = length( LABEL ) ; int SLIDER[ N ];
int CHECK_BOX[ 2 ]

bool REMOVE_HEXAHEDRON = false ;
bool REMOVE_OCTAHEDRON = false ;
double P[ N ] = o ;

string LABEL_TEXT[ N ]
N = length( CHECK_BOX ) ; string CHECK_BOX_TEXT[ N ]
{
    CHECK_BOX_TEXT[0] = "正六面体の表面と内部を描画しない" ;
    CHECK_BOX_TEXT[1] = "正八面体の表面と内部を描画しない" ;
    LABEL_TEXT[0] = "赤い面(正六面体)を広げる" ; 
    LABEL_TEXT[1] = "青い面(正八面体)を広げる" ; 
}

void CreateGuiElements() {

    int nc = length( CHECK_BOX ) ;
    int nl = length( LABEL ) , ns = nl ;
    int lx = 15 , lw = 280 ; 
    int lh = 15 ; int lyspace = 15 ; int ly[nl];
    int sx = lx , sw = lw, sh = lh , syspace = 5 ; int sy[ns];
    int cbx = lx , cbw = lw , cby = 20 , cbh = 15 , cbyspace = lyspace ;
    {
        int initial_ly = nc*cby + nc*cbyspace + lyspace + 10;
        for ( int i=0; i<length( LABEL ); i++ ) {
            ly[i] = initial_ly + ( lh + lyspace + sh + syspace ) * i ;
            sy[i] = ly[i] + lh + syspace ;
        }
    }

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

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

        for ( int i=0; i<nc; i++ ) {
            int y = cby + (cby + cbyspace) * i ;
            CHECK_BOX[i] = newCheckBox( cbx, y, cbw, cbh, CHECK_BOX_TEXT[i], false )
            addComponent( CHECK_BOX[i], SETTING_WINDOW );
        }

        for ( int i=0; i<nl; i++ ) {
            LABEL[i] = newTextLabel( lx, ly[i], lw, lh, LABEL_TEXT[i] );
            addComponent( LABEL[i], SETTING_WINDOW );
            SLIDER[i] = newHorizontalSlider( sx, sy[i], sw, sh, o );
            addComponent( SLIDER[i], SETTING_WINDOW );
        }
    }

    paintComponent( SETTING_WINDOW );
}




/* event handlers */


void onSliderMove( int id, double value ) {

    if ( id == SLIDER[0] ) {

        if ( REMOVE_HEXAHEDRON == false ) {
             P[0] = value;
            l = a ;
            AppendQuadrangle_to_QP( P[0] );
        }

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

        if ( REMOVE_OCTAHEDRON == false ) {
            P[1] = value ;
            l = a ;
            AppendQuadrangle_to_TP( P[1] );
        }
    }
}


int QQ[ NQ ][ 4 ]; // append to QP
{
    for ( int i=0; i<NQ; i++ ) {
        for ( int j=0; j<4; j++ ) {
            QQ[i][j] = newQuadranglePolygon( O, O, O, O ) ;
            setPolygonCull( QQ[i][j], false, false );
            SetPolygonSurface( QQ[i][j], OPTIN );
            SetPolygonColor( QQ[i][j], COLOR_Q, OPACITY[0] );
        }
    }
}

void AppendQuadrangle_to_QP( double p ) {

    int n[ ] = length( QQ )int m = n[0]; // number of QQs for a QP
    int v[ m ][ 4 ];
    for ( int i=0; i<m; i++ ) {
        v[i][0] = newVector( o, l, l );
        v[i][1] = newVector( p*l, l, l );
        v[i][2] = newVector( l, l, p*l );
        v[i][3] = newVector( l, l, o );
        for ( int j=0; j<4; j++ ) {
            rotYVector( v[i][j], PI/2 * i );
        }
    }

    for ( int i=0; i<NQ; i++ ) {
        for ( int j=0; j<m; j++ ) {
            setPolygonVector( QQ[i][j], v[j][0], v[j][1], v[j][2], v[j][3] );
            if ( ( i >= 1 ) && ( i <= 4 ) ) {
                rotXPolygon( QQ[i][j], PI/2 );
                rotYPolygon( QQ[i][j], PI/2 * ( i - 1 ) );
            } else if ( i == 5 ) {
                rotXPolygon( QQ[i][j], PI );
            }
            setPolygonSortOffset( QQ[i][j], 0.4*( 1.0 - p ) );
        }
    }
}


int QT[ NT ][ 3 ]; // append to TP
{
    for ( int i=0; i<NT; i++ ) {
        for ( int j=0; j<3; j++ ) {
            QT[i][j] = newQuadranglePolygon( O, O, O, O ) ;
            setPolygonCull( QT[i][j], false, false );
            SetPolygonSurface( QT[i][j], OPTIN );
            SetPolygonColor( QT[i][j], COLOR_T, OPACITY[1] );
        }
    }
}


void AppendQuadrangle_to_TP( double p ) {

    int n[ ] = length( QT )int m = n[0]; // number of QTs for a TP
    int v[ m ][ 4 ];
    for ( int i=0; i<m; i++ ) {
        v[i][0] = newVector( o, l, l );
        v[i][1] = newVector( l, l, o );
        v[i][2] = GetInternallyDividingVector( l, l, o,  o, 2*l, o,  p );
        v[i][3] = GetInternallyDividingVector( o, l, l,  o, 2*l, o,  p );
        for ( int j=0; j<4; j++ ) {
            rotVector( v[i][j], 2*PI/3 * i, l, l, l );
        }
    }

    for ( int i=0; i<NT; i++ ) {
        for ( int j=0; j<m; j++ ) {
            setPolygonVector( QT[i][j], v[j][0], v[j][1], v[j][2], v[j][3] );
            if ( ( i >= 1 ) && ( i <= 3 ) ) {
                rotYPolygon( QT[i][j], PI/2 * i );
            } else if ( i >= 4 ) {
                rotZPolygon( QT[i][j], PI );
                rotYPolygon( QT[i][j], PI/2 * ( i -3 ) );
            }
            setPolygonSortOffset( QT[i][j], 0.4*( 1.0 - p ) );
        }
    }
}


void onCheckBoxClick( int id, bool remove ){

    if ( id == CHECK_BOX[0] ) {
        REMOVE_HEXAHEDRON = remove ;
        if ( REMOVE_HEXAHEDRON ) {
            l = o ;
            SetVectors68hedronTriangle( VT );
            SetVectors68hedronQuadrangle( VQ );
            SetPolygons6hedronVertexSymmetry( TP, VT );
            SetPolygons8hedronVertexSymmetry( QP, VQ );
            AppendQuadrangle_to_QP( P[0] );
        } else {
            l = a ;
            SetVectors68hedronTriangle( VT );
            SetVectors68hedronQuadrangle( VQ );
            SetPolygons6hedronVertexSymmetry( TP, VT );
            SetPolygons8hedronVertexSymmetry( QP, VQ );
            AppendQuadrangle_to_QP( P[0] );
            REMOVE_HEXAHEDRON = remove ;
        }


    } else if ( id == CHECK_BOX[1] ) {
        REMOVE_OCTAHEDRON = remove ;
        if ( REMOVE_OCTAHEDRON ) {
            l = o ;
            SetVectors68hedronTriangle( VT );
            SetVectors68hedronQuadrangle( VQ );
            SetPolygons6hedronVertexSymmetry( TP, VT );
            SetPolygons8hedronVertexSymmetry( QP, VQ );
            AppendQuadrangle_to_TP( P[1] );
        } else {
            l = a ;
            SetVectors68hedronTriangle( VT );
            SetVectors68hedronQuadrangle( VQ );
            SetPolygons6hedronVertexSymmetry( TP, VT );
            SetPolygons8hedronVertexSymmetry( QP, VQ );
            AppendQuadrangle_to_TP( P[1] );
            REMOVE_OCTAHEDRON = remove ;
        }

    }
    
}




/* forward motion */


bool CREATE_GUI = false ;

void ForwardMotion() {

    int t = newVector( o, o, o ) ; // x,y成分がそれぞれ開始、終了時刻

    DesignMotion( t ); // アニメーション

    float gui_uptime = getVectorY( t ) ; //終了時刻にGUI windowを配置
    
    CREATE_GUI = ( T >= gui_uptime ) && ( T < gui_uptime + STEP ) ;

    SetTRangeAbsolutely( t, o, gui_uptime + 60.0 );
    if ( Motion( t ) ) {
        spinYCoordinate( COORD[0], 2/180.0 * PI );
    }
}


void DesignMotion( int v ) {

    float start_t = 2.0 ;
    double d = 0.3 ; // 時間の単位

    SetTRangeAbsolutely( v, start_t, start_t + 2*d ) ;
    if ( Motion( v ) ) {
        if ( Moment( v ) ) {
            for ( int i=0; i<NQ; i++ ) {
                for ( int j=0; j<4; j++ ) {
                    addPolygon( QQ[i][j], RENDERER, CD[0] );
                }
            }
        }
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_QP( t );
    }

    SetTRange( v, d, 2*d )
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_QP( 1.0 - t );
    }

    SetTRange( v, d, 2*d );
    if ( Motion( v ) ) {
        if ( Moment( v ) ) {
            for ( int i=0; i<NT; i++ ) {
                for ( int j=0; j<3; j++ ) {
                    addPolygon( QT[i][j], RENDERER, CD[0] );
                }
            }
        }
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_TP( t );
    }

    int u1 = newVector( v ) ;

    SetTRange( v, d, 2*d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_QP( t );
    }

    SetTRange( v, 2*d, STEP );
    int u2 = newVector( v ) ;
    if ( Motion( v ) ) {
        l = o ;
        SetVectors68hedronTriangle( VT );
        SetVectors68hedronQuadrangle( VQ );
        SetPolygons6hedronVertexSymmetry( TP, VT );
        SetPolygons8hedronVertexSymmetry( QP, VQ );
        AppendQuadrangle_to_QP( o );
        l = 1.0 ;
    }

    SetTRange( v, 2*d, STEP );
    if ( Motion( v ) ) {
        SetVectors68hedronTriangle( VT );
        SetVectors68hedronQuadrangle( VQ );
        SetPolygons6hedronVertexSymmetry( TP, VT );
        SetPolygons8hedronVertexSymmetry( QP, VQ );
        AppendQuadrangle_to_QP( a );
    }

    SetTRange( v, 2*d, STEP );
    if ( Motion( v ) ) {
        l = o ;
        SetVectors68hedronTriangle( VT );
        SetVectors68hedronQuadrangle( VQ );
        SetPolygons6hedronVertexSymmetry( TP, VT );
        SetPolygons8hedronVertexSymmetry( QP, VQ );
        AppendQuadrangle_to_TP( o );
        l = 1.0 ;
    }

    SetTRange( v, 2*d, STEP );
    if ( Motion( v ) ) {
        SetVectors68hedronTriangle( VT );
        SetVectors68hedronQuadrangle( VQ );
        SetPolygons6hedronVertexSymmetry( TP, VT );
        SetPolygons8hedronVertexSymmetry( QP, VQ );
        AppendQuadrangle_to_TP( a );
    }

    SetTRange( v, 2*d, 4*d );
    float dt0 = getVectorZ( v ) ;
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_TP( 1.0 - t );
    }

    SetTRange( v, -dt0/2, dt0/2 );
    float p1 = Slv - 1.0 ;
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_QP( 1.0 - t + p1*t );
    }

    SetTRange( v, 2*d, 2*d );
    float p2 = 1.0/3 ;
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_TP( p2*t );
        AppendQuadrangle_to_QP( p1*( 1.0 - t ) );
    }

    SetTRange( v, 2*d, 2*d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        AppendQuadrangle_to_TP( p2*( 1.0 - t) );
    }

    SetTRangeAbsolutely( u1, start_t, getVectorY( u1 ) );
    if ( Motion( u1 ) ) {
        double t = GetLinearTime( u1 ) ;
        setCoordinateEulerAngle( COORD[1], o, 1.0*2*PI * t, o );
    }

    SetTRangeAbsolutely( u2, getVectorX( u2 ), getVectorY( v ) );
    if ( Motion( u2 ) ) {
        double t = GetLinearTime( u2 ) ;
        setCoordinateEulerAngle( COORD[1], 2*PI * t, 1.0*2*PI, o );
    }

    SetTRange( v, o, 5*d );
    if ( Motion( v ) ) {
        double t = GetLinearTime( v ) ;
        setCoordinateEulerAngle( COORD[1], o, o, o );
        rotYCoordinate( COORD[1], -PI/2 * t );
        rotXCoordinate( COORD[1], atan( ISlv ) * t );
    }
}

inserted by FC2 system