Computer Graphics Project2——画线及画圆

使用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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值