現在地 >> メニュー >> サンプルコード::OpenCV >> Bresenhamのアルゴリズムでの直線 >> Bresenhamのアルゴリズムでの直線2

問題


マウスで任意の位置を指定し、2点間をBresenhamのアルゴリズムを用いることで
直線を描画せよ。

答え


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

using namespace std;


void Mouse( int event, int x, int y, int flags ,void *param);


void DRAW_LINE(CvPoint *p1, CvPoint *p2);
int CHECK_DIRECTION(char *str ,CvPoint *p1, CvPoint *p2);

void PUT_PIXEL_X(CvPoint *p1, CvPoint *p2,int &sx, int &sy,int &dx, int &dy);
void PUT_PIXEL_Y(CvPoint *p1, CvPoint *p2,int &sx, int &sy,int &dx, int &dy);


CvSize window={300,300};//ウィンドウサイズ

IplImage *imgA;
int main( int argc, char **argv)
{

imgA = cvCreateImage(window,IPL_DEPTH_8U,3);
cvSet (imgA, cvScalarAll (0), 0);


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

cvSetMouseCallback("window", Mouse);


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

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

return 0;
}


/***************[ここから コールバック]****************/
CvPoint p1;
CvPoint p2;
int count;

void Mouse( int event, int x, int y, int flags ,void *param = NULL) // コールバック関数
{

switch(event)
{

case CV_EVENT_LBUTTONDOWN:

if(count == 0)
{
printf("p1:(%d,%d) \n",x,y);
cvSet (imgA, cvScalarAll (0), 0);
cvShowImage("window",imgA);

p1.x = x;
p1.y = y;
count++;

}else if(count == 1)
{
printf("p2:(%d,%d) \n",x,y);
puts("---------------");
p2.x = x;
p2.y = y;
count =0;

DRAW_LINE(&p1,&p2);

}

cvShowImage("window",imgA);

break;

}

}

/***[ここから各種関数]***/
void DRAW_LINE(CvPoint *p1, CvPoint *p2)
{

/*初期値代入*/
int dx = abs(p1->x - p2->x);
int dy = abs(p1->y - p2->y);

int sx = CHECK_DIRECTION("x",p1,p2); //進行方向決定(x軸)
int sy = CHECK_DIRECTION("y",p1,p2);//進行方向決定(y軸)

/*ここから描画*/
if(dx >= dy)
{
PUT_PIXEL_X(p1,p2,sx,sy,dx,dy);
}else
{
PUT_PIXEL_Y(p1,p2,sx,sy,dx,dy);
}

}


/*方向チェック*/
int CHECK_DIRECTION(char *str ,CvPoint *p1, CvPoint *p2)
{

if(strncmp(str,"x",1)== 0)
{
if(p1->x >= p2->x)
{
return -1;
}else
{
return 1;
}

}else if(strncmp(str,"y",1)== 0)
{
if(p1->y >= p2->y)
{
return -1;
}else
{
return 1;
}
}else
{
printf("CHECK_DIRECTION is fault.\n");
std::exit(0);
}

}


/*X軸方向に走査*/
void PUT_PIXEL_X(CvPoint *p1, CvPoint *p2,int &sx, int &sy ,int &dx, int &dy)
{

int a = 2*dy;
int a1= a-2*dx;
int e = a - dx;

int x = p1->x;
int y = p1->y;

for(x = p1->x; (sx >=0 ? x<= p2->x : x>=p2->x) ;x+=sx) // |傾き| <= 1
{
imgA->imageData[y*imgA->widthStep + x*3] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+1] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+2] = (signed char)255;

if (e>=0)
{
y+=sy;
e += a1;
}else
{
e+=a;
}
}

}

/*Y軸方向に走査*/
void PUT_PIXEL_Y(CvPoint *p1, CvPoint *p2,int &sx, int &sy ,int &dx, int &dy)
{
int a = 2*dx;
int a1= a-2*dy;
int e = a - dy;

int x = p1->x;
int y = p1->y;

for(y = p1->y; (sy >=0 ? y<= p2->y : y>=p2->y) ;y+=sy)// |傾き| > 1
{

imgA->imageData[y*imgA->widthStep + x*3] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+1] = (signed char)255;
imgA->imageData[y*imgA->widthStep + x*3+2] = (signed char)255;

if (e>=0)
{
x+=sx;
e += a1;
}else
{
e+=a;
}

}
}


メモ


引数に「参照」を使ってみた。

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます