图形算法:圆形生成算法
图形算法:圆形生成算法
标签(空格分隔): 算法
版本:2
作者:陈小默
声明:禁止商用,禁止转载
发布于:作业部落、CSDN博客
圆的定义为所有距离中心位置 (xc,yc)
为定值 r
的点的集合1。在本章内容中,我们将会介绍三种常用的圆形生成算法:勾股定理算法、极坐标算法和中点圆算法。
- 图形算法圆形生成算法
- 一算法导论
- 1 四分法与八分法
- 2 勾股定理算法
- 3 极坐标算法
- 4 中点圆算法
一、算法导论
1.1 四分法与八分法
由于圆具有对称性,只计算圆上一部分的值,再通过对称性将值变换到其他象限可以极大的减少计算量。
假如我们确定了圆在第一象限的位置,则可以通过变换 y
的符号去生成圆在第二象限的位置。我们再对上述生成的全部位置进行相对于 x
轴的符号变换就可以得到圆在第三四象限的位置。这就是四分法的基本思路。
在同一个象限内,如果按照 45o
进行分割,可以看出其坐标关于这个分割线是对称的。也就是在(0~45)度范围内的值可以通过简单变换映射到其他区域内。这种分割方式被称为圆的八分法。
1.2 勾股定理算法
在笛卡尔坐标系中,对于给定的原点 (xc,yc)
和半径 r
,圆上任意一点(x,y)
满足勾股定理
利用这个算法我们可以通过任意 x
值计算对应的 y
值
现在我们通过示例程序演示该算法,仅展示思路,可使用任意语言或图形软件包实现。
void Pythagorean(int x,int y,int r){//使用勾股定理绘制圆int start = x-r;int end = r+x;_IntArray _arr;int size = 4*(end-start);_arr = new IntArray(size);IntArray_ arr = *_arr;int r2 = r*r;for(int i=start,j=0;i<end;i++){int p = sqrt(float(r2-power(x-i)));arr[j++]=i;arr[j++]=y+p;arr[j++]=i;arr[j++]=y-p;}_list->add(_arr);}
通过结果 [图 1.2-1]
我们可以看出直接使用勾股定理会造成像素间距不一致的问题。处理方法有两种:第一种是在斜率的绝对值大于1后,交换 x
和y
来调整间距;第二种方式是使用1.1节
中提到的八分法。我们只需要计算八分之一的图形,剩下的操作就是简单映射即可。以下是使用八分法的示例
void Pythagorean(int xc,int yc,int r){//使用勾股定理和八分法绘制圆int len = int(1+0.5*sqrt(2.0)*r);int size = 16*len;_IntArray _arr = new IntArray(size);IntArray_ arr = *_arr;int r2 = r*r;int j=0;for(int x=0;x<len;x++){int p = sqrt(float(r2-power(x)));arr[j++]=x;arr[j++]=p;}int k=j;for(int i=0;i<k;i+=2){arr[j++] = arr[i+1];arr[j++] = arr[i];}k = j;for(int i=0;i<k;i+=2){arr[j++] = arr[i];arr[j++] = -arr[i+1];}k = j;for(int i=0;i<k;i+=2){arr[j++] = -arr[i];arr[j++] = arr[i+1];}for(int i=0;i<j;i+=2){arr[i]+=xc;arr[i+1]+=yc;}_list->add(_arr);}
在此示例中,我们先将圆计算时的圆心已原点(0,0)计算,在所有操作完成之后在平移到相应位置,这么做方便变换简化计算量。
总结:勾股定理算法简单,即使是使用八分法缩减运算规模,其大量复杂的开平方计算仍然是影响效率的关键因素。接下来,我们将介绍一种能够替换开平方运算的算法。
1.3 极坐标算法
极坐标系是一种常用的坐标系。其中坐标位置由到原点的极半径距离 r
和距水平轴的角 θ
指定。正的角位移是逆时针的,而负的角位移是逆时针的。利用三角函数的定义,可以从极坐标系转换为笛卡尔坐标系。x=rcosθ,y=rsinθ(1.3.1)
通过式(1.3.1)我们可以通过下列方程组表示圆方程
使用上述方式以单位角度为步长,可以在圆周上以等距离的点来绘制圆。
下面将使用程序展示极坐标算法的计算过程
void Polar(int xc,int yc,int r){//使用极坐标系绘制圆int point = 2;//每一度绘制两个点double angle = 1.0/point;//每两个点之间的角度int size = point*45*8*2;//使用八分法,_IntArray _arr = new IntArray(size);IntArray_ arr = *_arr;int j=0;for(int i=0;i<45;i++){for(int m=0;m<point;m++){arr[j++] = int(r*cos(((i+angle*m)*(PI/180))));//使用c库中的三角函数需要将角度转换为弧度arr[j++] = int(r*sin(((i+angle*m)*(PI/180))));}}int k=j;for(int i=0;i<k;i+=2){arr[j++] = arr[i+1];arr[j++] = arr[i];}k = j;for(int i=0;i<k;i+=2){arr[j++] = arr[i];arr[j++] = -arr[i+1];}k = j;for(int i=0;i<k;i+=2){arr[j++] = -arr[i];arr[j++] = arr[i+1];}for(int i=0;i<j;i+=2){arr[i]+=xc;arr[i+1]+=yc;}_list->add(_arr);}
总结:我们可以从图中看出其边缘有毛刺状突起,这是因为极坐标系运算以角度为步长而不是任何一个轴,这就导致其结果取整后不仅仅只会在一个方向上浮动。从效率的角度上说,虽然极坐标系统提供了等距离点,但是其三角函数计算仍然十分耗时。
1.4 中点圆算法
我们可以参照直线算法中的Bresenham算法,以决策参数的增量运算为基础,将圆的计算过程转换为简单的整数加减运算。
如同画线算法,我们在每一步中以单位间隔取样并确定离圆最近的像素位置。对于给定半径 r
和屏幕中心 (xc,yc)
,可以现将圆的圆心放在坐标原点运算,在运算完成之后,再将圆移动到相应的位置。
为了应用中点圆算法,我们先定义一个圆函数
任意一点 (x,y)
均满足
我们需要使用(1.4.2)对每一个取样步上对接近圆周的两个像素的中点进行测试。因此,在中点算法中,圆函数(1.4.1)是决策参数。
图 [1.4-1]
给出了取样位置 xk+1
上的中点,我们可以取出中点的坐标 (xk+1,(yk+yk−1)/2)
也就是点 (xk+1,yk−12)
,接下来,我们只需要将中点位置代入方程(1.4.1)就可以算出决策参数
如果 pk<0
,那么这个圆的轨迹在中点的上方,所以我们选择扫描 yk
这个像素,否则,我们扫描 yk−1
这个像素。
接下来我们要寻找决策增量之间的关系。这使用了我们中学所学的数学归纳法。通过任意相邻两点之间的关系递推整个决策的关系。
通过式(1.4.4)我们可以求出下一个决策参数
我们可以找出相邻的两个决策参数之间的关系
其中 yk+1
是 yk
或者是 yk−1
具体取值取决于 pk
的符号。
我们已经计算出了决策增量的关系,接下来只需要计算出决策增量的初始值即可,对于圆心在坐标原点,半径为 r
的圆来说,假设第一点从(0,r)
处起笔
如果为了简化运算,我们可以将决策参数近似为整数,而不用浮点数,其中 r
也是整数
接下来我们将使用一段代码来解释其流程:
void Bresenham(int xc,int yc,int r){//使用中点圆算法int j = 0;int p = 1-r;//这里计算出的p0使用近似的整型来简化运算int x = 0;int y = r;int size = 16*int(1+0.5*sqrt(2.0)*r);//整个运算过程会产生size/2个点_IntArray _arr = new IntArray(size);IntArray_ arr = *_arr;for(int i=x;i<y;i++){arr[j++] = x++;if(p<0){//决策参数小于0说明中点在圆内,所以点要绘制在上方arr[j++] = y;p+=2*x+1;}else{arr[j++] = y--;p+=2*x+1-2*y;}}int k=j;for(int i=0;i<k;i+=2){arr[j++] = arr[i+1];arr[j++] = arr[i];}k = j;for(int i=0;i<k;i+=2){arr[j++] = arr[i];arr[j++] = -arr[i+1];}k = j;for(int i=0;i<k;i+=2){arr[j++] = -arr[i];arr[j++] = arr[i+1];}for(int i=0;i<j;i+=2){arr[i]+=xc;arr[i+1]+=yc;}_list->add(_arr);}
图中示例分别为勾股定理(左),极坐标系(中)和中点算法(右)
- 计算机图形学第四版.电子工业出版社.109~114 ↩
图形算法:圆形生成算法相关推荐
- 算法 - 随机密码生成算法
算法 - 随机密码生成算法 import java.util.Random;/*** Created by 谭健 on 2017/10/16. 11:13.* © All Rights Reserve ...
- C4.5决策树生成算法完整版(Python),连续属性的离散化, 缺失样本的添加权重处理, 算法缺陷的修正, 代码等
C4.5决策树生成算法完整版(Python) 转载请注明出处:©️ Sylvan Ding ID3算法实验 决策树从一组无次序.无规则的事例中推理出决策树表示的分类规则,采用自顶向下的递归方式,在决策 ...
- 从一维cutting问题看列生成算法
从一维cutting问题看列生成算法 列生成算法 一维cutting问题 列生成原理 集合覆盖模型 列生成步骤说明 python 代码实现 列生成算法 列生成在求解大型线性规划时往往都表现良好,在很多 ...
- 基于材料生成算法的工程优化
文章目录 一.理论基础 1.材料生成算法 (1)模拟化合物 (2)模拟化学反应 (3)模拟化学稳定性 2.MGA算法流程图 二.仿真实验与分析 三.参考文献 一.理论基础 1.材料生成算法 材料生成算 ...
- 计算机地图制图原理与算法,计算机地图制图原理与方法-基本图形生成算法.ppt...
<计算机地图制图原理与方法-基本图形生成算法.ppt>由会员分享,可在线阅读,更多相关<计算机地图制图原理与方法-基本图形生成算法.ppt(35页珍藏版)>请在人人文库网上搜索 ...
- 计算机图形生成的基本单位是,第五章 基本图形生成算法
如何在指定的输出设备上根据坐标描述构造基本二维几何图形(点.直线.圆.椭圆.多边形域.字符串及其相关属性等). 图形生成的概念 图形的生成:是在指定的输出设备上,根据坐标描述构造二维几何图形. 图形的 ...
- 计算机图形学期末复习之第四章:基本图形生成算法
可能这会是图形学期末复习最后一个整理了, 感觉其实不如直接看PPT. 1.填空20+选择20+判断10+简答20+综合30 2.没有编程题 3.复习PPT上的基本概念和算法 计算机图形学期末复习之第四 ...
- 计算机图形学-基本图形生成算法
基本图形生成算法 图元扫描转换 直线段扫描转换 圆弧扫描转换 实区域填充 图形的剪裁 图形反走样 消隐 光栅化算法 线段光栅化算法 DDA算法 中点Bresenham画线算法 Bresenha ...
- [20] 鼓状物(Drum)图形的生成算法
顶点数据的生成 1 bool YfBuildDrumVertices 2 ( 3 Yreal radius, 4 Yreal assistRadius, 5 Yuint slices, 6 Yuint ...
最新文章
- P1160 队列安排
- mac 查看mysql是否安装_[简明核心系列] 三分钟Mac安装MySQL教程
- cad字体安装_浩辰CAD与AutoCAD兼容性测评大起底!
- C++编程思想:指针,引用,拷贝构造函数,赋值运算符
- SAP Fiori里Contact Support的按钮渲染逻辑
- 蓝桥杯 作物杂交 DFS搜索
- Magento调用静态块 static block
- ASP母版页与内容页不同目录 链接问题
- 【房价预测】基于matlab GUI BP神经网络房价预测【含Matlab源码 972期】
- 【模拟考勤打卡程序vim报错分享】
- XP WIN7局域网共享传输速度
- 区块链技术最佳的监管方式是智能合约监管智能合约
- Steam游戏服务器配置选择 IP
- iperf测试交换机流量
- 和用户一起做设计的时代
- 东周列国 演绎版 mp3
- Android WebView 调用JS方法获取返回值
- 水桶服务器1.7.10服务器文件,我的世界1.7.10怎么开水桶服务器
- Unity3D 图片空间和内存占用分析
- 华为鸿蒙系统智能手机_华为宣布推出鸿蒙2.0系统 首款“鸿蒙手机”年底登场...