/*
* =====================================================================================
*
* Filename: linebresenham2.c
*
* Description: A program for bresenham ,any point you want
*
* Version: 1.0
* Created: 01/08/2009 10:36:37 AM
* Revision: none
* Compiler: gcc
*
* Author: Futuredaemon (BUPT), [email protected]
* Company: BUPT_UNITED
*
* =====================================================================================
*/
#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};//窗口大小
CvPoint p1;
CvPoint p2;
int number;
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);
cvReleaseImage( &imgA );
cvDestroyWindow("window");
return 0;
}
void Mouse( int event, int x, int y, int flags ,void *param = NULL) //记录点
{
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
if (number == 0)
{
printf("p1:(%d,%d) \n",x,y);
cvSet (imgA, cvScalarAll (0), 0);
cvShowImage("window",imgA);
p1.x = x;
p1.y = y;
number++;
}
else if (number == 1)
{
printf("p2:(%d,%d) \n",x,y);
puts("---------------");
p2.x = x;
p2.y = y;
number =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)
{
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)
{
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;
}
}
}