一、中点画圆法

首先是中点画圆法,考虑圆心在原点,半径为R的圆在第一象限内的八分之一圆弧,从点(0, R)到点(R/ , R/ )顺时针方向确定这段圆弧。假定某点Pi(xi, yi)已经是该圆弧上最接近实际圆弧的点,那么Pi的下一个点只可能是正右方的P1或右下方的P2两者之一,如图所示:

构造判别函数:F(x, y)= x2 + y2 – R2

当F(x, y)= 0,表示点在圆上,当F(x, y)> 0,表示点在圆外,当F(x, y)< 0,表示点在圆内。如果M是P1和P2的中点,则M的坐标是(xi + 1, yi – 0.5),当F(xi + 1, yi – 0.5)< 0时,M点在圆内,说明P1点离实际圆弧更近,应该取P1作为圆的下一个点。同理分析,当F(xi + 1, yi – 0.5)> 0时,P2离实际圆弧更近,应取P2作为下一个点。当F(xi + 1, yi – 0.5)= 0时,P1和P2都可以作为圆的下一个点,算法约定取P2作为下一个点。

现在将M点坐标(xi + 1, yi – 0.5)带入判别函数F(x, y),得到判别式d:

d = F(xi + 1, yi – 0.5)= (xi + 1)2 + (yi – 0.5)2 – R2

若d < 0,则取P1为下一个点,此时P1的下一个点的判别式为:

d’ = F(xi + 2, yi – 0.5)= (xi + 2)2 + (yi – 0.5)2 – R2

展开后将d带入可得到判别式的递推关系:

d’ = d + 2xi + 3

若d > 0,则取P2为下一个点,此时P2的下一个点的判别式为:

d’ = F(xi + 2, yi – 1.5)= (xi + 2)2 + (yi – 1.5)2 – R2

展开后将d带入可得到判别式的递推关系:

d’ = d + 2(xi - yi) + 5

特别的,在第一个象限的第一个点(0, R)时,可以推倒出判别式d的初始值d0:

d0 = F(1, R – 0.5) = 1 – (R – 0.5)2 – R2 = 1.25 - R

根据上面的分析,可以写出中点画圆法的算法。考虑到圆心不在原点的情况,需要对计算出来的坐标进行了平移,下面就是通用的中点画圆法的源代码:

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#define x0 400
#define y0 300                    //定义全局变量x0,y0:坐标轴中心(x0,y0)
void Middle_point_draw_circle(int x1, int y1, int r)
{int d0, x = 0, y = r;//d0是判别式的值d0 = 1.25 - r;   //判别式的初始值,1.25可以改为1while (x < y) {if (d0 >= 0) {d0 = d0 + 2 * (x - y) + 5;            //d0一定要先比x,y更新x += 1;                //因为d0表达式中的x,y是上一个点y -= 1;putpixel(((x + x1) + x0), (y0 - (y + y1)), RED);         //(x,y)putpixel(((-x + x1) + x0), (y0 - (y + y1)), RED);        //(-x,y)putpixel(((y + x1) + x0), (y0 - (x + y1)), RED);         //(y,x)putpixel(((-y + x1) + x0), (y0 - (x + y1)), RED);        //(-y,x)putpixel(((x + x1) + x0), (y0 - (-y + y1)), RED);        //(x,-y)putpixel(((-x + x1) + x0), (y0 - (-y + y1)), RED);       //(-x,-y)putpixel(((y + x1) + x0), (y0 - (-x + y1)), RED);        //(y,-y)putpixel(((-y + x1) + x0), (y0 - (-x + y1)), RED);       //(-y,-x)Sleep(50);}else {d0 = d0 + 2 * x + 3;x += 1;y = y;putpixel(((x + x1) + x0), (y0 - (y + y1)), RED);         //(x,y)putpixel(((-x + x1) + x0), (y0 - (y + y1)), RED);        //(-x,y)putpixel(((y + x1) + x0), (y0 - (x + y1)), RED);         //(y,x)putpixel(((-y + x1) + x0), (y0 - (x + y1)), RED);        //(-y,x)putpixel(((x + x1) + x0), (y0 - (-y + y1)), RED);        //(x,-y)putpixel(((-x + x1) + x0), (y0 - (-y + y1)), RED);       //(-x,-y)putpixel(((y + x1) + x0), (y0 - (-x + y1)), RED);        //(y,-y)putpixel(((-y + x1) + x0), (y0 - (-x + y1)), RED);       //(-y,-x)Sleep(50);}}
}
void main()
{int x1, y1, r;printf("请输入中点画圆算法圆心坐标(x1,y1)和圆的半径r:\n");scanf("%d %d %d", &x1, &y1, &r);initgraph(x0 * 2, y0 * 2);           //初始化图形窗口大小setbkcolor(WHITE);cleardevice();setcolor(BLACK);line(x0, 0, x0, y0 * 2);         //坐标轴Xline(0, y0, x0 * 2, y0);           //坐标轴YMiddle_point_draw_circle(x1, y1, r);             //中点画圆算法_getch();                                        //等待一个任意输入结束closegraph();                                    //关闭图形窗口
}

运行结果:

二、Bresenham算法

中点画圆法中,计算判别式d使用了浮点运算,影响了圆的生成效率。如果能将判别式规约到整数运算,则可以简化计算,提高效率。于是人们针对中点画圆法进行了多种改进,其中一种方式是将d的初始值由1.25 – R改成1 – R,考虑到圆的半径R总是大于2,因此这个修改不会响d的初始值的符号,同时可以避免浮点运算。还有一种方法是将d的计算放大两倍,同时将初始值改成3 – 2R,这样避免了浮点运算,乘二运算也可以用移位快速代替,采用3 – 2R为初始值的改进算法,称为Bresenham算法。

源代码展示:

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#define x0 400
#define y0 300                    //定义全局变量x0,y0:坐标轴中心(x0,y0)
void Middle_point_draw_circle(int x1, int y1, int r)
{int d0, x = 0, y = r;//d0是判别式的值d0 = 3 - 2*r;   //判别式的初始值while (x < y) {if (d0 >= 0) {d0 = d0 + 4 * (x - y) + 10;            //d0一定要先比x,y更新x += 1;                //因为d0表达式中的x,y是上一个点y -= 1;putpixel(((x + x1) + x0), (y0 - (y + y1)), RED);         //(x,y)putpixel(((-x + x1) + x0), (y0 - (y + y1)), RED);        //(-x,y)putpixel(((y + x1) + x0), (y0 - (x + y1)), RED);         //(y,x)putpixel(((-y + x1) + x0), (y0 - (x + y1)), RED);        //(-y,x)putpixel(((x + x1) + x0), (y0 - (-y + y1)), RED);        //(x,-y)putpixel(((-x + x1) + x0), (y0 - (-y + y1)), RED);       //(-x,-y)putpixel(((y + x1) + x0), (y0 - (-x + y1)), RED);        //(y,-y)putpixel(((-y + x1) + x0), (y0 - (-x + y1)), RED);       //(-y,-x)Sleep(50);}else {d0 = d0 + 4 * x + 6;x += 1;y = y;putpixel(((x + x1) + x0), (y0 - (y + y1)), RED);         //(x,y)putpixel(((-x + x1) + x0), (y0 - (y + y1)), RED);        //(-x,y)putpixel(((y + x1) + x0), (y0 - (x + y1)), RED);         //(y,x)putpixel(((-y + x1) + x0), (y0 - (x + y1)), RED);        //(-y,x)putpixel(((x + x1) + x0), (y0 - (-y + y1)), RED);        //(x,-y)putpixel(((-x + x1) + x0), (y0 - (-y + y1)), RED);       //(-x,-y)putpixel(((y + x1) + x0), (y0 - (-x + y1)), RED);        //(y,-y)putpixel(((-y + x1) + x0), (y0 - (-x + y1)), RED);       //(-y,-x)Sleep(50);}}
}
void main()
{int x1, y1, r;printf("请输入中点画圆算法圆心坐标(x1,y1)和圆的半径r:\n");scanf("%d %d %d", &x1, &y1, &r);initgraph(x0 * 2, y0 * 2);           //初始化图形窗口大小setbkcolor(WHITE);cleardevice();setcolor(BLACK);line(x0, 0, x0, y0 * 2);         //坐标轴Xline(0, y0, x0 * 2, y0);           //坐标轴YMiddle_point_draw_circle(x1, y1, r);             //中点画圆算法_getch();                                        //等待一个任意输入结束closegraph();                                    //关闭图形窗口
}

运行结果:

C语言——中点画圆算法和Bresenham画圆算法(easyx图形库)相关推荐

  1. 【计算机图形学】中点画圆算法和Bresenham画圆算法

    在平面解析几何中,圆的方程可以描述为(x – x0)2 + (y – y0)2 = R2,其中(x0, y0)是圆心坐标,R是圆的半径,特别的,当(x0, y0)就是坐标中心点时,圆方程可以简化为x2 ...

  2. 游戏中DDA算法和Bresenham算法的应用

    在角色扮演或即时战略游戏中,经常会将角色以最佳的方式走到指定地点.游戏场景的地面情况复杂,而且场面大,若采用盲目式搜索,例如盲目穷举法,则几乎要遍历整个场景,效率非常低,造成角色反应速度过慢,实践证明 ...

  3. 【计算机图形学】小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解

    小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解 引言 如何画圆 基本思想 中点画圆法 中点画圆基本思路 中点画圆改进 Bresenham画圆算法 Bre ...

  4. openGL实现中点画线算法、DDA画线算法,Bresenham画线算法,并进行鼠标键盘的交互

    首先设置变量用于进行鼠标交互和键盘交互: int m = 0; GLdouble m1 =0, m2 = 0; 1.实验入口主函数: //主函数 int main(int argc, char** a ...

  5. WordCount作业提交到FileInputFormat类中split切分算法和host选择算法过程源码分析

    参考 FileInputFormat类中split切分算法和host选择算法介绍  以及 Hadoop2.6.0的FileInputFormat的任务切分原理分析(即如何控制FileInputForm ...

  6. 图形学--(中点画线法+Bresenham画线算法)

    编程环境:codeblocks+EGE库 用到的函数:putpixel(int x1,int y1,int color)  用某种颜色打亮一个坐标点. 这俩种算法都是用来在计算机上画一条直线的,那么我 ...

  7. 【计算机图形学】扫面转换算法(DDA算法 中点画线算法 Bresenham画线算法)

    模块1 扫描转换算法 一 实验目的 编写直线.弧线的光栅扫描转换算法,并对线宽与线形的算法加以探讨 用DDA算法.中点画线算法.Bresenham画线算法绘制直线(如果键盘输入数据,给出数据值:如果绘 ...

  8. 画毛毛虫代码计算机图形学,计算机图形学 实验 数值微分(DDA)法、中点画线法、Bresenham算法.doc...

    文档介绍: 实验名称数值微分(DDA)法.中点画线法.Bresenham算法实验时间年月日专业姓名学号预****操作座位号教师签名总评一.实验目的:1.了解数值微分(DDA)法.中点画线法.Brese ...

  9. 中点Bresenham画圆算法|MFC|计算机图形学

    中点Bresenham画圆算法|MFC|计算机图形学 Bresenham中点画圆算法 计算机图形学-基本图元的生成-圆 基于学习直线的生成算法后,又展开了圆.椭圆的讲解: 此次试验是简单的MFC应用, ...

最新文章

  1. LNMP_ 配置文件
  2. 游戏杆编程心得二:如何判断按钮的有效按下
  3. 通过双向证书认证使用 gSOAP 访问 web services
  4. [转]vue项目中,main.js,App.vue,index.html如何调用
  5. redis集群依赖ruby
  6. java取网页源码_Java获取任意http网页源代码的方法
  7. 【LeetCode笔记】剑指 Offer 61-. 扑克牌中的顺子 (Java、哈希表)
  8. /usr/bin/python^M: 解释器错误: 没有那个文件或目录
  9. Maven:maven-shade-plugin, 打包失败, MojoExecutionException: Error creating shaded jar: null
  10. 【考古向翻译】Pwn2Own 2010 Windows 7 Internet Explorer 8 exploit
  11. 使用 做签名的post_使用 Go 添加 JWT 认证
  12. bug:刷机卡Logo界面,adb shell 报- exec '/system/bin/sh' failed: No such file or directory (2) -
  13. python统计段落单词词频_python词频统计实例
  14. 对话系统 | (4) 任务型对话系统基础
  15. EXCEL保存“加载宏”
  16. 数模电路基础知识 —— 8. PN结与三极管的工作原理
  17. python谷歌翻译 频率限制_使用Python实现谷歌批量翻译
  18. 05.Django基础五之django模型层(一)单表操作
  19. Python项目实战化:爬取堆糖网研究所美好生活照
  20. 好123主页篡改修复方法

热门文章

  1. 解决Ubuntu18.04中启动kworker等占用系统cpu过高问题
  2. esp now 的坑
  3. 工业机器人入门z50的含义_工业机器人实操与应用技巧第版.PDF
  4. sharding-jdbc分片策略
  5. 微信小程序列表数据渲染无效问题
  6. 【软件工程专业】学生,居然不会编程?
  7. Java如何通过IP获得真实地址
  8. windows ADB 5037端口总是被占用
  9. Dart理论篇<一>webstorm安装dartsdk
  10. C语言 HexDump