个性化阅读
专注于IT技术分析

布雷森汉姆的循环算法

使用Bresenham算法对圆进行扫描转换的工作方式如下:点从90°到45°生成, 仅在+ x&-y方向上移动, 如图所示:

布雷森汉姆圆算法

真实圆的最佳近似将由栅格中与真实圆的距离最小的那些像素描述。我们想从中产生点

布雷森汉姆圆算法

90°至45°。假定最后的经扫描转换的像素是P1, 如图2所示。可以通过以下两个动作之一找到最接近真实圆的每个新点。

  1. 在x方向上移动一个单位或
  2. 在x方向上移动一个单位, 在y方向上移动一个负数。

令D(Si)是从原点到真实圆平方的距离减去到点P3平方的距离。 D(Ti)是从原点到真圆平方的距离减去到点P2平方的距离。因此, 出现以下表达式。

D (Si)=(xi-1+1)2+ yi-12 -r2 D (Ti)=(xi-1+1)2+(yi-1 -1)2-r2

由于D(Si)始终为+ ve, 而D(Ti)始终为-ve, 因此可以将决策变量d定义如下:

布雷森汉姆圆算法

di = D(硅)+ D(Ti)

Therefore, di=(xi-1+1)2+ yi-12 -r2+(xi-1+1)2+(yi-1 -1)2-r2

从这个方程式, 我们可以将di的初始值驱动为

如果假定圆以原点为中心, 则第一步x = 0&y = r。

因此, di =(0 + 1)2 + r2 -r2 +(0 + 1)2+(r-1)2-r2 = 1 + 1 + r2-2r + 1-r2 = 3-2r

此后, 如果d_i <0, 则仅x递增。

xi+1=xi+1 di+1=di+ 4xi+6

& if di≥0, then x & y are incremented xi+1=xi+1 yi+1 =yi+ 1 di+1=di+ 4 (xi-yi)+10

布雷森汉姆圆算法

步骤1:开始算法

步骤2:声明p, q, x, y, r, d变量p, q是圆心的坐标r是圆心的半径

步骤3:输入r的值

步骤4:计算d = 3-2r

步骤5:初始化x = 0&nbsy = r

步骤6:检查整个圆是否已扫描转换如果x> = y停止

步骤7:使用八向对称的概念绘制八个点。中心位于(p, q)。当前有效像素为(x, y)。像素(x + p, y + q)像素(y + p, x + q)像素(-y + p, x + q)像素(-x + p, y + q)像素(-x + p, – y + q)像素(-y + p, -x + q)像素(y + p, -x + q)像素(x + p, -yq)

步骤8:查找要扫描的下一个像素的位置如果d <0, 则d = d + 4x + 6增量x = x + 1如果d≥0, 则d = d + 4(x-y)+ 10增量x = x + 1递减y = y-1

步骤9:前往步骤6

步骤10:停止算法

示例:使用Bresenham算法绘制6个圆点。圆弧半径为10个单位时。圆的中心为(50, 50)。

解决方案:令r = 10(给出)

步骤1:取初始点(0, 10)d = 3-2r d = 2-3 * 10 = -17 d <0 d = d + 4x + 6 = -17 + 4(0)+ 6 = -11

步骤2:绘制(1, 10)d = d + 4x + 6(∵d <0)= -11 + 4(1)+ 6 = -1

步骤3:绘制(2, 10)d = d + 4x + 6(∵d <0)= -1 + 4 x 2 + 6 = 13

第4步:绘制(3, 9)d> 0, 因此x = x + 1, y = y-1 d = d + 4(xy)+ 10(∵d> 0)= 13 + 4(3-9)+ 10 = 13 + 4(-6)+ 10 = 23-24 = -1

步骤5:绘制(4, 9)d = -1 + 4x + 6 = -1 + 4(4)+ 6 = 21

步骤6:绘制(5, 8)d = d + 4(x-y)+ 10(∵d> 0)= 21 + 4(5-8)+ 10 = 21-12 + 10 = 19

所以P1(0, 0)⟹(50, 50)P2(1, 10)⟹(51, 60)P3(2, 10)⟹(52, 60)P4(3, 9)⟹(53, 59)P5 (4, 9)⟹(54, 59)P6(5, 8)⟹(55, 58)

使用Bresenham的圆图绘制算法绘制圆的程序:

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>

    void	EightWaySymmetricPlot(int xc, int yc, int x, int y)
   {
	putpixel(x+xc, y+yc, RED);
	putpixel(x+xc, -y+yc, YELLOW);
	putpixel(-x+xc, -y+yc, GREEN);
	putpixel(-x+xc, y+yc, YELLOW);
	putpixel(y+xc, x+yc, 12);
	putpixel(y+xc, -x+yc, 14);
	putpixel(-y+xc, -x+yc, 15);
	putpixel(-y+xc, x+yc, 6);
   }

    void BresenhamCircle(int xc, int yc, int r)
   {
	int x=0, y=r, d=3-(2*r);
	EightWaySymmetricPlot(xc, yc, x, y);

	while(x<=y)
     {
	  if(d<=0)
             {
	    d=d+(4*x)+6;
	  }
	 else
	  {
	    d=d+(4*x)-(4*y)+10;
	    y=y-1;
	  }
	   x=x+1;
	   EightWaySymmetricPlot(xc, yc, x, y);
      }
    }

    int  main(void)
   {
	/* request auto detection */
	int xc, yc, r, gdriver = DETECT, gmode, errorcode;
	/* initialize graphics and local variables */
	 initgraph(&gdriver, &gmode, "C:\\TURBOC3\\BGI");

	 /* read result of initialization */
	 errorcode = graphresult();

	  if (errorcode != grOk)  /* an error occurred */
	 {
		printf("Graphics error: %s\n", grapherrormsg(errorcode));
		printf("Press any key to halt:");
		getch();
		exit(1); /* terminate with an error code */
	 }
	   printf("Enter the values of xc and yc :");
	   scanf("%d%d", &xc, &yc);
	   printf("Enter the value of radius  :");
	   scanf("%d", &r);
	   BresenhamCircle(xc, yc, r);

	 getch();
	 closegraph();
	 return 0;
    }

输出:

布雷森汉姆圆算法

赞(0)
未经允许不得转载:srcmini » 布雷森汉姆的循环算法

评论 抢沙发

评论前必须登录!