图形算法:圆形生成算法

标签(空格分隔): 算法

版本:2
作者:陈小默
声明:禁止商用,禁止转载

发布于:作业部落、CSDN博客


圆的定义为所有距离中心位置 (xc,yc)
为定值 r
的点的集合1。在本章内容中,我们将会介绍三种常用的圆形生成算法:勾股定理算法极坐标算法中点圆算法

  • 图形算法圆形生成算法
  • 一算法导论
    • 1 四分法与八分法
    • 2 勾股定理算法
    • 3 极坐标算法
    • 4 中点圆算法

一、算法导论


1.1 四分法与八分法

由于圆具有对称性,只计算圆上一部分的值,再通过对称性将值变换到其他象限可以极大的减少计算量。

图 1.1-1
假如我们确定了圆在第一象限的位置,则可以通过变换 y
的符号去生成圆在第二象限的位置。我们再对上述生成的全部位置进行相对于 x
轴的符号变换就可以得到圆在第三四象限的位置。这就是四分法的基本思路。
图 1.1-2
在同一个象限内,如果按照 45o
进行分割,可以看出其坐标关于这个分割线是对称的。也就是在(0~45)度范围内的值可以通过简单变换映射到其他区域内。这种分割方式被称为圆的八分法。

1.2 勾股定理算法

在笛卡尔坐标系中,对于给定的原点 (xc,yc)
和半径 r
,圆上任意一点(x,y)
满足勾股定理

(xxc)2+(yyc)2=r2(1.2.1)

利用这个算法我们可以通过任意 x
值计算对应的 y

y=yc±r2(xcx)2(1.2.2)

现在我们通过示例程序演示该算法,仅展示思路,可使用任意语言或图形软件包实现。

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.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);}

图 1.2-2
在此示例中,我们先将圆计算时的圆心已原点(0,0)计算,在所有操作完成之后在平移到相应位置,这么做方便变换简化计算量。

总结:勾股定理算法简单,即使是使用八分法缩减运算规模,其大量复杂的开平方计算仍然是影响效率的关键因素。接下来,我们将介绍一种能够替换开平方运算的算法。

1.3 极坐标算法

极坐标系是一种常用的坐标系。其中坐标位置由到原点的极半径距离 r
和距水平轴的角 θ
指定。正的角位移是逆时针的,而负的角位移是逆时针的。利用三角函数的定义,可以从极坐标系转换为笛卡尔坐标系。

x=rcosθ,y=rsinθ(1.3.1)

通过式(1.3.1)我们可以通过下列方程组表示圆方程

x=xc+rcosθ(1.3.2)

y=yc+rsinθ(1.3.3)

使用上述方式以单位角度为步长,可以在圆周上以等距离的点来绘制圆。

下面将使用程序展示极坐标算法的计算过程

    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.3-1

总结:我们可以从图中看出其边缘有毛刺状突起,这是因为极坐标系运算以角度为步长而不是任何一个轴,这就导致其结果取整后不仅仅只会在一个方向上浮动。从效率的角度上说,虽然极坐标系统提供了等距离点,但是其三角函数计算仍然十分耗时。

1.4 中点圆算法

我们可以参照直线算法中的Bresenham算法,以决策参数的增量运算为基础,将圆的计算过程转换为简单的整数加减运算。

如同画线算法,我们在每一步中以单位间隔取样并确定离圆最近的像素位置。对于给定半径 r
和屏幕中心 (xc,yc)
,可以现将圆的圆心放在坐标原点运算,在运算完成之后,再将圆移动到相应的位置。

为了应用中点圆算法,我们先定义一个圆函数

fcirc(x,y)=x2+y2r2(1.4.1)

任意一点 (x,y)
均满足

f(n)=<0,=0,>0,(x,y)(x,y)(x,y)(1.4.2)

我们需要使用(1.4.2)对每一个取样步上对接近圆周的两个像素的中点进行测试。因此,在中点算法中,圆函数(1.4.1)是决策参数。

图 1.4-1

[1.4-1] 给出了取样位置 xk+1
上的中点,我们可以取出中点的坐标 (xk+1,(yk+yk1)/2)
也就是点 (xk+1,yk12)
,接下来,我们只需要将中点位置代入方程(1.4.1)就可以算出决策参数

pk=fcirc(xk+1,yk12)=(xk+1)2+(yk12)2r2(1.4.3)

如果 pk<0
,那么这个圆的轨迹在中点的上方,所以我们选择扫描 yk
这个像素,否则,我们扫描 yk1
这个像素。

接下来我们要寻找决策增量之间的关系。这使用了我们中学所学的数学归纳法。通过任意相邻两点之间的关系递推整个决策的关系。

通过式(1.4.4)我们可以求出下一个决策参数

pk=1=fcirc(xk+1+1,yk+112)=[(xk+1)+1]2+(yk+112)2r2(1.4.4)

我们可以找出相邻的两个决策参数之间的关系

pk+1=pk+2(xk+2)+(ykyk+1)(1.4.5)

其中 yk+1
yk
或者是 yk1
具体取值取决于 pk
的符号。

我们已经计算出了决策增量的关系,接下来只需要计算出决策增量的初始值即可,对于圆心在坐标原点,半径为 r
的圆来说,假设第一点从(0,r)
处起笔

p0=fcirc(1,r12)=1+(r12)2r2=54r(1.4.6)

如果为了简化运算,我们可以将决策参数近似为整数,而不用浮点数,其中 r
也是整数

p0=1r(1.4.7)

接下来我们将使用一段代码来解释其流程:

    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);}

图 1.4-2

图中示例分别为勾股定理(左),极坐标系(中)和中点算法(右)


  1. 计算机图形学第四版.电子工业出版社.109~114 ↩

图形算法:圆形生成算法相关推荐

  1. 算法 - 随机密码生成算法

    算法 - 随机密码生成算法 import java.util.Random;/*** Created by 谭健 on 2017/10/16. 11:13.* © All Rights Reserve ...

  2. C4.5决策树生成算法完整版(Python),连续属性的离散化, 缺失样本的添加权重处理, 算法缺陷的修正, 代码等

    C4.5决策树生成算法完整版(Python) 转载请注明出处:©️ Sylvan Ding ID3算法实验 决策树从一组无次序.无规则的事例中推理出决策树表示的分类规则,采用自顶向下的递归方式,在决策 ...

  3. 从一维cutting问题看列生成算法

    从一维cutting问题看列生成算法 列生成算法 一维cutting问题 列生成原理 集合覆盖模型 列生成步骤说明 python 代码实现 列生成算法 列生成在求解大型线性规划时往往都表现良好,在很多 ...

  4. 基于材料生成算法的工程优化

    文章目录 一.理论基础 1.材料生成算法 (1)模拟化合物 (2)模拟化学反应 (3)模拟化学稳定性 2.MGA算法流程图 二.仿真实验与分析 三.参考文献 一.理论基础 1.材料生成算法 材料生成算 ...

  5. 计算机地图制图原理与算法,计算机地图制图原理与方法-基本图形生成算法.ppt...

    <计算机地图制图原理与方法-基本图形生成算法.ppt>由会员分享,可在线阅读,更多相关<计算机地图制图原理与方法-基本图形生成算法.ppt(35页珍藏版)>请在人人文库网上搜索 ...

  6. 计算机图形生成的基本单位是,第五章 基本图形生成算法

    如何在指定的输出设备上根据坐标描述构造基本二维几何图形(点.直线.圆.椭圆.多边形域.字符串及其相关属性等). 图形生成的概念 图形的生成:是在指定的输出设备上,根据坐标描述构造二维几何图形. 图形的 ...

  7. 计算机图形学期末复习之第四章:基本图形生成算法

    可能这会是图形学期末复习最后一个整理了, 感觉其实不如直接看PPT. 1.填空20+选择20+判断10+简答20+综合30 2.没有编程题 3.复习PPT上的基本概念和算法 计算机图形学期末复习之第四 ...

  8. 计算机图形学-基本图形生成算法

    基本图形生成算法 图元扫描转换 直线段扫描转换 圆弧扫描转换 实区域填充 图形的剪裁 图形反走样 消隐 光栅化算法 线段光栅化算法     DDA算法 中点Bresenham画线算法 Bresenha ...

  9. [20] 鼓状物(Drum)图形的生成算法

    顶点数据的生成 1 bool YfBuildDrumVertices 2 ( 3 Yreal radius, 4 Yreal assistRadius, 5 Yuint slices, 6 Yuint ...

最新文章

  1. P1160 队列安排
  2. mac 查看mysql是否安装_[简明核心系列] 三分钟Mac安装MySQL教程
  3. cad字体安装_浩辰CAD与AutoCAD兼容性测评大起底!
  4. C++编程思想:指针,引用,拷贝构造函数,赋值运算符
  5. SAP Fiori里Contact Support的按钮渲染逻辑
  6. 蓝桥杯 作物杂交 DFS搜索
  7. Magento调用静态块 static block
  8. ASP母版页与内容页不同目录 链接问题
  9. 【房价预测】基于matlab GUI BP神经网络房价预测【含Matlab源码 972期】
  10. 【模拟考勤打卡程序vim报错分享】
  11. XP WIN7局域网共享传输速度
  12. 区块链技术最佳的监管方式是智能合约监管智能合约
  13. Steam游戏服务器配置选择 IP
  14. iperf测试交换机流量
  15. 和用户一起做设计的时代
  16. 东周列国 演绎版 mp3
  17. Android WebView 调用JS方法获取返回值
  18. 水桶服务器1.7.10服务器文件,我的世界1.7.10怎么开水桶服务器
  19. Unity3D 图片空间和内存占用分析
  20. 华为鸿蒙系统智能手机_华为宣布推出鸿蒙2.0系统 首款“鸿蒙手机”年底登场...

热门文章

  1. 游资会带散户炒股吗?
  2. Rsync 备份服务:基本概述、应用场景、传输模式、注意事项、密码解决方案、服务实践、备份案例、结合inotify
  3. QT中窗口置顶失效问题解决方案
  4. 漫画:什么是 “幼态持续” ?
  5. JavaScript Web APIs部分参考pink老师ppt(网页常见的js案例)
  6. Android拍摄视频上传服务器及本地预览
  7. Android客户端与PHP服务端API接口Token安全验证
  8. 明光市机器人_明光市安保巡逻机器人在线咨询
  9. 通向Golang的捷径【Top】
  10. phpoffice/phpword 表格合并和表格绝对居中