zoukankan      html  css  js  c++  java
  • 基于Bresenham算法画圆

    bresenham算法画圆思想与上篇 bresenham算法画线段 思想是一致的

    画圆x^2+y^2=R^2

     

     

    将他分为8个部分,如上图

    1.

    只要画出1中1/8圆的圆周,剩下的就可以通过对称关系画出这个圆

    X变化从0->R

    那为什么不采用从-R->R呢,

    Y=+-sqrt(R^2-x^2);

    dy/dx=-x/(sqrt(R^2-x^2)) =-x/y

    所以采用从-R到R,每次横坐标增1,计算量大,而且在(x=+-R,y=0)处,x的很小变化就引起了y的很大变化。

     所以不是采用x从-R--->R变化。而是采用1/8画圆法。

    2.

    在2这1/8圆周上,x值单调增加,y值单调递减,且fabs(dx/dy)=fabs(-x/y)<=1;所以圆周上相应点的y值变化小于1.

    假设当前点为(x1,y1)这下个点为(x1+1,y1)或(x1+1,y1-1)

    d1=(x1+1)^2+y1^2-R^2;

    d2=R^2-(x1+1)^2-(y1-1)^2;

    p=d1-d2 若p>0 选点(x1+1,y1-1)否则选点(x1+1,y1)

    p=2(x1+1)^2+2y1^2-2y1-2R^2+1

    接下来就是求p了。

    P1=3-2R(坐标为x=0,y=R)

    然后仿照线段算法得出p(i+1)=p(i)+4(Xi-Yi)+10(pi>0)否则P(i+1)=p(i)+4Xi+6

    这样就可以成功画出1/8圆弧了

    3.接下来的问题,是剩下的部分怎么处理,

    有两种方法:

    方法一:存储器将前1/8的坐标存储起来,然后通过镜像求出其他圆弧坐标,调整顺序输出,即可得到。

    方法二:分别求出对应的8个圆弧的算法式,一次画弧。

    算法比较:前者算法比较简单,但是存储数据,需要较大的RAM,一旦在计算高精度,大半径的圆时,数据存储量就比较大,可能就需要扩充RAM。后者代码比较多,占用较多的程序存储空间。


    然后从控制理论角度考虑:前者是先计算后执行,实时性比较差,后者运算和控制交叉进行。但不会减少总时间。

    综上所述,当圆的精度低时,可以采用方法一。当圆精度高,半径大,或者对运动过程中实时性要求比较高时,采用方法二。

     在实际的实现过程中,发现按照方法二实现,圆无法画整。因为每次后面1/8圆弧都是与前面的1/8圆弧最好一个点相接的,这样累积下来,势必造成首尾无法相接,最后是采用方法一和方法二结合实现方法二的,即画一半圆,然后利用对称性实现的【即方法一的思想】。

    方法一代码实现:


    方法二代码是实现:



    说明:上述代码实现均是基于stm32处理器,tftLCD2.8寸屏上实现的

    关于p的求法如果有疑问,可以参考上篇文章基于Bresenham和DDA算法画线段


    对于屏上画点,对各坐标点赋值有疑问的可以参考这篇资料看看bresenham直线算法与画圆算法 

     下面两幅图,是方法二实现的两种比较,如果采用单一的 画8个圆弧,会出现累积误差,圆无法闭合。


    图1


    图 2
  • 相关阅读:
    【Python】Visual Studio Code 安装&&使用 hello python~~~~
    linux系统644、755、777权限详解
    python对象销毁(垃圾回收)
    linux .bashrc文件修改和生效
    Python学习笔记(20)-文件和文件夹的移动、复制、删除、重命名
    HDU 4635 Strongly connected(强连通)经典
    推荐一款免费的SQLsever的备份软件sqlBackupAndFtp
    Objective-C基础笔记(6)Block
    iOS开发UI篇—懒载入
    关于Adapter对数据库的查询、删除操作
  • 原文地址:https://www.cnblogs.com/stoneFang/p/6715332.html
Copyright © 2011-2022 走看看