frostar@wiki
RotateBlt
最終更新:
frostar
-
view
PlgBltを利用して、ある点を中心として回転させて描画する関数RotateBltを作成する。
下準備として、POINT型のポインタと回転させる角度を引数として、(0,0)を中心に回転させ、回転させた座標をそのまま持ってきたポインタの中身に格納する関数を作る。
(x,y)を(0,0)を中心にradだけ回転させて(x',y')に移るとき、その座標の関係は
下準備として、POINT型のポインタと回転させる角度を引数として、(0,0)を中心に回転させ、回転させた座標をそのまま持ってきたポインタの中身に格納する関数を作る。
(x,y)を(0,0)を中心にradだけ回転させて(x',y')に移るとき、その座標の関係は
x'=x*cos(rad)-y*sin(rad); y'=x*sin(rad)+y*cos(rad);
なので
void Rotate(POINT* p,double rad){ int x = p->x; int y = p->y; p->x = (int)(x*cos(rad)-y*sin(rad)); p->y = (int)(x*sin(rad)+y*cos(rad)); }
となる。
このRotateを使ってRotateBltを作ると
このRotateを使ってRotateBltを作ると
BOOL RotateBlt( HDC hdcDest,//描画先HDC int DestX,//描画先長方形左上X座標 int DestY,//描画先長方形左上Y座標 int DestW,//描画先長方形幅 int DestH,//描画先長方形高さ HDC hdcSrc,//描画元HDC int SrcX,//描画元長方形左上X座標 int SrcY,//描画元長方形左上Y座標 int SrcW,//描画元長方形幅 int SrcH,//描画元長方形高さ int rad//回転角度 ){ POINT p[3]; p[0].x = DestW/-2; p[0].y = DestH/-2; Rotate(&p[0],rad); p[1].x = DestW/2; p[1].y = DestH/-2; Rotate(&p[1],rad); p[2].x = DestW/-2; p[2].y = DestH/2; Rotate(&p[2],rad); for(int i=0;i<3;i++){ p[i].x+=DestX+DestW/2; p[i].y+=DestY+DestH/2; } return PlgBlt(hdcDest,p,hdcSrc,SrcX,SrcY,SrcW,SrcH,NULL,NULL,NULL); }
まずはじめにPOINT型の変数配列を作成する。
配列のサイズは3だが、これはPlgBltが平行四辺形への描画であり、平行四辺形は3つの頂点さえ決まれば最後1点は自動的に決まるので、PlgBltの第2引数にはサイズ3のPOINT型の配列を指定するだけでOK。
各POINTに初期値を設定し、それぞれRotateに引き渡している。
Rotateは(0,0)を中心とした回転なので、描画サイズの幅をwidth,高さをhightとすると
配列のサイズは3だが、これはPlgBltが平行四辺形への描画であり、平行四辺形は3つの頂点さえ決まれば最後1点は自動的に決まるので、PlgBltの第2引数にはサイズ3のPOINT型の配列を指定するだけでOK。
各POINTに初期値を設定し、それぞれRotateに引き渡している。
Rotateは(0,0)を中心とした回転なので、描画サイズの幅をwidth,高さをhightとすると
左上(-width/2,-height/2) 右上(width/2,-height/2) 左下(-width/2,height/2) (右下(width/2,height/2))
となり、これを回転させた座標をそれぞれ描画先の座標(DestX,DestY)に平行移動させることで、実際に描画する座標を得られるので、これをPlgBltの第2引数に渡すことで回転描画を実現できる。
つまり最終的に描画されるのは、描画先の長方形を回転角度だけまわした長方形に描画元の画像を描画することになる。
つまり最終的に描画されるのは、描画先の長方形を回転角度だけまわした長方形に描画元の画像を描画することになる。