ポインタを使った引数を利用して,座標回転の関数を作ってみる。

●2次元の座標上で座標回転を行う関数を考えてみる。

座標(x, y) を,(xc, yc)を中心に θラジアン回転した座標は,次の式で計算できることが知られている。

・回転した後のX座標 =  (x - xc) * cosθ - (y - yc) * sinθ + xc
・回転した後のY座標 = (x - xc) * sinθ + (y - yc) * cosθ + yc

※ただし,数学の座標とコンピュータ画面座標ではy軸方向が逆なので,注意する必要がある。

この座標の回転を計算してくれる関数 rotation2D() は以下の様に定義できる。

main_rotation.cpp

 #include "DxLib.h" /* DXライブラリという便利な機能を使うため */
#include <math.h>  /* C言語に用意されているsin()とcos()を使うため */
 
/* 座標(x, y) を,(xc, yc)を中心にthetaラジアン回転した座標をそれぞれ,*xp, *yp に返す関数 rotation2D() */
void rotation2D( double * xp, double * yp, double x, double y, double xc, double yc, double theta  ) {
    y = -y; yc = -yc; // 数学座標と同じ様にするためにy座標値を反転
    *xp = (x - xc) * cos(theta) - (y - yc) * sin(theta) + xc;
    *yp = -1.0 * ( (x - xc) * sin(theta) + (y - yc) * cos(theta) + yc ); // y座標を数学座標系から戻すために -1.0 をかけて反転させる
}
 
int main() {
 
    double PI = 3.14159265358979323846;
 
    double xc = 640/2,   yc = 480/2;
    double x0 = 50 + xc, y0 =  20 + yc; // 頂点0の座標
    double x1 =  0 + x0, y1 = -40 + y0;
    double x2 = 30 + x0, y2 =   0 + y0;
 
    double angle = 5.0; // 1回あたりの回転角5.0度
 
    SetDrawScreen( DX_SCREEN_BACK );  /* 描画先を裏画面に設定する */
 
    long i = 0;
 
    while( 1 ){ /* 無限に繰り返す(無限ループ) */
 
        double tx0, ty0, tx1, ty1, tx2, ty2;
        rotation2D( &tx0, &ty0, x0, y0, xc, yc, (angle/180.0) * PI * i  );
        rotation2D( &tx1, &ty1, x1, y1, xc, yc, (angle/180.0) * PI * i  );
        rotation2D( &tx2, &ty2, x2, y2, xc, yc, (angle/180.0) * PI * i  );
        i++;
        
        ClsDrawScreen(); /* 描画先画面をきれいに消去する */
        
        DrawPixel( xc, yc, GetColor( 255, 0, 0 ) );
        DrawTriangle( tx0, ty0, tx1, ty1, tx2, ty2, GetColor( 0, 255, 100 ), FALSE );
 
        ScreenFlip(); /* 裏画面に描画したものを表画面に転写する */
        
        WaitTimer( 10 );
 
        if( CheckHitKey(KEY_INPUT_ESCAPE) ) break; /* エスケープキーが押されたら繰り返し処理から出る */
    } /* while()の閉じ中括弧 */
 
    return 0;
}