2D基本图形生成算法
- 格式:ppt
- 大小:1.47 MB
- 文档页数:110
计算机图形学实验二课程名称:计算机图形学实验名称:二维图形生成技术实验日期:2011-12-07班级:数媒0902班姓名:沈玉婷学号:0305090206一、实验目的和要求1、掌握二维基本图元直线段生成的DDA算法,中点算法、Bresenham算法;2、掌握二维基本图元圆的扫描算法;3、掌握二维图元填充的种子填充算法;4、掌握二维图元填充的多边形扫描线算法。
二、实验内容1、编程实现利用交互形式确定直线的两端点,并实现DDA、中点算法和Bresenham算法生成直线2、推导1/4圆的中点画圆算法,并编程实现。
3、构造任意一个边界表示的多边形,假定该多边形内部是四连通的。
要求:用递归算法实现对多边形内部的填充,要求内部颜色和边界不一致。
三、实验步骤假设已知P(xi,yi),则可能的下一个像素只能是P1(xi+1,yi)或者P2(xi+1,yi+1),构造圆函数为F(x,y)=x²+y²-R²圆上的点(x,y),有F(x,y)=0;圆外的点(x,y),有F(x,y)>0;圆内的点(x,y),有F(x,y)<0。
构造原函数:F(x,y)= x2+y2-R2..构造判别式:di=F(Mi)=F(xi+1,yi-0.5)=(xi+1)2+(yi-0.5)2-R21.di<0,则应取P1(xi+1,yi)为下一像素:di+1=F(xi+2,yi-0.5)=(xi+2)2+(yi-0.5)2-R2=di+2xi+32.di>=0,则应取P2(xi+1,yi-1)为下一像素:di+1=F(xi+2,yi-1.5)=(xi+2)2+(yi-1.5)2-R2= di+2(xi-yi)+5若按顺时针方向生成1/4圆,则第一个像素是(0,R),则判别式的初值:d0=1.25-R,进一步整理可令:d0=1-R;程序中令:xx=0,yy=r;dtx=3,dty=2-2*r;d=1-r;画四分之一圆,令yy>=0即可;其中按照di的正负确定下一像素的位置,逐渐画出四分之一的圆。
2D简单图形相关算法罗列因为平常在Qt开发过程中经常会与⼀些简单的2D⼏何图形打交道,因此学习和掌握⼀些基本的2D⼏何计算还是很有必要的,在这⾥罗列⼀些常⽤的基本情况,之后会适时补充。
[1] 两点之间距离,根据两个点的差值算出对应的向量,然后算出这个向量的斜边开放即这两点的距离。
qreal distance(const QPointF &pt1, const QPointF &pt2){QPointF offset = pt1 - pt2;return sqrt(offset.x() * offset.x() + offset.y() * offset.y());}[2] 计算两条直线的交点QPointF intersection(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3, const QPointF &pt4){// ⾸先根据两点式 (y - y1) / (y2 - y1) = (x - x1) / (x2 - x1)// 得出 y = (y2 - y1) / (x2 - x1)(x - x1) + y1// 其中(y2 - y1) / (x2 - x1)为斜率k// 即 y = k(x - x1) + y1// 两线平⾏即k1 == k2// ⼀线平⾏y即 p1.x == p2.xint state -- 标志位⽤来进⾏简单的情况判断if (pt1.x() != pt2.x()){a = (p2.y() - p1.y()) / (p2.x() - p1.x());state |= 1; // 1即01}if (pt3.x() != pt4.x()){b = (p4.y() - p3.y()) / (p4.x() - p3.x());state |= 2; // 2即10}switch(sate){case0: // 既不是01也不是10,即两线同时平⾏于Yreturn QPointF();case1: // 第⼀条直线斜线,第⼆条直线平⾏于Yfloat x = p3.x();float y = a * x - a * p1.x() + p1.y();return QPointF(x, y);case2: // 第⼆条直线斜线,第⼀条直线平⾏于Yfloat x = p1.x();float y = b * x - a * p3.x() + p3.y();return QPointF(x, y);case3: // 两条直线都存在斜率if (a == b)return QPointF();float x = (a * p1.x() - b * p3.x() - p1.y() + p3.y()) / (a - b);float y = a * x - a * p1.x() + p1.y();return QPointF(x, y);}}[3] 返回⼀点到直线的垂直交点的坐标QPointF Formula::verticalCrossPoint(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3){if((fabs(pt1.x() - pt2.x()) < 1e-6)) // 判断是否平⾏于Y轴{return QPointF(pt1.x(), pt3.y());}// 直线 y = ax + b, 垂线则为 -ay = x - m// 直线斜率为k,垂线斜率为-1/kqreal a = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());qreal b = (pt1.y()- a * pt1.x());qreal m = pt3.x() + a * pt3.y();// 硬解求出交点QPointF ptCross;ptCross.setX((m - a * b) / (a * a + 1));ptCross.setY(a * ptCross.x() + b);return ptCross}[4] 判断点是否在直线上,需要注意的是,浮点数与0的⽐较通常为 < 1e-6。