OpenGL de プログラミング - OpenCV::曲線
現在地 >> メニュー >> サンプルコード::OpenCV >> OpenCV::曲線

問題


以下の4点を制御点として、ベジェ曲線を描画せよ。

[スタート](0,0)→(100,100)→(150,50)→(100,100)

その他条件:
 点を打って描画。途切れる部分は、線でむすぶ。

答え

#include <cmath>
#include <cstdio>
#include <cv.h>
#include <highgui.h>

/******[制御点]*******/
double ctlpoints[4][2]=
{
{0,0},
{200,25},
{150,50},
{100,100}
};


void DRAW_BEZIER(double points[4][2],IplImage *imgA);
void DRAW_CTL_POINTS(double points[4][2],IplImage *imgA);



int main( int argc, char **argv)
{

static CvSize window_size={300,300};
IplImage *imgA = cvCreateImage(window_size,IPL_DEPTH_8U,3);
cvSet (imgA, cvScalarAll (255), 0);


DRAW_BEZIER(ctlpoints,imgA);
DRAW_CTL_POINTS(ctlpoints,imgA);


cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);

cvWaitKey(0); // 0秒待つ => ずっと入力待ち

cvReleaseImage(& imgA);
cvDestroyWindow("window");

return 0;
}


/***********[ここから、各種関数]************/
void DRAW_BEZIER(double points[4][2],IplImage *imgA)
{

int tmpX,tmpY;
int x=(int)points[0][0] ,y = (int)points[0][1];

for(double t = 0; t <= 1;t += 0.005)
{
tmpX = x;
tmpY = y;

x = int(pow( (1-t), 3) * points[0][0] + 3 * pow(1-t,2) * t * points[1][0] + 3*(1-t) * t*t * points[2][0]+t*t*t *points[3][0]);
y = int (pow( (1-t), 3) * points[0][1] + 3 * pow(1-t,2) * t * points[1][1] + 3*(1-t) * t*t * points[2][1]+t*t*t *points[3][1]);


if(abs(tmpX - x) >1 || abs(tmpY - y))
{
cvLine(imgA,cvPoint(tmpX,tmpY),cvPoint(x,y),cvScalar(0,255,0));
}else
{
cvRectangle(imgA,cvPoint(x,y),cvPoint(x,y),cvScalar(0,255,0),CV_FILLED);
}


}

}



void DRAW_CTL_POINTS(double points[4][2],IplImage *imgA)
{
cvRectangle(imgA,cvPoint((int)points[0][0],(int)points[0][1]),cvPoint((int)points[0][0]+1,(int)points[0][1]+1),cvScalar(0,0,255),CV_FILLED);
cvRectangle(imgA,cvPoint((int)points[1][0],(int)points[1][1]),cvPoint((int)points[1][0]+1,(int)points[1][1]+1),cvScalar(0,0,255),CV_FILLED);
cvRectangle(imgA,cvPoint((int)points[2][0],(int)points[2][1]),cvPoint((int)points[2][0]+1,(int)points[2][1]+1),cvScalar(0,0,255),CV_FILLED);
cvRectangle(imgA,cvPoint((int)points[3][0],(int)points[3][1]),cvPoint((int)points[3][0]+1,(int)points[3][1]+1),cvScalar(0,0,255),CV_FILLED);

}

メモ