回転付きの楕円塗りつぶし
前回までで回転について説明したので、ここで一旦円の塗りつぶしに戻って、今度は回転付きの楕円塗りつぶしを描画してみたいと思います。
スクリーンショット
左クリックで、15 度単位で回転します。
ソースコード
024_rotate3.c
#include <math.h> #include "sptk.h" #define PI 3.141592 #define SUBPIXEL 5 SPTK_IMAGE *img; int angle = 0; void draw_fill_ellipse_rotation(double yscale) { int ix,iy,jx,jy,cnt,val; double xx,yy,dx,dy,r,dcos,dsin,rd; r = 85; rd = angle * PI / 180.0; dcos = cos(rd); dsin = sin(rd); for(iy = 0; iy < 200; iy++) { for(ix = 0; ix < 200; ix++) { /* オーバーサンプリング */ cnt = 0; for(jy = 0; jy < SUBPIXEL; jy++) { for(jx = 0; jx < SUBPIXEL; jx++) { xx = ix - 100 + jx * (1.0 / SUBPIXEL); yy = iy - 100 + jy * (1.0 / SUBPIXEL); dx = xx * dcos - yy * dsin; dy = (xx * dsin + yy * dcos) / yscale; if(dx * dx + dy * dy < r * r) cnt++; } } val = 255 * cnt / (SUBPIXEL * SUBPIXEL); val = 255 - val; sptk_image_setpixel(img, ix, iy, SPTK_RGB(val, val, val)); } } } void winhandle(SPTK_EVENT *ev) { switch(ev->type) { case SPTK_EVENT_BTTDOWN: angle = (angle + 15) % 360; draw_fill_ellipse_rotation(0.4); sptk_update(NULL, 0, 0, 200, 200, 0); break; case SPTK_EVENT_WINDOW_CLOSE: sptk_quit(); break; } } int main() { sptk_init("test", 200, 200); sptk_window_set_handle(winhandle); img = sptk_window_get_image(); draw_fill_ellipse_rotation(0.4); sptk_run(); return 0; }
解説
正円の状態を元にして考えると、円の縦方向を yscale 倍した後、回転を行うのですから、描画としてはその逆をやればいいことになります。
描画先の座標を、原点を (0, 0) とした位置で逆回転を行って、その後 Y 位置を yscale で割ると、正円における位置を求めることができます。
描画先の座標を、原点を (0, 0) とした位置で逆回転を行って、その後 Y 位置を yscale で割ると、正円における位置を求めることができます。