トップページ > 空即是色 > 2006年の記事 > 2次ベジェ曲線
空即是色 2次ベジェ曲線
2006年 02月23日
赤い点が曲線のアンカーポイントです。
以下、ソースコード。
始点と終点の処理など色々特殊かもしれない。
太字の部分が2次ベジェ曲線の公式にあたる。
vpx: アンカーポイントの配列[x座標]
vpy: アンカーポイントの配列[y座標]
vp_size: vpx,vpyのサイズ
vp_div: 曲線の近似/分割数
bcpx: 算出した値が入る[x座標]
bcpy: 算出した値が入る[y座標]
void convertBezierCurve( float* vpx, float* vpy, int vp_size, int vp_div, float* bcpx, // (vp_size-2)*vp_div+1 float* bcpy ){ float px1, py1, px2, py2, px3, py3; float x, y; float t, dt; int idx;
// convert bezier curve for( int i = 0; i < vp_size-2; i++ ){
// first if( i == 0 ){ px1 = vpx[i]; py1 = vpy[i]; px2 = vpx[i+1]; py2 = vpy[i+1]; px3 = ( vpx[i+1] + vpx[i+2] ) / 2.0; py3 = ( vpy[i+1] + vpy[i+2] ) / 2.0; } // end else if ( i == vp_size-3 ){ px1 = ( vpx[i] + vpx[i+1] ) / 2.0; py1 = ( vpy[i] + vpy[i+1] ) / 2.0; px2 = vpx[i+1]; py2 = vpy[i+1]; px3 = vpx[i+2]; py3 = vpy[i+2]; } else { px1 = ( vpx[i] + vpx[i+1] ) / 2.0; py1 = ( vpy[i] + vpy[i+1] ) / 2.0; px2 = vpx[i+1]; py2 = vpy[i+1]; px3 = ( vpx[i+1] + vpx[i+2] ) / 2.0; py3 = ( vpy[i+1] + vpy[i+2] ) / 2.0; }
t = 0.0; dt = 1.0 / (float)vp_div; for( int j = 0; j < vp_div; j++ ){ x = (1-t)*(1-t)*px1 + 2.0*t*(1-t)*px2 + t*t*px3; y = (1-t)*(1-t)*py1 + 2.0*t*(1-t)*py2 + t*t*py3; t += dt;
idx = j+i*vp_div; bcpx[idx] = x; bcpy[idx] = y; } }
// last idx = (vp_size-2) * vp_div; bcpx[idx] = vpx[vp_size-1]; bcpy[idx] = vpy[vp_size-1]; }
こんな感じで使う。
int vp_size = 5; float vpx[] = { 10, 20, 30, 40, 50 }; float vpy[] = { 20, 60, 30, 120, 10 };
// alloc int vp_div = 10; int bc_size = (vp_size-2)*vp_div+1; float* bcpx = new float[bc_size]; float* bcpy = new float[bc_size]; memset( bcpx, 0, sizeof(float)*bc_size ); memset( bcpy, 0, sizeof(float)*bc_size );
// convert bezir convertBezierCurve( vpx, vpy, vp_size, vp_div, bcpx, bcpy );
// draw bezier line glColor3f( 1.0, 1.0, 1.0 ); glBegin( GL_LINE_STRIP ); for( int i = 0; i < bc_size; i++ ){ glVertex2f( bcpx[i], bcpx[i] ); } glEnd();
// free delete bcpx; delete bcpy;
参考:
ベジェ曲線の数学的関数
トラックバック
この記事のトラックバックURL:http://null-null.net/mt/mt-tb.cgi/417