234彩票官网登录

  • <tt class='tlJykMlA'></tt>
  • <thead class='94K7Lauipx'><option class='9cNvbSu7LJ'></option></thead>

    <em class='jepytdnyfeW3'><b class='oR1Ys12nk'><td class='6rzzLTN'></td></b></em>

  • <dl class='Td0EmkF'><b class='qoWhaibfJ9'></b></dl>

  • <span class='lS1G'></span>

    我的一账户
    中国电子DIY

    科技成就未来

    亲爱的一游客,欢迎!

    已有账号,请

    如尚未注册?

    • 客服电话

      在线时间:8:00-16:00

      客服电话

      000-000-0000

      电子邮件

      ndiyadmin@163.com
    • 手机版

      电子DIY手机版

      随时随地掌握网站动态

    • 官方微信

      扫描二维码

      免费获取▓邀请码

    利用STM32F103画320*240点阵圆№和支线直线

    [复制链接]
    尕bb 发表于 2020-1-22 22:13:38 | 显示全部楼层 |阅读模式 打印 上    一主题 下一主题
    IMG_20200122_200138.jpg
    void draw_circle(int x, int y, int r, int color)
    {
    int a, b, num;
    a = 0;
    b = r;
    while(2 * b * b >= r * r)  // 1/8圆即可
    {

    draw_point(x + a, y - b,color); // 0~1
    draw_point(x - a, y - b,color); // 0~7
    draw_point(x - a, y + b,color); // 4~5
    draw_point(x + a, y + b,color); // 4~3
    draw_point(x + b, y + a,color); // 2~3
    draw_point(x + b, y - a,color); // 2~1
    draw_point(x - b, y - a,color); // 6~7
    draw_point(x - b, y + a,color); // 6~5

    a++;

    num = (a * a + b * b) - r*r;

    if(num > 0)

    {
    b--;
    a--;
    }
    }
    }

    //-----------画线 。参数:起始坐标,终点坐标,颜色--------

    void draw_line(int x1,int y1,int x2,int y2,int color)
    {
    int dx,dy,e;
    dx=x2-x1;
    dy=y2-y1;
    if(dx>=0)

    {

    if(dy >= 0) // dy>=0
    {
    if(dx>=dy) // 1/8 octant

    {

    e=dy-dx/2;

    while(x1<=x2)

    {

    draw_point(x1,y1,color);

    if(e>0){y1+=1;e-=dx;}   

    x1+=1;

    e+=dy;

    }
    }
    else// 2/8 octant

    {

    e=dx-dy/2;

    while(y1<=y2)

    {

    draw_point(x1,y1,color);

    if(e>0){x1+=1;e-=dy;}   

    y1+=1;
    e+=dx;

    }

    }

    }

    else   // dy<0
    {
    dy=-dy;   // dy=abs(dy)

    if(dx>=dy) // 8/8 octant
    {

    e=dy-dx/2;

    while(x1<=x2)
    {

    draw_point(x1,y1,color);

    if(e>0){y1-=1;e-=dx;}   

    x1+=1;
    e+=dy;
    }
    }

    else// 7/8 octant

    {

    e=dx-dy/2;

    while(y1>=y2)

    {

    draw_point(x1,y1,color);

    if(e>0){x1+=1;e-=dy;}   
    y1-=1;
    e+=dx;

    }

    }

    }   

    }

    else //dx<0
    {

    dx=-dx; //dx=abs(dx)
    if(dy >= 0) // dy>=0
    {

    if(dx>=dy) // 4/8 octant

    {
    e=dy-dx/2;
    while(x1>=x2)

    {

    draw_point(x1,y1,color);
    if(e>0){y1+=1;e-=dx;}   
    x1-=1;
    e+=dy;

    }
    }

    else// 3/8 octant

    {
    e=dx-dy/2;
    while(y1<=y2)
    {
    draw_point(x1,y1,color);
    if(e>0){x1-=1;e-=dy;}   
    y1+=1;
    e+=dx;
    }
    }
    }
    else   // dy<0
    {
    dy=-dy;   // dy=abs(dy)

    if(dx>=dy) // 5/8 octant

    {

    e=dy-dx/2;

    while(x1>=x2)
    {
    draw_point(x1,y1,color);
    if(e>0){y1-=1;e-=dx;}   
    x1-=1;
    e+=dy;
    }
    }
    else// 6/8 octant
    {
    e=dx-dy/2;
    while(y1>=y2)
    {
    draw_point(x1,y1,color);
    if(e>0){x1-=1;e-=dy;}   
    y1-=1;
    e+=dx;
    }
    }
    }   
    }
    }
    // 区域填色函数

    // 参数:开始列数,结束列数,开始行数,结束行数,颜色
    void fill_fb(int start_x, int end_x, int start_y, int end_y, unsigned short val)
    {
    int i, j;
    for(i = start_y; i < end_y; i++)
    {
    for(j = start_x; j < end_x; j++)
    {
    fb[i*480 + j] = val;

    }
    }
    }
    void clr_fb(void)
    {
    int i, j;
    for(i = 0; i < 272; i++)
    {
    for(j = 0; j < 480; j++)
    {
    fb[i*480 + j] = 0;
    }
    }
    }


    下面先简要介绍常用的一画圆算︻法(Bresenham算︻法),然后再具体阐述笔者对该算︻法的一改进 。

    一个圆,如果画出了圆上    的一某一点,那么可以利用对称性计算︻余下的一七段圆弧:Plot(x,y),Plot(y,x),Plot(y,-x),Plot(x,-y),Plot(-x,-y),Plot(-y,-x),Plot(-y,x),Plot(-x,y) 。

    1、Bresenham 画圆算︻法 。Bresenham算︻法的一主要思想是:以坐标原点(0,0)为圆心的一圆可以通过0度到45°的一弧计算︻得到,即x从0增加到半径,然后利用对称性计算︻余下的一七段圆弧 。当x从0增加到时,y从R递减到 。

    设圆的一半径为R,则圆的一方程为:

    f(x,y)=(x+1)2+y2-R2=0   (1)

    假设当前列(x=xi列)中最接近圆弧的一像素已经取▓为P(xi,yi),根据第二卦限1/8圆的一走向,下一列(x=xi+1列)中最接近圆弧的一像素只能在P的一正右方点H(xi+1,yi)或右下方点L(xi+1,yi-1)中选择,如图1所示 。Bresenham画圆算︻法采用点T(x,y)到圆心的一距离平方与半径平方之差D(T)作为选择标准,即

    D(T)=(x+1)2+y2-R2 (2)

    通过比较H、L两点各自对实圆弧上    点的一距离大小,即根据误差大小来选取▓,具有最小误差的一点为绘制点 。根据公式(2)得:

    对H(xi+1,yi)点有:D(H)=(xi+1)2+yi2-R2;
    对L(xi+1,yi-1)点有:D(L)=(xi+1)2+(yi-1)2-R2;
    根据Bresenham画圆算︻法,则选择的一标准是:
    如果|D(H)|<|D(L)|,那么下一点选取▓H(xi+1,yi);
    如果|D(H)|>|D(L)|,那么下一点选取▓L(xi+1,yi-1);
    如果|D(H)|=|D(L)|,那么下一点可以取▓L(xi+1,yi-1),也可以选取▓H(xi+1,yi),我们约定选取▓H(xi+1,yi) 。

    图1  Bresenham画圆算︻法点的一选取▓

    综合上    述情况,得:

    当|D(H)|>|D(L)|时,选取▓L点(xi+1,yi-1)为绘制点坐标;
    当|D(H)|<|D(L)|时,选取▓H点(xi+1,yi)为绘制点坐标 。
    然后将选取▓的一点坐标作为当前坐标,重复上    述过程直至xi=或者yi=为止,(xi,yi)的一初始值为(0,R) 。

    以上    便是Bresenham算︻法的一主要思想,但是上    述算︻法是在一个假设下:以坐标原点(0,0)为圆心 。该假设实际上    只是为了方便算︻法的一研究 。但在实际嵌入式LCD显示设备中,往往圆心坐标不 是(0,0)点,而是以左上    角为(0,0)点,这样就使得在实际运用中,需要对这个算︻法做很大的一改进 。

    另外,如果完全按照Bresenham画圆算︻法,那么就会涉及到浮点运算︻,这使得嵌入式编程十分烦琐,因 为本系统中所有数据都是整型的一,因 此在这方面也要作一定的一改进 。下面根据本系统中嵌入式硬件特点№和数据结构得特点,对这个算︻法进行改进 。

    2、改进的一Bresenham画圆算︻法 。先假设起始点为(R,0),令Pi=(xi,yi)为当前的一一点,那么我们就需要在Ti=(xi,yi+1)№和Si=(xi-1,yi+1)中选取▓一点,如图2所示 。

    图2 嵌入式LCD画圆时点的一选取▓

    设(xi-1/2+e,yi+1)为S№和T之间圆上    的一点,e是S、T中点到圆上    点的一误差,带入圆的一方程(1)得:

    f(xi-1/2+e,yi+1)=(xi-1/2+e)2+(yi+1)2-R2=f(xi-1/2,yi+1)+2(xi-1/2)e+e2=0   (3)

    在式(3)中,令

    di="f"(xi-1/2,yi+1)=-2(xi-1/2)e-e2(4)

    如果e<0,那么di>0,因 此选择S=(xi-1,yi+1),根据(3)与(4)得:

    di+1=f(xi-1-1/2,yi+1+1)=di-2(xi-1)+2(yi+1)+1=di+2(yi+1-xi+1)+1 (5)

    如果e30,那么di£0,因 此选择T=(xi,yi+1),根据(3)与(4)得:

    di+1=f(xi-1/2,yi+1+1)=di+2yi+1+1  (6)

    起始点是(R,0)的一时候,根据(4)得di的一初始值d0就是:

    d0=f(R-1/2,0+1)=(R-1/2)2+1-R2=5/4-R=1-R(由于编程中所用数据类型均为整型,故取▓1-R) 。

    综合上    述情况,得:

    当选取▓S=(xi-1,yi+1)时,那么di+1=di+2(yi+1-xi+1)+1;

    当选取▓T=(xi,yi+1)时,那么di+1=di+2yi+1+1;

    然后将选取▓的一点坐标作为当前坐标,重复上    述过程直至x=y,而不 是xi=或者yi=,这样就可以不 用作浮点数计算︻了 。

    本项目中的一LCD像素为320×240点阵,并且数据是八位的一,当横坐标№和纵坐标超过255时,那么数据就不 能一次传送成功,因 此需要通过字节操作来设定高字节,然后再传送低字节 。因 此,每次画圆上    的一点时要传送的一参数至少是六个,圆心坐标是四个(因 为要考虑圆心坐标可能大于255,因 此要对其圆心坐标设置高、低字节),另外两个是圆上    的一点相对于圆心的一坐标,但是最后要画一个点,需要四个参数,即改进的一画圆算︻法为六个参数输入,四个参数输出 。

    用C语言在嵌入式LCD上    实现改进的一Bresenham画圆算︻法的一部分代码如下:

    voidMidBresenhamcircle(int R)
    {
    intx,y,d;
    x="0";y=R;d=1-R;  
    while(x<y)
    {circlePoint(x,y);  
    if(d<0)  d+=2*x+3;  

       else

    {d+=2*(x-y)+5;

      y--;

    }

      x++;

    delay(1000);

    }

    精彩评论1

     楼主| 尕bb 发表于 2020-1-22 22:14:35 | 显示全部楼层
    6666,欢迎回复啊,《字数补丁,啊啊啊啊啊啊啊》
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关注0

    粉丝2

    帖子51

    发布主题
    推荐阅读
    关注我们
    中国电子DIY官方微信

    客服电话:000-000-0000

    客服邮箱:776513803@qq.com

    周一至周五 9:00-18:00

    公司|234彩票官网登录地址:234彩票官网登录深圳市南山区美丽湾大厦B座

    Powered by X3.4@ 2001-2013