[XJTUSE]计算机图形学第二章作业,使用OpenGL编程实现DDA、中点画线和Bresenham算法和中点画圆法
首先是Windows10 + Visual Studio 2019 搭建OpenGL环境可以查看如下链接:
萌新向!!!Windows10 + Visual Studio 2019 搭建OpenGL环境(图文教程) - 哔哩哔哩 (bilibili.com)
//使用PC端浏览器打开,Android端似乎被删除了
一、计算机图形学第二章作业
1、题目描述
第二章 作业
1. 编程实现DDA、中点画线和Bresenham算法,对比它们的效率。
2. 编程实现中点画圆法。(重点关注算法原理和伪代码)
2、题目一
2.1关于DDA的实现
2.1.1算法原理
原理:根据直线的参数微分方程计有dy=m*dx
Step1:首先将给定端点作为了输入参数;
Step2:其次初始化,初值加上0.5保证精度;
Step3:比较起止点的水平以及垂直的差值较大的大数作为计算步数steps;
Step4:然后每步计算dx,dy分别为差数并除以steps;
Step5:最后,从起始点开始来确定相邻两点间的增量并且进行递推计算。
2.1.2算法实现
具体代码如下:
#include <Windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>void DDAline()
{int x1=101,y1=101,x2=499,y2=499;int steps;float m, x, y, dx, dy;x = x1 + 0.5f;y = y1 + 0.5f;steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);dx = (float)(x2 - x1) / steps;dy = (float)(y2 - y1) / steps;//计算直线斜率和截距m = (float)(y2 - y1) / (float)(x2 - x1);float b = y2 - m * x2;glClear(GL_COLOR_BUFFER_BIT);glPointSize(1.0f);glBegin(GL_POINTS);for (int i = 0; i < steps; i++) {glVertex2f((x + 400 / 2)/400.0-1.6, (400 / 2 - y)/400.0+0.5);x=x+dx;y=y+dy;}glEnd();glFlush();
}int main(int argc, char * argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("DrawLineByDDA");glutDisplayFunc(&DDAline);glutMainLoop();return 0;
}
2.1.3结果展示
2.2中点画线
2.2.1算法原理
原理:构造判别式:d=F(M)=F(xp+1,yp+0.5) =a(xp+1)+b(yp+0.5)+c
其中a=y0-y1, b=x1-x0, c=x0 y 1-x1 y 0
当d<0,M 在L(Q点 )下方,取右上方P 2为下一个象素
当d>0,M 在L(Q点 )上方,取右下方P 1为下一个象素
当d=0,选P 1 或 P 2均可,约定取P 1为下一个象素
Step1:画线从(x0, y0 )开始,d的初值 d 0=F(x0+1, y0+0.5)=F(x0, y0)+a+0.5b =a+0.5b。 a=y0-y1, b=x1-x0
可以用2d代替d来摆脱小数,提高效率。
Step2:令 d 0=2a+b, d1=2a, d2=2a+2b,我们有如下算法 。
Step3:若当前象素处于d ³ 0情况,则取正右方象素P1 (xp+1, yp), 要判下一个象素位置,应计算 d 1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a; 增量为a
• 若d<0时,则取右上方象素P 2 (xp+1, yp+1)。要判断再下一象素,则要计算 d 2= F(xp+2, yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b ;增量为a+b
Step4:画出对应的点
2.2.2算法实现
具体代码如下:
#include <Windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>float X[65536], Y[65536];
int cnt = 0;void MidPointline(int x1, int y1, int x2, int y2)
{int a, b, d1, d2, d, x, y;a = y1 - y2;b = x2 - x1;d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);x = x1; y = y1;X[0] = x;Y[0] = y;cnt++;while (x < x2){if (d < 0){x++;y++;d += d2;}else{x++;d += d1;}X[cnt] = x;Y[cnt] = y;cnt++;}
}void midPoints()
{glClear(GL_COLOR_BUFFER_BIT);glPointSize(1.0f);glBegin(GL_POINTS);for (int i = 0; i < cnt; i++) {glVertex2f((X[i] + 400 / 2) / 400.0 - 1.6, (400 / 2 - Y[i]) / 400.0 + 0.5);}glEnd();glFlush();
}int main(int argc, char* argv[])
{MidPointline(101, 101, 499, 499);glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("DrawLineBymidPoints");glutDisplayFunc(&midPoints);glutMainLoop();return 0;
}
2.2.3结果展示
2.3实现Bresenham算法
2.3.1算法原理
原理如下:
Step1:设定interChange、Xsign、Ysign便于判断位置并计算误差初值e = 2 * min - max;(min和max分别为水平距离和垂直距离的最值)
Step2:设置点(Xi, Yi) 的颜色值,并求下一误差ei+1;
If ei >= 0 then ei+1 =ei+m-1;
else ei+1 = ei + m;
Step3:根据不同象限,确定X和Y变化符号的正负,进行下一次(2)(3)循环直至结束;
2.3.2算法实现
#include <Windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>void B()
{int x1 = 101, y1 = 101, x2 = 499, y2 = 499;int x, y, dx, dy, e, xSign, ySign, interChange = 0;dx = abs(x2 - x1);dy = abs(y2 - y1);float m = (float)(y2 - y1) / (float)(x2 - x1);float b = y2 - m * x2;if (dx < dy) {int temp;interChange = 1;temp = dx;dx = dy;dy = temp;}xSign = (x2 > x1) ? 1 : -1;ySign = (y2 > y1) ? 1 : -1;x = x1;y = y1;e = 2 * dy - dx;glClear(GL_COLOR_BUFFER_BIT);glPointSize(1.0f);glBegin(GL_POINTS);for (int i = 0; i <= dx; i++) {glVertex2f((x + 400.0 / 2) / 400.0 - 1.6, (400.0 / 2 - y) / 400.0 + 0.5);if (e > 0) {e = e - 2 * dx;if (interChange)x += xSign;elsey += ySign;}if (interChange)y += ySign;elsex += xSign;e = e + 2 * dy;}glEnd();glFlush();
}int main(int argc, char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("DrawLineByBresenham");glutDisplayFunc(&B);glutMainLoop();return 0;
}
2.3.3结果展示
2.4三种方法效率的比较
DDA算法:
复杂度:加法+取整
优点:避免了y=kx+b 方程中的浮点乘法。
缺点:需浮点数加法及取整运算,不利于硬件实现。
中点算法:
中点算法与DDA相比,主要是加法运算和浮点数运算,但是优化后,省去了浮点运算。
主要优点:算法简单,无乘除,只有移位操作,尤其适用硬件实现
Bresenham算法:
Bresenham算法是计算机图形学使用最广泛的直线光栅化算法。Bresenham算法是每个象素只需一个整数加法,其优点还有就是可以用于其他二次曲线。
3、题目二
3.1算法原理
中点画圆法利用的也是类似于Bresenham直线算法的思想,利用判别式选择像素,只需做简单的整数运算。
在平面直角坐标系的四个象限中第二象限的1/8圆为例,若确定了一个像素点为($x_{p},y_{p}$),那么下一个点要么是右方的P1,要么是右下方的P2。
构造函数一个函数F(x,y)=$x^{2}$+$y^{2}$-$R^{2}$,当F大于0时,点在圆外,反之则在圆内。
图中的M是P1和P2的中点,所以M=($x_{p}$+1,$y_{p}-0.5$),当F(M)<0时,M在圆内,说明P1离圆弧更近,反之M在圆外,P2更近。
根据以上原理,可构造判别式:
当$d_{p}$<0时,取P1为下一像素,下一像素判别式为:
当$d_{p}$>0时,取P2为下一像素,下一像素判别式为:
我们按顺时针方式生成八分圆,所以第一个像素为(0,R),初始判别式为:
1.25-R可以简化成1-R,去除浮点数运算,因为运算过程中增量都为整数,所以减去0.25是不会影响符号的。
3.2算法实现
#include <Windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>float X[65536], Y[65536];
const float R = 400.0;
int cnt = 0;void CirclePoints(int x, int y, int offx, int offy)//利用对称性画整圆
{X[cnt] = (x + offx) / R; Y[cnt] = (y + offy) / R;cnt++;X[cnt] = (y + offx) / R; Y[cnt] = (x + offy) / R;cnt++;X[cnt] = (x + offx) / R; Y[cnt] = (-y + offy) / R;cnt++;X[cnt] = (-y + offx) / R; Y[cnt] = (x + offy) / R;cnt++;X[cnt] = (-x + offx) / R; Y[cnt] = (y + offy) / R;cnt++;X[cnt] = (y + offx) / R; Y[cnt] = (-x + offy) / R;cnt++;X[cnt] = (-x + offx) / R; Y[cnt] = (-y + offy) / R;cnt++;X[cnt] = (-y + offx) / R; Y[cnt] = (-x + offy) / R;cnt++;
}void MidPointCircle(int x1, int y1, int r)
{int x, y, e;x = 0; y = r; e = 1 - r;CirclePoints(x, y, x1, y1);while (x <= y){if (e < 0)e += 2 * x + 3;else{e += 2 * (x - y) + 5;y--;}x++;CirclePoints(x, y, x1, y1);}
}void B()
{glClear(GL_COLOR_BUFFER_BIT);glPointSize(1.0f);glBegin(GL_POINTS);for(int i=0;i<cnt;i++)glVertex2f(X[i],Y[i]);glEnd();glFlush();
}int main(int argc, char* argv[])
{MidPointCircle(0, 0, 380);glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("DrawMidPointCircle");glutDisplayFunc(&B);glutMainLoop();return 0;
}
3.3结果展示
二、参考资料
[1]萌新向!!!Windows10 + Visual Studio 2019 搭建OpenGL环境(图文教程) - 哔哩哔哩 (bilibili.com)
[2]三种直线段绘制方法:DDA算法、B算法和中点分割法_独苍的博客-CSDN博客
[3]图形学入门(2)——圆生成算法(中点画圆法) - 走看看 (zoukankan.com)
[XJTUSE]计算机图形学第二章作业,使用OpenGL编程实现DDA、中点画线和Bresenham算法和中点画圆法相关推荐
- 计算机图形学第二次作业:画三角形
文章目录 1.画三角形 Step: 代码重点部分 详细算法及函数解释可见源代码`firstsol.cpp`注释 2.画红绿蓝三角形 代码重点部分 详细算法及函数解释可见源代码`secondsol.cp ...
- 【XJTUSE计算机图形学】第二章 光栅图形学(1)
文章目录 [XJTUSE计算机图形学]第二章 光栅图形学(1) 1.基本概念 2.直线段的扫描转换算法 数值微分(DDA)法 增量算法 中点画线法[重点] Bresenham算法[重点 很有可能会考] ...
- 【XJTUSE计算机图形学】第一章 绪论
禁止转载 文章目录 [XJTUSE计算机图形学]第一章 绪论 1.1 研究内容 1.图形系统的主要任务 2.计算机图形学的研究对象 3.图形的要素[填空题] 4.图形图像表示法 5.图形研究例子 6. ...
- 【XJTUSE计算机图形学】第三章 几何造型技术(2)——Bezier 曲线与曲面
文章目录 [XJTUSE计算机图形学]第三章 几何造型技术(2)--Bezier 曲线与曲面 Bezier 曲线与曲面 Bezier 曲线的定义与性质 定义 习题 Bernstein基函数性质 Bez ...
- 【XJTUSE计算机图形学】第三章 几何造型技术(1)——参数曲线和曲面
文章目录 [XJTUSE计算机图形学]第三章 几何造型技术(1)--参数曲线和曲面 参数曲线和曲面 曲线曲面参数表示 非参数表示 参数表示 曲线的基本概念 插值.拟合和光顺(掌握概念) 参数化 概念 ...
- 计算机导论重写算法,计算机导论第二章.ppt
<计算机导论第二章.ppt>由会员分享,可在线阅读,更多相关<计算机导论第二章.ppt(66页珍藏版)>请在人人文库网上搜索. 1.1.第二章计算机系统的组成2.1四个功能部件 ...
- 现代计算机工作模式是由科学家,计算机概论各章作业.doc
计算机概论各章作业 第一章 1.一个完整的计算机系统应该包括 ______. A)主机.键盘.鼠标和显示器 B)硬件系统和软件系统 C)主机和其他外部设备 D)系统软件和应用软件 2.计算机之 ...
- 第二章计算机网络答案,《计算机网络》第二章-作业参考答案
版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如果有侵权请立即联系:55525090@qq.com,我 ...
- 计算机图像学试题,北交20秋《计算机图形学》在线作业二题目
北交20秋<计算机图形学>在线作业二题目 2020-10-13 10:10:52 154 有学员问关于北交20秋<计算机图形学>在线作业二题目的题目的参考答案和解析,具体如下: ...
最新文章
- 自学python有哪些方向-Python新手入门应该注意的一些问题以及学习方向
- 51nod 1435 位数阶乘 (手动计算)
- UIButton或UILabel加个下划线
- 360容器平台监控实践
- Ajax学习总结(2)——Ajax参数详解及使用场景介绍
- Hashtable几种常用的遍历方法
- Axure RP9 自学之路1-软件初识
- 低字节+高字节+字地址+大端序+小端序全辨析
- CentOS6.5下lv调整空间大小
- java中json转map
- 深度思考比勤奋更重要
- python3大小写转换函数_python字符串大小写转换
- Python打包为exe文件
- cdr怎么把矩形去掉一个边_如何把一个矩形的四个角变形?
- 文件服务器属于固定资产吗,服务器内存属于固定资产吗
- 中国石斑鱼养殖产量不断上升,捕捞产量逐渐下降「图」
- 心理、意识和其他状态
- 【区块链 | Merkle】使用Merkle Tree空投,白名单验证
- 如何学好python
- “你的期望薪资是多少?” 月薪3万的他是这样回答的......
热门文章
- 虚拟场景+AR特效,世优科技助力京东手机华为新品发布会MR直播
- Codeforces869E The Untended Antiquity
- 链接元宇宙,开启新纪元
- 河北工业大学城市学院2019级 Java企业级系统管理期末复习资料
- 别让你20多岁的活法,毁掉你30岁后的人生
- 校友会小程序开发笔记十八:为浏览记录(我的足迹)模块的设计与实现
- 实验一 Java编程基础
- fastposter 2.2.0 新版本发布 电商级海报生成器
- unity游戏开发毕设_《毕业设计(论文)-基于Unity游戏引擎的游戏设计》.doc
- “创新雷神号”卫星成功发射,华为云分布式云原生“天地一体”首次组网成功