没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![application/x-zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![thumb](https://img-home.csdnimg.cn/images/20210720083646.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pptx](https://img-home.csdnimg.cn/images/20210720083543.png)
![](https://csdnimg.cn/release/download_crawler_static/89463451/bg1.jpg)
算法系列之九:计算几何与图形学有关的几种常用算法(一)
分类: 算法系列 2011-12-18 23:13 8182 人阅读 评论(41) 收藏 举报
我的专业是计算机辅助设计(CAD),算是一半机械一半软件,《计算机
图形学》是必修课,也是我最喜欢的课程。热衷于用代码摆平一切的我几乎将这
本教科书上的每种算法都实现了一遍,这种重复劳动虽然意义不大,但是收获很
多,特别是丢弃了多年的数学又重新回到了脑袋中,算是最大的收获吧。尽管已
经毕业多年了,但是每次回顾这些算法的代码,都觉得内心十分澎湃,如果换成
现在的我,恐怕再也不会有动力去做这些事情了。
在学习《计算机图形学》之前,总觉得很多东西高深莫测,但实际掌握了
之后,却发现其中了无神秘可言,就如同被原始人像神一样崇拜的火却被现代人
叼在嘴上玩弄一样的感觉。图形学的基础之一就是计算几何,但是没有理论数学
那么高深莫测,它很有实践性,有时候甚至可以简单到匪夷所思。计算几何是随
着计算机和 CAD 的应用而诞生的一门新兴学科,在国外被称为“计算机辅助几何
设计(Computer Aided Geometric Design,CAGD)”。“算法系列”接下来的几
篇文章就会介绍一些图形学中常见的计算几何算法(顺便晒晒我的旧代码),都
是一些图形学中的基础算法,需要一些图形学的知识和数学知识,但是都不难。
不信?那就来看看到底有多难。
本文是第一篇,主要是一些图形学常用的计算几何方法,涉及到向量、点
线关系以及点与多边形关系求解等数学知识,还有一些平面几何的基本原理。事
先声明一下,文中涉及的算法实现都是着眼于解释原理以及揭示算法实质的目的,
在算法效率和可读性二者的考量上,更注重可读性,有时候为了提高可读性会刻
意采取“效率不高”的代码形式,实际工程中使用的代码肯定更紧凑更高效,但是
算法原理都是一样的,请读者们对此有正确的认识。
一、 判断点是否在矩形内
计算机图形学和数学到底有什么关系?我们先来看几个例子,增加一些感
性认识。首先是判断一个点是否在矩形内的算法,这是一个很简单的算法,但是
![](https://csdnimg.cn/release/download_crawler_static/89463451/bg2.jpg)
却非常重要。比如你在一个按钮上点击鼠标,系统如何知道你要触发这个按钮对
应的事件而不是另一个按钮?对了,就是一个点是否在矩形内的判断处理。
Windows 的 API 提供了 PtInRect()函数,实现方法其实就是判断点的 x 坐标和 y
坐标是否同时落在矩形的 x 坐标范围和 y 坐标范围内,算法实现也很简单:
150 bool IsPointInRect(const Rect& rc, const Point& p)
151 {
152 double xr = (p.x - rc.p1.x) * (p.x - rc.p2.x);
153 double yr = (p.y - rc.p1.y) * (p.y - rc.p2.y);
154
155 return ( (xr <= 0.0) && (yr <= 0.0) );
156 }
看看 IsPointInRect()函数的实现是否和你想象的不一样?有时候硬件实现乘法
有困难或受限制于 CPU 乘法指令的效率,可以考虑用下面的函数替换,代码繁
琐了一点,但是避免了乘法运算:
120 bool IsPointInRect(const Rect& rc, const Point& p)
121 {
122 double xl,xr,yt,yb;
123
124 if(rc.p1.x < rc.p2.x)
125 {
126 xl = rc.p1.x;
127 xr = rc.p2.x;
128 }
129 else
130 {
131 xl = rc.p2.x;
132 xr = rc.p1.x;
133 }
134
135 if(rc.p1.y < rc.p2.y)
136 {
137 yt = rc.p2.y;
138 yb = rc.p1.y;
139 }
140 else
141 {
142 yt = rc.p1.y;
143 yb = rc.p2.y;
144 }
145
![](https://csdnimg.cn/release/download_crawler_static/89463451/bg3.jpg)
146 return ( (p.x >= xl && p.x <= xr) && (p.y >= yb && p.y <=
yt) );
147 }
由于 IsPointInRect()函数并不假设矩形的两个定点是按照坐标轴升序排列的,所
以算法实现时就考虑了所有可能的坐标范围。IsPointInRect()函数使用的是平面
直角坐标系,如果不特别说明,本文所有的算法都是基于平面直角坐标系设计的。
另外,IsPointInRect()函数没有指定特别的浮点数精度范围,默认是系统浮点数
的最大精度,只在某些必须要与 0 比较的情况下,采用 10
-8
次方精度,如无特
别说明,本文的所有算法都这样处理。
一、 判断点是否在圆内
现在考虑复杂一点,如果图形界面的按钮不是矩形而是圆形的怎么办呢?
当然就是判断点是否在圆内部。判断算法的原理就是计算点到圆心的距离 d,然
后与圆半径 r 进行比较,若 d < r 则说明点在圆内,若 d = r 则说明点在圆上,若
d > r 则说明点在圆外。这就要提到计算平面上两点距离的算法。以下图为例,
计算平面上任意两点之间的距离主要依据著名的勾股定理:
图 1 平面两点距离计算示意图
![](https://csdnimg.cn/release/download_crawler_static/89463451/bg4.jpg)
113 //计算欧氏几何空间内平面两点的距离
114 double PointDistance(const Point& p1, const Point& p2)
115 {
116 return std::sqrt( (p1.x-p2.x)*(p1.x-p2.x)
117 + (p1.y-p2.y)*(p1.y-p2.y) );
118 }
一、 判断点是否在多边形内
现在再考虑复杂一点的,如果按钮是个不规则的多边形区域怎么办?别以
为这个考虑没有意义,很多多媒体软件和游戏,通常都是用各种形状的不规则图
案作为热点(Hot Spot),Windows 也提供了 PtInRegion() API,用于判断点是
否在一个不规则区域中。我们对问题做一个简化,就判断一个点是否在多边形内?
判断点 P 是否在多边形内是计算几何中一个非常基本的算法,最常用的方法是
射线法。以 P 点为端点,向左方做射线 L,然后沿着 L 从无穷远处开始向 P 点
移动,当遇到多边形的某一条边时,记为与多边形的第一个交点,表示进入多边
形内部,继续移动,当遇到另一个交点时,表示离开多边形内部。由此可知,
当 L 与多边形的交点个数是偶数时,表示 P 点在多边形外,当 L 与多边形交点
个数是奇数时,表示 P 点在多边形内部。
由此可见,要实现判断点是否在多边形内的算法,需要知道直线段求交算
法,而求交算法又涉及到矢量的一些基本概念,因此在实现这个算法之前,先讲
一下矢量的基本概念以及线段求交算法。
3.1 矢量的基础知识
什么是矢量?简单地讲,就是既有大小又有方向的量,数学中又常被称为
向量。矢量有几何表示、代数表示和坐标表示等多种表现形式,本文讨论的是几
何表示。如果一条线段的端点是有次序之分的,我们把这种线段成为有向线段
(Directed Segment),比如线段 P
1
P
2
,如果起始端点 P
1
就是坐标原点(0, 0),
P
2
的坐标是(x, y),则线段 P
1
P
2
的二维矢量坐标表示就是 P= (x, y)。
剩余19页未读,继续阅读
资源评论
![avatar-default](https://csdnimg.cn/release/downloadcmsfe/public/img/lazyLogo2.1882d7f4.png)
![avatar](https://profile-avatar.csdnimg.cn/45bb3dfef5b44d4dbfa924f0e5a9e163_liuning940307.jpg!1)
随风浪仔
- 粉丝: 715
- 资源: 2939
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![voice](https://csdnimg.cn/release/downloadcmsfe/public/img/voice.245cc511.png)
![center-task](https://csdnimg.cn/release/downloadcmsfe/public/img/center-task.c2eda91a.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![dialog-icon](https://csdnimg.cn/release/downloadcmsfe/public/img/green-success.6a4acb44.png)