实验三画圆与凸多边形填充算法.docx

上传人:b****7 文档编号:15751337 上传时间:2023-07-07 格式:DOCX 页数:17 大小:54.75KB
下载 相关 举报
实验三画圆与凸多边形填充算法.docx_第1页
第1页 / 共17页
实验三画圆与凸多边形填充算法.docx_第2页
第2页 / 共17页
实验三画圆与凸多边形填充算法.docx_第3页
第3页 / 共17页
实验三画圆与凸多边形填充算法.docx_第4页
第4页 / 共17页
实验三画圆与凸多边形填充算法.docx_第5页
第5页 / 共17页
实验三画圆与凸多边形填充算法.docx_第6页
第6页 / 共17页
实验三画圆与凸多边形填充算法.docx_第7页
第7页 / 共17页
实验三画圆与凸多边形填充算法.docx_第8页
第8页 / 共17页
实验三画圆与凸多边形填充算法.docx_第9页
第9页 / 共17页
实验三画圆与凸多边形填充算法.docx_第10页
第10页 / 共17页
实验三画圆与凸多边形填充算法.docx_第11页
第11页 / 共17页
实验三画圆与凸多边形填充算法.docx_第12页
第12页 / 共17页
实验三画圆与凸多边形填充算法.docx_第13页
第13页 / 共17页
实验三画圆与凸多边形填充算法.docx_第14页
第14页 / 共17页
实验三画圆与凸多边形填充算法.docx_第15页
第15页 / 共17页
实验三画圆与凸多边形填充算法.docx_第16页
第16页 / 共17页
实验三画圆与凸多边形填充算法.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

实验三画圆与凸多边形填充算法.docx

《实验三画圆与凸多边形填充算法.docx》由会员分享,可在线阅读,更多相关《实验三画圆与凸多边形填充算法.docx(17页珍藏版)》请在冰点文库上搜索。

实验三画圆与凸多边形填充算法.docx

实验三画圆与凸多边形填充算法

华北水利水电大学计算机图形学实验报告

2017--2018学年第一学期2014级计算机科学与技术专业

指导老师曹源昊班级2014157学号201415717姓名李卫朋

实验三、画圆与凸多边形填充算法

1.实验目的

练习直线和圆的光栅扫描线算法,多边形的扫描转换算法。

2.实验内容和要求

按要求完成以下三个作业。

提交纸质实验报告,同时提交实验报告和源代码的电子版。

(I).利用Bresenham直线扫描算法绘制任意直线段。

输入为起点坐标(x0,y0)和终点坐标(x1,y1)以及线宽w,利用Bresenham算法计算离散的近似像素点,并在OpenGL窗口中绘制该线段。

要求绘制至少五条线段,具有不同的斜率,不同的起点和终点,不同的线宽。

不允许直接调用GL_LINES来实现。

(II).利用中点画圆算法绘制圆。

输入为圆心(xc,yc)和圆的的半径r,利用中点画圆算法计算离散的近似像素点,并在OpenGL窗口中绘制。

要求绘制至少四个圆,构成一个图案,比如奥迪车标或五环。

(III).实现多边形的扫描转换算法。

输入一个凸多边形的顶点序列,利用活性边表计算每条扫描线上位于多边形内部的像素,并填充上一个新颜色,最终达到填充多边形内部的目的。

建议:

为了实现坐标点和像素的一一对应,建议坐标轴的范围和窗口像素宽高一致,比如:

glutInitWindowSize(800,600);//像素宽800,高600

坐标系设定为:

gluOrtho2D(-400,400,-300,300);//坐标轴x方向宽为800,y方向高为600

3.算法描述

使用OpenGL进行画图,采用VS编程环境。

4.源程序代码

(1)

//bresenham直线.cpp:

定义控制台应用程序的入口点。

//

#include"stdio.h"

#include"stdafx.h"

#include"glut.h"

#include"stdlib.h"

#include"math.h"

#include"iostream"

usingnamespacestd;

GLsizeiwinWidth=400,winHeight=300;//屏幕显示宽高.

inta[100],b[100],c[100],d[100],n=-1;

voidinit()

{

glClearColor(1.0,1.0,1.0,1.0);

glMatrixMode(GL_PROJECTION);

gluOrtho2D(0.0,200.0,0.0,150.0);

}

voidlineBres(intx0,inty0,intxEnd,intyEnd)

{

intdx=abs(xEnd-x0),dy=abs(yEnd-y0);

intp=2*dy-dx;

inttwoDy=2*dy,twoDyMinusDx=2*(dy-dx);

intx,y;

if(x0>xEnd)

{

x=xEnd;

y=yEnd;

xEnd=x0;

}

else

{

x=x0;

y=y0;

}

glBegin(GL_POINTS);

glVertex2i(x,y);

glEnd();

while(x

{

x++;

if(p<0)

p+=twoDy;

else

{

y++;

p+=twoDyMinusDx;

}

glBegin(GL_POINTS);

glVertex2i(x,y);

glEnd();

}

}

voiddisplayFcn()

{

glColor3f(1.0,0.0,0.0);

for(inti=0;i<=n;i++)

{

lineBres(a[i],b[i],c[i],d[i]);

}

glFlush();

}

 

voidwinReshpeFcn(GLintnewWidth,GLintnewHeight)

{

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,GLdouble(newWidth),0.0,GLdouble(newHeight));

glClear(GL_COLOR_BUFFER_BIT);

winWidth=newWidth;

winHeight=newHeight;

}

int_tmain(intargc,char**argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowPosition(100,100);

glutInitWindowSize(winWidth,winHeight);

glutCreateWindow("bresenham直线");

init();

inth=1;

while(h==1)

{

printf("输入起点和终点的坐标");

n++;

scanf_s("%d%d%d%d",&a[n],&b[n],&c[n],&d[n]);

glutDisplayFunc(displayFcn);

printf("继续输入请按1,退出请按0");

scanf_s("%d",&h);

}

glutReshapeFunc(winReshpeFcn);

glutMainLoop();

return0;

}

 

(2)//中点画圆法.cpp:

定义控制台应用程序的入口点。

//

#include"stdafx.h"

#include"glut.h"

#include"stdlib.h"

#include"math.h"

#include"iostream"

usingnamespacestd;

constGLdoubletwoPi=6.283185;

GLsizeiwinWidth=400,winHeight=300;//屏幕显示宽高.

classscreenPt{

public:

screenPt(){

x=y=0;

}

GLintx,y;

voidsetCoords(GLintxCoordValue,GLintyCorrdValue){

x=xCoordValue;

y=yCorrdValue;

}

GLintgetx()const{

returnx;

}

GLintgety()const{

returny;

}

voidincrementx(){

x++;

}

voidincrementy(){

y--;

}

};

voidinit()

{

glClearColor(1.0,1.0,1.0,1.0);

glMatrixMode(GL_PROJECTION);

gluOrtho2D(0.0,200.0,0.0,150.0);

}

voidsetPixel(GLintxCoord,GLintyCoord){

glBegin(GL_POINTS);

glVertex2i(xCoord,yCoord);

glEnd();

}

voidcircleMidpoint(GLintxc,GLintyc,GLintradius){

screenPtcircPt;

GLintp=1-radius;//中点参数初值

circPt.setCoords(0,radius);

voidcirclePlotPoints(GLint,GLint,screenPt);

circlePlotPoints(xc,yc,circPt);

while(circPt.getx()

circPt.incrementx();

if(p<0)

p+=2*circPt.getx()+1;

else{

circPt.incrementy();

p+=2*(circPt.getx()-circPt.gety())+1;

}

circlePlotPoints(xc,yc,circPt);

}

}

voidcirclePlotPoints(GLintxc,GLintyc,screenPtcircPt)

{

setPixel(xc+circPt.getx(),yc+circPt.gety());

setPixel(xc-circPt.getx(),yc+circPt.gety());

setPixel(xc+circPt.getx(),yc-circPt.gety());

setPixel(xc-circPt.getx(),yc-circPt.gety());

setPixel(xc+circPt.gety(),yc+circPt.getx());

setPixel(xc-circPt.gety(),yc+circPt.getx());

setPixel(xc+circPt.gety(),yc-circPt.getx());

setPixel(xc-circPt.gety(),yc-circPt.getx());

}

voidpieChart()

{

screenPtcircCtr,piePt;

GLintradius=winWidth/16;

circCtr.x=winWidth/4;

circCtr.y=winHeight/1.5;

circleMidpoint(circCtr.x,circCtr.y,radius);//调用中点画圆方法

glColor3f(0.0,0.0,1.0);

circleMidpoint(circCtr.x+60,circCtr.y,radius);

glColor3f(0.0,0.0,0.0);

circleMidpoint(circCtr.x+120,circCtr.y,radius);

glColor3f(1.0,1.0,0.0);

circleMidpoint(circCtr.x+30,circCtr.y-30,radius);

glColor3f(0.0,1.0,0.0);

circleMidpoint(circCtr.x+90,circCtr.y-30,radius);

}

voiddisplayFcn()

{

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0,0.0,0.0);

pieChart();

glFlush();

}

voidwinReshpeFcn(GLintnewWidth,GLintnewHeight)

{

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,GLdouble(newWidth),0.0,GLdouble(newHeight));

glClear(GL_COLOR_BUFFER_BIT);

winWidth=newWidth;

winHeight=newHeight;

}

int_tmain(intargc,char**argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowPosition(100,100);

glutInitWindowSize(winWidth,winHeight);

glutCreateWindow("PieChart");

init();

glutDisplayFunc(displayFcn);

glutReshapeFunc(winReshpeFcn);

glutMainLoop();

}

(3)

#include"stdafx.h"

constintPOINTNUM=10;//多边形点数.

/******定义结构体用于活性边表AET和新边表NET***********************************/

typedefstructXET

{

floatx;

floatdx,ymax;

XET*next;

}AET,NET;

/******定义点结构体point******************************************************/

structpoint

{

floatx;

floaty;

}

polypoint[POINTNUM]={100,200,122,131,195,131,136,88,159,19,100,62,41,19,64,88,5,131,78,131};//五角星

voidPolyScan()

{

//计算最高点的y坐标(扫描到此结束)

intMaxY=0;

inti;

for(i=0;i

if(polypoint[i].y>MaxY)

MaxY=polypoint[i].y;

//初始化AET表

AET*pAET=newAET;

pAET->next=NULL;

//初始化NET表

NET*pNET[1024];

for(i=0;i<=MaxY;i++)

{

pNET[i]=newNET;

pNET[i]->next=NULL;

}

glClear(GL_COLOR_BUFFER_BIT);//赋值的窗体显示.

glColor3f(0.0,0.0,0.0);//设置直线的颜色红色

glBegin(GL_POINTS);

//扫描并建立NET表

for(i=0;i<=MaxY;i++)

{

for(intj=0;j

if(polypoint[j].y==i)

{//一个点跟前面的一个点形成一条线段。

跟后面的点也形成线段

if(polypoint[(j-1+POINTNUM)%POINTNUM].y>polypoint[j].y)

{

NET*p=newNET;

p->x=polypoint[j].x;

p->ymax=polypoint[(j-1+POINTNUM)%POINTNUM].y;

p->dx=(polypoint[(j-1+POINTNUM)%POINTNUM].x-polypoint[j].x)/(polypoint[(j-1+POINTNUM)%POINTNUM].y-polypoint[j].y);

p->next=pNET[i]->next;

pNET[i]->next=p;

}

if(polypoint[(j+1+POINTNUM)%POINTNUM].y>polypoint[j].y)

{

NET*p=newNET;

p->x=polypoint[j].x;

p->ymax=polypoint[(j+1+POINTNUM)%POINTNUM].y;

p->dx=(polypoint[(j+1+POINTNUM)%POINTNUM].x-polypoint[j].x)/(polypoint[(j+1+POINTNUM)%POINTNUM].y-polypoint[j].y);

p->next=pNET[i]->next;

pNET[i]->next=p;

}

}

}

//建立并更新活性边表AET

for(i=0;i<=MaxY;i++)

{

//计算新的交点x,更新AET

NET*p=pAET->next;

while(p)

{

p->x=p->x+p->dx;

p=p->next;

}

//更新后新AET先排序

//断表排序,不再开辟空间

AET*tq=pAET;

p=pAET->next;

tq->next=NULL;

while(p)

{

while(tq->next&&p->x>=tq->next->x)

tq=tq->next;

NET*s=p->next;

p->next=tq->next;

tq->next=p;

p=s;

tq=pAET;

}

//(改进算法)先从AET表中删除ymax==i的结点

AET*q=pAET;

p=q->next;

while(p)

{

if(p->ymax==i)

{

q->next=p->next;

deletep;

p=q->next;

}

else

{

q=q->next;

p=q->next;

}

}

//将NET中的新点增加AET,并用插入法按X值递增排序

p=pNET[i]->next;

q=pAET;

while(p)

{

while(q->next&&p->x>=q->next->x)

q=q->next;

NET*s=p->next;

p->next=q->next;

q->next=p;

p=s;

q=pAET;

}

//配对填充颜色

p=pAET->next;

while(p&&p->next)

{

for(floatj=p->x;j<=p->next->x;j++)

glVertex2i(static_cast(j),i);

p=p->next->next;//考虑端点情况

}

}

glEnd();

glFlush();

}

voidinit(void)

{glClearColor(1.0,1.0,1.0,1.0);

//窗体的背景颜色设置为白色

glMatrixMode(GL_PROJECTION);

//gluOrtho2D(0.0,600.0,0.0,450.0);

gluOrtho2D(-400,400,-300,300);

}

voidmain(intargc,char*argv)

{

glutInit(&argc,&argv);//I初始化GLUT.

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);//设置显示模式:

单个缓存和使用RGB模型

glutInitWindowPosition(50,100);//设置窗体的顶部和左边位置

glutInitWindowSize(800,600);//设置窗体的高度和宽度

glutCreateWindow("五角星");//创建显示窗体

init();

glutDisplayFunc(PolyScan);

glutMainLoop();

}

5.实验结果

(1)

 

(2)

 

(3)

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2