SDL2 で楕円を回転させる

 楕円を回転して描画させたいと思います。

楕円

 もともと、上のような楕円を回転させます。例えば、45° 回転させた下のような楕円を描画できるようにします。

45°回転させた楕円

 原点を中心としてある点 (x, y) を回転させた座標 (x’, y’) を求める式は次の式になります。

回転の計算

 この計算を行う関数 rotate() を作ります。元の座標を SDL_Point で受け取り、新しい座標に変更して返します。

void rotate(SDL_Point *pt, int angle) {
    int x, y;
    double r;

    x = pt->x, y = pt->y;
    r = M_PI * angle / 180.;

    pt->x = x * cos(r) - y * sin(r);
    pt->y = x * sin(r) + y * cos(r);
}

 この関数を使い、draw_oval() 関数に角度の引数を追加します。直交座標の xy 座標が決まったら、rotate() 関数で回転後の座標を求めます。

void draw_oval(SDL_Renderer *renderer, int sx, int sy, int a, int b, int angle) 
{
    SDL_Point p;
    int x, y, px, py;

    for( x = -a; x <= a; x++ ) {
        y = sqrt(1.0 - (double)(x*x)/(a*a))*b +0.5;
        p.x = x, p.y = y;
        rotate(&p, angle);
        px = sx + p.x;
        py = sy - p.y;
        SDL_RenderDrawPoint(renderer, px, py);
        p.x = x, p.y = -y;
        rotate(&p, angle);
        px = sx + p.x;
        py = sy - p.y;
        SDL_RenderDrawPoint(renderer, px, py);
    }
    for( y = -b; y <= b; y++ ) {
        x = sqrt(1.0 - (double)(y*y)/(b*b))*a +0.5;
        p.x = x, p.y = y;
        rotate(&p, angle);
        px = sx + p.x;
        py = sy - p.y;
        SDL_RenderDrawPoint(renderer, px, py);
        p.x = -x, p.y = y;
        rotate(&p, angle);
        px = sx + p.x;
        py = sy - p.y;
        SDL_RenderDrawPoint(renderer, px, py);
    }
}

 これで任意の回転が出来るようになります。

楕円の回転

 なかなかきれいな図形がかけました。

SDL2

Posted by sirius