北航计算机图形学公选期末考试整理资料
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
裁剪算法 直线段裁剪
1.直线段和窗口的关系
我们所说的窗口是各边平行于坐标轴的矩形。
窗口把一个直线段分成窗口内部分和窗口外部分。
通常落在窗口内部分是可见的,而落在窗口外部分是不可见的。
裁剪:确定图形中哪些部分落在显示区之内,哪些落在显示区之外,以便只显示落在显示区内的那部分图形。
这个选择过程称为裁剪。
裁减的依据是一对简单的不等式:
通常,我们只要验证点的坐标是否满足上述条件即可。
然而,如果逐点验证上述不等式,运算效率是非常低的。
直线段和窗口的关系有 (1)直线段在窗口外; (2)直线段完全在窗口内;
(3)直线段与窗口的一条边相交; (4)直线段与窗口的两条边相交;
结论:对于任意一条直线,它要么被完全排斥在窗口之外;要么在窗口内留下一个可见段,并且只能有一个可见段。
⎩⎨
⎧≤≤≤≤t b l l x
y y x x x
3.实现方法
端点在窗口内。
段只有一个
只有一个成立,则直线或如果满足
.22211⎩⎨⎧<<<<⎩⎨
⎧<<<<t b r
l t b r l y y y x x x y y y x x x
窗口外。
端点在窗口外或直线段两个都不成立,则直线段的和如果满足
.32211⎩⎨⎧<<<<⎩⎨
⎧<<<<t b r
l t b r l y y y x x x y y y x x x
()()⎩⎨
⎧≤≤≤≤⎪⎩
⎪⎨
⎧=+-=+-=10来判断是否满足11交点计算
.42121t y y y x
x ty
y t y tx x t x t
b l
代码裁剪法
基本思想:对于每条线段P 1P 2分为三种情况处理: (1)若P 1P 2完全在窗口内,则显示该线段P 1P 2简称“取”之。
(2)若P 1P 2明显在窗口外,则丢弃该线段,简称“弃”之。
(3)若线段不满足“取”或“弃”的条件,则在交点处把线段分为两段。
其中一段完全在窗口外,可弃之。
然后对另一段重复上述处理。
为快速判断,采用如下编码方法:
()()直线段在窗口内。
和如果满足
,右上角为
,假设窗口左下角坐标为⎩⎨⎧<<<<⎩⎨
⎧<<<<t b r
l t b r l t r b l y y y x x x y y y x x x y x y x 2211.1,,
每个区域赋予4位编码l r b t C C C C
⎩⎨
⎧<=⎩⎨
⎧>=other y y C other
y y C b t 0101min
max
⎩⎨
⎧>=⎩⎨
⎧>=other x x C other
x x C l r 0
10
1min
max
若P 1P 2完全在窗口内code1=0,且code2=0,则“取” 若P 1P 2明显在窗口外code1&code2≠0,则“弃”
在交点处把线段分为两段。
其中一段完全在窗口外,可弃之。
然后对另一段
重复上述处理。
中点分割裁剪算法
基本思想:
与前一种Cohen-Sutherland 算法一样首先对线段端点进行编码,并把线段与窗口的关系分为三种情况:
全在、完全不在和线段和窗口有交。
对前两种情况,进行一样的处理。
对于第三种情况,用中点分割的方法求出线段与窗口的交点。
求线段与窗口的交点
P0
A 、
B 分别为距P 0、P 1最近的可见点,P m 为P 0P 1中点
从出发找最近可见点的方法
先求出的中点
若不是显然不可见的,并且在窗口中有可见部分,则距最近的可见点一定落在上,所以用代替;
否则取代替
再对新的求中点。
重复上述过程,直到长度小于给定的控制常数为止,此时收敛于交点A。
从出发找最近可见点采用上面类似方法。
多边形裁剪
基本思想是一次用窗口的一条边裁剪多边形。
考虑窗口的一条边以及延长线构成的裁剪线
该线把平面分成两个部分:可见一侧;不可见一侧
基本思想是一次用窗口的一条边裁剪多边形。
考虑窗口的一条边以及延长线构成的裁剪线
该线把平面分成两个部分:可见一侧;不可见一侧
可见一
可
见
一
侧
p S
S S
p p
(1)(2)(3)(4)
对于
情况(1)仅输出顶点P;
情况(2)输出0个顶点;
情况(3)输出线段PS与裁剪线的交点I;
情况(4)输出线段PS与裁剪线的交点I和终点P
上述算法仅用一条裁剪边对多边形进行裁剪,得到一个顶点序列,作为下一条裁剪边处理过程的输入。
对于每一条裁剪边,只是判断点在窗口哪一侧以及求线段PS与裁剪边的交点算法应随之改变。
多边形运算
1.多边形的覆盖
1)多边形覆盖情况分析
当两个多边形互相重叠时,就会产生覆盖的效果。
覆盖是指一个多边形部分或全部地盖掉
了下面的另一个多边形
对于多边形的覆盖,特别是凹多边形,由于情况比较复杂,画图的步骤一般是:
①利用“重叠性检验”,排除不会发生覆盖的多边形。
②逐条求出被覆盖多边形的边和覆盖多边形轮廓边的交点。
③对交点进行排序。
④利用“包含性检验”,区分出被覆盖段和未覆盖段。
⑤绘图输出未覆盖线段。
2.多边形的布尔运算
1)布尔运算的概念
多边形的布尔运算指的是:在两个多边形之间进行并、交、差的运算。
2)多边形的描述
任何一个多边形均是由顶点和边组成的。
所以可以把多边形的数据结构组成两张数据表:顶点表和边表。
通常,在实际的布尔运算处理中,为了方便把多边形的边表改为环表。
环表是由组成多边形的顶点按照一定的顺序连接而成。
在环表中,每相邻两个顶点组成一条有向线段,它的方向与环的方向相同。
3)布尔运算的规则
在两个多边形有相互重叠的部分时,两个多边形可以进行布尔运算。
当两个多边形相互重叠时,表示两个多边形的两个环相交,其交点将有向直线段分为两部分:环内部分和环外部分,分别表示处于另一个环的内部或外部。
交点分为出点和入点两种:当一个环的有向线段经过交点进入另一环,则该交点称为入点;反之,如果是走出另一环,则该交点称为出点。
在进行布尔运算时,搜索新环的路径应该从交点处开始。
其运算规则如下:
(1)并运算顺着环的方向搜索,当遇到的交点为入点时,则从该点在另一环上的对应点转入另一环,然后沿另一环的方向搜索;当遇到的交点为出点时,则继续顺着本环进行。
(2)交运算顺着环的方向搜索,当遇到的交点为出点时,则从该点在另一环上的对应点转入另一环,然后沿另一环的方向搜索;当遇到的交点为入点时,则继续顺着本环进行。
(3)差运算进行差运算时,首先要将差环的原方向倒转过来,然后按照与并运算相同的规则进行处理。
曲线
曲线、曲面主要分为两种:
1.可以用一个称为标准方程解析式表示的,如圆、椭圆、双曲线、圆柱、圆球等。
2.大部分曲线是由实验数据来给出的,只有一些数据点,称为“型值点”。
常见二次曲线的绘制
1.绘制方法
(1)曲线的方程取参数方程。
(2)将曲线分割成很多短线段,用这些短线段来逼近曲线。
/*正弦曲线*/
#include <graphics.h>
#include <math.h>
#define PI 3.1415926
main()
{
intdlt,x;
float n0,s0,n,s,ds,dn;
intgdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,"");
setbkcolor(15);
setcolor(4);
dlt=3;
ds = sin(2 * dlt * PI/640);
dn= cos(2 * dlt * PI/640);
s0 = 0;
n0 = 1;
line (0,240,640,240);
moveto(0,240);
x=0;
while(x<640)
{
s = s0 * dn + n0 * ds;
n= n0 * dn- s0 * ds;
x = x + dlt;
lineto(x, 240 – 160* s);
s0 = s;
n0 = n;
}
getch();
closegraph();
}
曲线参数表示
参数表示:曲线上任一点的坐标均表示成给定参数的函数。
假定用t 表示参数,平面
曲线上任一点P 可表示为:[])(),()(
t y t x t P =
空间曲线上任一三维点P 可表示为:[])(),(),()(
t z t y t x t P =
参数表示例子:
直线]1,0[,
)()(
121∈-+=t t P P P t P
圆]1,0[12,11)(22
2∈⎥⎦⎤⎢⎣
⎡++-=t t t t t t P
参数表示的优点:
1)有更大的自由度来控制曲线、曲面的形状
2)对曲线、曲面进行变换,可对其参数方程直接进行几何变换。
3)便于处理斜率为无穷大的情形,不会因此而中断计算。
4)便于用户把低维空间中曲线、曲面扩展到高维空间去。
5)规格化的参数变量t ∈[0, 1],使其相应的几何分量是有界的,而不必用另外的参数去定义边界。
6)易于用矢量和矩阵表示几何分量,简化了计算。
位置矢量、切矢量
● 曲线上任一点的位置矢量可表示为: P(t)=[x(t), y(t), z(t)];
● ● ● ● ●
● 切向量(切矢量)
• 选择弧长s 作为参数,则
s P
ds dP T s ∆∆==
→∆0lim
• 于是有
)
()
(''t P t P ds dt dt dP ds dP =⋅=,即为单位矢量
插值、拟合、逼近
给定一组有序的数据点P i ,i=0, 1, …, n ,构造一条曲线顺序通过这些数据点,称为对
这些数据点进行插值,所构造的曲线称为插值曲线。
线性插值:假设给定函数f(x)在两个不同点x1和x2的值,用一个直线:y=ax+b
近似代替,称为线性插值。
抛物线插值:已知在三个互异点
321,,x x x 的函数值为321,,y y y ,要求构造一
个函数
c bx ax x ++=2
)(ϕ 使抛物线)(x ϕ在结点)3,2,1(=i x i 处与)(x f 在i x
处的值相等
拟合:构造一条曲线使之在某种意义下最接近给定的数据点(但未必通过这些点),所
构造的曲线为拟合曲线。
在计算数学中,逼近通常指用一些性质较好的函数近似表示一些性质不好的函数。
在计算机图形学中,逼近继承了这方面的含义,因此插值和拟合都可以视为逼近。
抛物样条曲线
1、抛物线样条的由来
最主要的由来是由于二次曲线是曲线中最简单的,用它来拟合一般型值点比较方便。
2、过三点定义一段抛物线
设不在同一条直线上的三点:P1,P2,P3,过P1,P2,P3三点抛物线方程为: 每相邻的四个点可以决定中间一段抛物线样条曲线。
2、曲线的讨论 (1)端点条件
)
(x 1
2
)
(x ϕ=123
(a)
(b)
图3.1.4 线性插值和抛物插值
前面我们讲到,在全部点列P*i+(I=1,2,…,n)中,我们只能得到n-3段曲线。
但n 个点之间应当有n-1个曲线段,因为点列的首、尾两段P[1]P[2]和P[n-1]P[n]由于缺乏连续相邻的四点这样的条件而无法产生。
为了产生首尾两段曲线,一个最直接的方法是在原点列的两端各加入一个辅助点P[0]和P[n+1]。
如何加上点P[0]和P[n+1]呢?通常有三种方法: (1)已知两端的切矢P*1+‘和P*n+‘. P*1+’=P*2+-P[0] ∴ P[0] =P[2]- P*1+’
P*1+’=P*2+-P[0] ∴ P[n+1] =P[n- 1++P*n+’ (2)自由端点
取P[0] =P[1]、P[n+1] =P[n] (3)形成封闭曲线
取P[n+1] =P[1] ,P[0] =P[n] ,P[n+2] =P[2] 2.抛物线样条的性质
我们可以证明,抛物样条是一阶光滑的。
连续性曲线间连接的光滑度的度量有两种:
● 函数的可微性:组合参数曲线在连接处具有直到n 阶连续导矢,即n 阶连续
可微,这类光滑度称之为或n 阶参数连续性。
● 几何连续性:组合曲线在连接处满足不同于的某一组约束条件,称为具有n
阶几何连续性,简记为。
若要求在结合处达到0G 连续或0C 连续,即两曲线在结合处位置连续:
)0()1(Q P = 若要求在结合处达到1G 连续,就是说两条曲线在结合处在满足0
G 连续的条件下,
并有公共的切矢
)0()1()0('
'>=ααP Q
当a =1时,1
G 连续就成为1
C 连续
若要求在结合处达到2
G 连续,就是说两条曲线在结合处在满足1
G 连续的条件下,并有公共的曲率矢:
三次参数曲线 代数形式
⎪⎪⎩
⎪⎪⎨⎧+++=∈+++=+++=z z z z y y y y x x x x a t a t a t a t z t a t a t a t a t y a t a t a t a t x 012233012
233012233)(]
1,0[)()(
● 上述代数式写成矢量式是
]1,0[)(0
12233∈+++=t a t a t a t a t P
几何形式
● 对三次参数曲线,若用其端点位矢P(0)、P(1)和切矢P¢(0)、P¢(1)描述。
● 将P(0)、P(1)、P¢(0)和P¢(1)简记为P 0、P 1、P¢0和P¢1,代入
得]1,0[)(
12233∈+++=t a t a t a t a t P
⎪⎪⎩⎪⎪⎨⎧+'+-=--+-==='
10103
'10'102'
010022233P P P P a P P P P a P a P a
令:
132)(230+-=t t t F 23132)(t t t F +-=t t t t G +-=2
302)(231)(t t t G -=
]1,0[)('
11'001100∈+++=t P G P G P F P F t P
可将其简化为:
上式是三次Hermite 曲线的几何形式,几何系数是P 0、P 1、P¢0和P¢1。
1010,,,G G F F 称为调和函数(或混合函数)
二维图形的运算 1.交点计算
1.1两直线段的交点。
和21S S ()
1111,的两个端点为y x P S ()()()4443332222,和,的两个端点为;,和y x P y x P S y x P
则两条直线段的参数方程为:
()()()
()()()1011014
322
11≤≤+-=≤≤+-=v
vP P v v S u uP P u u S
()()()()()
()
10
:10:34334321211211≤≤⎩⎨
⎧-+=-+=≤≤⎩⎨
⎧-+=-+=v v y y y y v x x x x S u u
y y y y u x x x x S
如果两条直线相交,则满足
()()()()
⎩⎨
⎧-+=-+-+=-+v y y y u y y y v
x x x u x x x 343121343121 04
3124
312≠----=
∆y y y y x x x x ⎪
⎪⎩
⎪⎪
⎨
⎧-
-
------=--------=4
3
12
43121
3121
3124312431243134
313y y y y x x x x y y y y x x x x v y y y y x x x x y y y y x x x x u
(1)Δ=0
方程组无解。
说明两条直线段所在直线相互平行或重合,所以不相交,没有交点产生。
(2)Δ≠0
方程组有唯一解。
如果0≤u ≤1则说明交点P 位于线段S 1上。
否则,交点P 位于线段S 1延长线上。
如果0≤v ≤1则说明交点P 位于线段S 2上。
否则,交点P 位于线段S 2延长线上。
所以,只有当0≤u ≤1和0≤v ≤1同时成立时,交点P 既位于线段S 1上又位于线段S 2上。
1.2直线与圆弧的交点 设直线AB 的方程为
⎩⎨
⎧≤≤-+=-+=)
10()
()(t t y y y y t x x x x a b a a b a
圆心为C(x c ,y c )半径为R 的圆弧的参数方程为
角和终止角。
分别表示圆弧的起始和)(sin cos e s e s c c R y y R x x αααααα
α
⎩⎨
⎧≤≤+=+=
如果直线段和圆弧相交,则有:
[][]22
2
)()(R t y y y t x x x
a b a a b a
=-++-+
02=++C Bt At 式中A,B,C 均可由已知点的坐标求得
当Δ=B 2-4AC ≤ 0时,直线和圆弧不相交。
当Δ=B 2-4AC >0时,前面的一元二次方程有两个不相等的实根t 1和t 2。
当满足0≤ t 1≤1或0≤ t 2≤1时,直线段才有可能与圆弧相交。
此时α可以通过
()()R
t
y y y y R
t x x x x a b c a
a b c a )(sin )(cos -+-=
-+-=αα
当求得的α满足αs ≤α≤αe 时,直线段才与圆弧相交。
2.关系判断
1.1.点的包含性检验
点的包含性检验是指:判断一个点是否被包含在某一个区域内。
区域通常是多边形。
通常有两种方法: (1)夹角和检验法
A
E
(a )被测点p 在多边形外(b )被测点p 在多边形内 (2)交点数检验法
● 由被测点P 处向y = - ∞方向作射线
● 交点个数是奇数,则被测点在多边形内部
● 否则,偶数,在多边形外部。
● 若射线正好经过多边形的顶点,当共享顶点的两边在射线的同一侧,则交点计数加
2,否则加1。
1.2多边形重叠性检验
其思想是用包含多边形的最小矩形来检测。
3.窗口运算
1.1.定义窗口和视区 1.
2.窗口-视区转换
假设在用户坐标系xoy 中定义一个窗口,其左下角坐标为(x l ,y b ),右上角坐标为(x r ,y t );在设备坐标系x *o *y *中定义一个窗口,其左下角坐标为(x l *,y b *),右上角坐标为(x r *,y t *);则有:
b t b t b l r l
r y y y y y y y y x x x x x x x x b l l --=
----=--*
*****
**
从窗口w 到视口v 的转换
⎩⎨⎧+=+=D Cy y B Ax x w v
w v ⎪
⎪⎪
⎪
⎭⎫
⎝
⎛⋅-=--=
⋅-=--=
WYB C VYB D WYB WYT VYB
VYT C WXL A VXL B WXL WXR VXL VXR A
1.直线的生成算法 1.1.逐点比较法 (1)算法流程
算法说明: ①偏差判别:按偏差来判断画笔的当前位置与规定图形的位置的偏差符号,以确定画笔下一步方向。
②画笔作图:给出x 向或y 向的走步信号,使画笔在该方向上移动一个步距。
③终点判断:判断当前画笔是否到终点。
④偏差计算:在新位置上计算作图偏差,作为偏差判别的依据。
如果把直线的起点设置在坐标原点,则规定直线处于4个不同的象限中时,画笔的走向如图所示。
(2)偏差计算 ①一般公式
设直线的终点为A(x a ,y a ),当前位置为M (x m ,y m )。
oA ,oM 与x 轴的夹角分别为α和β。
则偏差为
a
m a
m a m a a m m x x y x x y x y x y -=-=
-=αβδtan tan
由于上述公式的分母在所有的象限为正,故偏差判别式可简化为 F m =y m x a -x m y a 第一象限为例
当δ<0时,表示画笔在oA 线的下方,应该走+y 一步;当δ≥0,表示画笔在oA 线上或上方,此时则应该走+x 一步。
②简化公式
当F m <0时,应该走+y 一步,即x m+1=x m ,y m+1=y m +1。
则 F m +1=y m +1x a -y a x m+1= F m +x a
当F m ≥ 0时,应该走+x 一步,即x m+1=x m +1,y m+1=y m 。
则 F m +1=y m +1x a -y a x m+1= F m -y a
起始时,设F1=0,即假设画笔在直线段的起点。
③其它象限中的偏差计算公式 第二象限
当F m <0时,应该走-x 一步,即x m+1=x m -1,y m+1=y m 。
则 F m +1=y m +1x a -y a x m+1= F m +y a = F m +|y a |
当F m ≥ 0时,应该走+y 一步,即x m+1=x m ,y m+1=y m +1。
则 F m +1=y m +1x a -y a x m+1= F m +x a = F m -|x a | 三、四象限是类似的。
④终点判断
设绘图机的步长为t ,直线段在x,y 两个方向上的增量分别为∆x 和∆y ,则绘图笔从直线的起点走到直线的终点,在x 方
向应走∆x/t 步,在y 方向应走∆y/t 步。
两个方向上的总步数为(∆x/t+∆y/t)。
● 直线的扫描转换: 确定最佳逼近于该直线的一组象素,并且按扫描线顺序,将这些
象素存入到帧缓存的相应单元中。
● 三个常用算法:
数值微分法(DDA)
中点画线法
Bresenham算法。
数值微分(DDA)法
voidDDALine(int x0,int y0,int x1,int y1,int color)
{
int x;
float dx, dy, y, k;
dx, = x1-x0, dy=y1-y0;
k=dy/dx, y=y0;
for (x=x0; x≤x1, x++)
{drawpixel (x, int(y+0.5), color);
y=y+k;
}
}
注意上述分析的算法仅适用于|k|≤1的情形。
在这种情况下,x每增加1, y最多增加1。
当|k|>1时,必须把x,y地位互换
Bresenham算法
voidBresenhamline (int x0,int y0,int x1, int y1,int color) { int x, y, dx, dy;
float k, e;
dx = x1-x0, dy = y1- y0, k=dy/dx;
e=-0.5, x=x0, y=y0;
for (i=0; i≤dx; i++)
{ drawpixel (x, y, color);
x=x+1,e=e+k;
if (e≥0)
{ y++, e=e-1;}
}
}
2.圆弧的生成算法
2.1逐点比较法
用逐点比较法生成圆弧是在绘图笔每走完一步,就要把绘图笔当前的位置距圆心的距离与半径进行比较,根据比较结果决定下一步的走向。
这种方法是用阶梯折线来逼近圆弧。
如图所示:
由于画圆的方向有顺时针和逆时针两种,所以讨论圆弧的生成算法时,要分成顺时针和逆时针及4个象限8种情况。
1)偏差计算
(1)一般公式
设圆弧的起点为A(x a,y a),终点为B(x b,y b),圆心在原点。
则圆弧的半径为
R=(x a2+y a2)1/2
设画笔的当前位置为M(x m,y m),则画笔至圆心的距离为R m=(x m2+y m2)1/2
记
F m=R m2 -R a2=(x m2+y m2)-(x a2+y a2)
以第一象限为例,
当F m≥0时,即画笔在圆外或圆上,此时应向-x走步;
当F m< 0时,即画笔在圆内,此时应向+y走步;
(2)简化公式
当F m≥0时,此时应向-x走步,则x m+1=x m-1,y m+1=y m,从而
F m+1=(x m+12+y m+12)-(x a2+y a2)
=(x m2-2x m+ 1+ y m2)-(x a2+y a2)
=F m-2x m+ 1
当F m< 0时,此时应向+y走步,则x m+1=x m,y m+1=y m+1,从而
F m+1=(x m+12+y m+12)-(x a2+y a2)
=(x m2+ y m2 +2y m+ 1)-(x a2+y a2)
=F m+2y m+ 1
2)公式的推广
以逆圆第三象限为例。
当F m≥0时,此时应向+x走步,则x m+1=x m+1,y m+1=y m,从而
F m+1=(x m+12+y m+12)-(x a2+y a2)
=(x m2+2x m+ 1+ y m2)-(x a2+y a2)
=F m+2x m+ 1
当F m< 0时,此时应向-y走步,则x m+1=x m,y m+1=y m-1,从而
F m+1=(x m+12+y m+12)-(x a2+y a2)
=(x m2+ y m2 -2y m+ 1)-(x a2+y a2)
=F m-2y m+ 1
3)终点的判断。