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


問題


再帰処理をもちいてコッホ曲線を描画せよ。

※wikipedia

答え(仮)


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

#define M_PI 3.1415926535
#define REPEAT 2

using namespace std;


void DRAW_KOCH(IplImage *img,CvPoint a,CvPoint b,int n);
CvSize window_size={400,400};


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

CvPoint p={50,200},q={350,200};

IplImage *imgA = cvCreateImage(window_size,IPL_DEPTH_8U,3);
cvSet (imgA, cvScalarAll (255), 0);

DRAW_KOCH(imgA,p,q,REPEAT);

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




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

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

return 0;
}


/* コッホ曲線の描画 */
void DRAW_KOCH(IplImage *img,CvPoint a,CvPoint b,int n)
{
CvPoint2D32f *tmp_c,*tmp_d,*tmp_e;
tmp_c = new CvPoint2D32f();
tmp_d = new CvPoint2D32f();
tmp_e = new CvPoint2D32f();

tmp_c->x=float( (2*a.x+b.x)/3.0 );
tmp_c->y=float( (2*a.y+b.y)/3.0 );

tmp_d->x=float( (a.x+2*b.x)/3.0 );
tmp_d->y=float( (a.y+2*b.y)/3.0 );

int dx = b.x-a.x;
int dy = -(b.y-a.y);

double dis = sqrt(dx*dx*1.0 + dy*dy*1.0)/ sqrt(3.0);

double angle1,angle2;

if(dx >= 0)
{
angle1 = atan2(dy*1.0,dx*1.0)+M_PI/6.0;
tmp_e->x = float( a.x+(int)(dis*cos(angle1)+0.5) );
tmp_e->y = float( a.y-(int)(dis*sin(angle1)+0.5) );
}else
{ //元になる直線が右下がりの場合
angle2 = atan(dy*1.0/dx*1.0) - M_PI/6.0;
tmp_e->x=float( b.x+(int)(dis*cos(angle2)+0.5) );
tmp_e->y=float( b.y-(int)(dis*sin(angle2)+0.5) );
}



CvPoint c={int(tmp_c->x + 0.5), int(tmp_c->y + 0.5)},
d={int(tmp_d->x + 0.5), int(tmp_d->y + 0.5)},
e={int(tmp_e->x + 0.5), int(tmp_e->y + 0.5)};

delete tmp_c; tmp_c = NULL;
delete tmp_d; tmp_d = NULL;
delete tmp_e; tmp_e = NULL;

if(n<=0)
{
cvLine(img,a,c,CV_RGB(255,0,0)); //点Aから点Cへ
cvLine(img,c,e,CV_RGB(0,255,0)); //点Cから点Eへ
cvLine(img,e,d,CV_RGB(0,0,255)); //点Eから点Dへ
cvLine(img,d,b,CV_RGB(0,0,0)); //点Dから点Bへ

}else{
DRAW_KOCH(img,a,c,n-1); //点Aから点Cへ
DRAW_KOCH(img,c,e,n-1); //点Cから点Eへ
DRAW_KOCH(img,e,d,n-1); //点Eから点Dへ
DRAW_KOCH(img,d,b,n-1); //点Dから点Bへ
}


}