Computer Graphics Project2——画线及画圆

来源:互联网 发布:linux中ll 编辑:程序博客网 时间:2024/05/15 17:20

使用CodeBlock+openCV完成本次Project,编译运行后的exe的链接附在博客后面,画圆时进行了一下拓展,使圆可以进行填充,使用的算法如下:
1. 画线算法:Bresenham算法

代码如下:

#include "cv.h"#include "highgui.h"#include <cmath>#include <cstring>#include <cstdio>#include <iostream>using namespace std;//初始化CvSize window={500,500};//窗口大小CvPoint p1;CvPoint p2;IplImage *img;//dx>dy前提下的xVector>0和xVector<0两种情况void draw1(CvPoint *p1, CvPoint *p2,int &xVector, int &yVector ,int &dx, int &dy){    int eps = 2*dy - dx;    int x;    int y = p1->y;    for(x = p1->x; (xVector > 0 ? x<= p2->x : x>=p2->x) ;x+=xVector){        //直线RGB(颜色)设置        img->imageData[y*img->widthStep + x*3+1] = (signed char)255;        img->imageData[y*img->widthStep + x*3+2] = (signed char)255;        if(xVector>0){            img->imageData[y*img->widthStep + x*3] = (signed char)255;//白色        }else{            img->imageData[y*img->widthStep + x*3] = (signed char)0;//黄色        }        if (eps>=0){            y += yVector;            eps += (2*dy-2*dx);        }        else{            eps += 2*dy;        }    }}//dy>dx前提下的yVector>0和yVector<0两种情况void draw2(CvPoint *p1, CvPoint *p2,int &xVector, int &yVector ,int &dx, int &dy){    int eps = 2*dx - dy;    int x = p1->x;    int y;    for (y = p1->y; (yVector >=0 ? y<= p2->y : y>=p2->y) ;y+=yVector){        img->imageData[y*img->widthStep + x*3] = (signed char)0;        if(yVector>0){            img->imageData[y*img->widthStep + x*3+1] = (signed char)255;            img->imageData[y*img->widthStep + x*3+2] = (signed char)0;//绿色        }else{            img->imageData[y*img->widthStep + x*3+1] = (signed char)0;//红色            img->imageData[y*img->widthStep + x*3+2] = (signed char)255;        }        if (eps>=0){            x += xVector;            eps += (2*dx-2*dy);        }        else{            eps += 2*dx;        }    }}void drawLine(CvPoint *p1, CvPoint *p2){    //方向向量分别用于确定x,y轴的方向    int xVector;//x轴方向向量    int yVector;//y轴方向向量    int dx = abs(p1->x - p2->x);    int dy = abs(p1->y - p2->y);    cvSet (img, cvScalarAll (0), 0);    cvShowImage("window",img);    if (p1->x >= p2->x){//确定x轴方向向量        xVector = -1;    }else{        xVector = 1;    }    if (p1->y >= p2->y){//确定y轴方向向量        yVector = -1;    }else{        yVector = 1;    }    if (dx>=dy){        draw1(p1,p2,xVector,yVector,dx,dy);//|k|<=1    }    else{        draw2(p1,p2,xVector,yVector,dx,dy);//|k|>1    }    cvShowImage("window",img);}int main( int argc, char **argv){    img = cvCreateImage(window,IPL_DEPTH_8U,3);    cvSet (img, cvScalarAll (0), 0);    cout<<"Please enter the first point:"<<endl;    cin>>p1.x>>p1.y;    cout<<"p1("<<p1.x<<","<<p1.y<<")"<<endl;    cout<<"Please enter the second point:"<<endl;    cin>>p2.x>>p2.y;    cout<<"p2("<<p2.x<<","<<p2.y<<")"<<endl;    cvNamedWindow("window",CV_WINDOW_AUTOSIZE);    cvShowImage("window",img);    drawLine(&p1,&p2);    //cvSetMouseCallback("window", Mouse);    cvWaitKey(0);    cvReleaseImage( &img );    cvDestroyWindow("window");    return 0;}

运行结果:

起始坐标点:(100,100) - (400,400)

结果截图:



2. 画圆算法:Bresenham算法

代码如下:

#include <iostream>#include "cv.h"#include "highgui.h"using namespace std;CvSize window={500,500};//窗口大小CvPoint p;IplImage *img;void drawPixel(int x, int y){    img->imageData[y*img->widthStep + x*3] = (signed char)0;    img->imageData[y*img->widthStep + x*3+1] = (signed char)255;    img->imageData[y*img->widthStep + x*3+2] = (signed char)255;}void drawSymmetry(CvPoint *p, int x, int y){//利用八对称性    drawPixel(p->x + x, p->y + y);    drawPixel(p->x - x, p->y + y);    drawPixel(p->x + x, p->y - y);    drawPixel(p->x - x, p->y - y);    drawPixel(p->x + y, p->y + x);    drawPixel(p->x + y, p->y - x);    drawPixel(p->x - y, p->y + x);    drawPixel(p->x - y, p->y - x);}void drawCircle(CvPoint *p, int x, int y, int d, int fill){    int a=0;    cvSet (img, cvScalarAll (0), 0);    cvShowImage("window",img);    if (fill) {        // 如果填充(画实心圆)        while (x <= y) {            for (a = x; a <= y; a ++){                drawSymmetry(p, x, a);            }            if (d < 0) {                d = d + 4 * x + 6;            } else {                d = d + 4 * (x - y) + 10;                y --;            }            x++;        }        cout<<"fill1 is:"<<fill<<endl;    }    else {        while(x <= y){            //RGB(颜色)设置            drawSymmetry(p, x, y);            if (d < 0) {                d = d + 4 * x + 6;            }            else {                d = d + 4 * (x - y) + 10;                y--;            }            x++;        }        cout<<"fill2 is:"<<fill<<endl;    }    drawPixel(p->x, p->y);//将原点画在面板上    cvShowImage("window",img);}int main(){    img = cvCreateImage(window,IPL_DEPTH_8U,3);    cvSet (img, cvScalarAll (0), 0);    int r;    //初始化    cout<<"输入圆心坐标:"<<endl;    cin>>p.x>>p.y;    cout<<"圆心坐标为:("<<p.x<<","<<p.y<<")"<<endl;    cout<<"请输入半径:"<<endl;    cin>>r;    cout<<"半径为:"<<r<<endl;    int fill;    cout<<"请确定是否想填充圆(1-yes/0-no):"<<endl;    cin>>fill;    cvNamedWindow("window",CV_WINDOW_AUTOSIZE);    cvShowImage("window",img);    int x = 0, y = r;    int d = 3 - 2 * r;    drawCircle(&p, x, y, d, fill);    cvWaitKey(0);    cvReleaseImage( &img );    cvDestroyWindow("window");    return 0;}

运行结果:

圆心坐标:(200,200) 圆半径:100

未填充圆状态:


填充圆状态:


画线及画圆算法的exe文件:http://pan.baidu.com/s/1nt9gVGX

0 0
原创粉丝点击