1. 首页 > 智能数码 >

bresenham算法计算坐标(bresenman算法)

Bresenham直线演算法的演算方法

Bresenham直线算法描绘的直线。假设我们需要由 (x0, y0) 这一点,绘画一直线至右下角的另一点(x1, y1),x,y分别代表其水平及垂直坐标,并且 x1 - x0 > y1 - y0。在此我们使用电脑系统常用的坐标系,即x坐标值沿x轴向右增长,y坐标值沿y轴向下增长。

bresenham算法计算坐标(bresenman算法)bresenham算法计算坐标(bresenman算法)


dda法生成直线的基本原理是什么?为什么说Bersenham画圆的算法效率较高?

DDA算法主要是根据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。算法的具体思路如下:

1. 输入直线的起点、终点;

2. 计算x方向的间距:△X和y方向的间距:△Y。

3. 确定单位步进,取MaxSteps = max(△X,△Y); 若△X>=△Y,则X方向的步进为单位步进,X方向步进一个单位,Y方向步进△Y/MaxSteps;否则相反。

4. 设置第一个点的像素值

5. 令循环初始值为1,循环次数为MaxSteps,定义变量x,y,执行以下计算:

a. x增加一个单位步进,y增加一个单位步进

b. 设置位置为(x,y)的像素值

Bresenham算法是DDA算法画线算法的一种改进算法。本质上它也是采取了步进的思想。不过它比DDA算法作了优化,避免了步进时浮点数运算,同时为选取符合直线方程的点提供了一个好思路。首先通过直线的斜率确定了在x方向进行单位步进还是y方向进行单位步进:当斜率k的|k|<1时,在x方向进行单位步进;当斜率k的|k|>1时,在y方向进行单位步进。

1. 输入线段的起点和终点。

2. 判断线段的斜率是否存在(即起点和终点的x坐标是否相同),若相同,即斜率不存在,

只需计算y方向的单位步进(△Y+1次),x方向的坐标保持不变即可绘制直线。

3. 计算线段的斜率k,分为下面几种情况处理

a. k等于0,即线段平行于x轴,即程序只需计算x方向的单位步进,y方向的值不变

b. |k|等于1,即线段的x方向的单位步进和y方向的单位步进一样,皆为1。直接循环△X次计算x和y坐标。

4. 根据输入的起点和终点的x、y坐标值的大小决定x方向和y方向的单位步进是1还是-1

6. 画出第一个点。

7. 若|k| <1,设m =0,计算P0,如果Pm>0,下一个要绘制的点为(Xm+单位步进,Ym),

Pm+1 = Pm -2△Y;

否则要绘制的点为(Xm+单位步进,Ym+单位步进)

Pm+1 = Pm+2△X-2△Y;

8. 重复执行第七步△X-1次;

9. 若|k| <1,设m =0,计算Q0,如果Qm>0,下一个要绘制的点为(Xm,Ym+单位步进),

Pm+1 = Pm -2△X;

否则要绘制的点为(Xm+单位步进,Ym+单位步进)

Pm+1 = Pm+2△Y-2△X;

10. 重复执行第9步△Y-1次;

关于Bresenham算法的求助

void Bresenham_Line(x0, y0, x1, y1, color)

int x0, y0, x1, y1, color;

{ int x, y, dx, dy;

float k, e;

dx=x1-x0; dy=y1-y0;

k=dy/dx; e=-0.5;

x=x0; y=y0;

for(i=0; i<=dx; i++)

{ putpixel(x, y, color);

x=x+1; e=e+k;

if(e>=0)

{ y=y+1; e=e-1;

} }}

算法原理:过各行、 各列像素中心构造一组虚拟网格线, 按直线从起点到终点的顺序计算直线与各垂直网格线的交点, 然后确定该列像素中与该交点近的像素

ja 已经圆心坐标(x0,y0)及圆上一点坐标(x1,y1),及圆半径(r),求圆上任意一点的坐标,求高手解答急

Bresenham算法画圆,可以参考下

public void drawCircle(int x, int y, int d, Color frameColor){

int xc = x + d / 2;

int yc = y + d / 2;

int r = d / 2;

int dx = r;

int dy = 0;

int xChange = 1 - 2 r;

int yChange = 1;

int radiusError = 0;

while( dx >= dy){

plot8CirclePoints(xc, yc, dx, dy, frameColor);

dy++;

radiusError += yChange;

yChange += 2;

if(2 radiusError + xChange > 0){

dx--;

radiusError += xChange;

xChange += 2;

}}

}private void plot8CirclePoints(int x, int y, int dx, int dy, Color color){

graph.setArrayData(x + dx, y + dy, color);

graph.setArrayData(x - dx, y + dy, color);

graph.setArrayData(x - dx, y - dy, color);

graph.setArrayData(x + dx, y - dy, color);

graph.setArrayData(x + dy, y + dx, color);

graph.setArrayData(x - dy, y + dx, color);

graph.setArrayData(x - dy, y - dx, color);

graph.setArrayData(x + dy, y - dx, color);

}

使用整数Bresenham算法光栅化直线起点P0(2,1)到终点P1(14,10)。1)主位移方向?

在使用整数Bresenham算法光栅化直线之前,我们需要确定主位移方向。这是指在每个步骤中哪个方向上的像素会被涂色或改变状态。

对于起点P0(2,1)到终点P1(14,10),我们可以通过将两个点的坐标相减并取来得出线段的斜率。即:$|m| = \frac{|y_1-y_0|}{|x_1 - x_0|} = \frac{|10-1|}{|14-2|} = \frac{9}{12} = \frac{3}{4}$

由于斜率小于1,则主要位移方向为水平方向(即x轴方向),而次要位移方向为竖直方向(即y轴方向)。因此,在每个步骤中,x值将增加1,而y值将根据Bresenham算法的规则增加或不变。

现在可以开始使用整数Bresenham算法光栅化直线从起点P0(2,1)到终点P1(14,10)。具体步骤如下:

1. 计算Δx和Δy

$\Delta x = x_1 - x_0 = 14 - 2 = 12$

$\Delta y = y_1 - y_0 = 10 - 1 = 9$

2. 计算初始决策参数d

$d_{ini} = 2\Delta y - \Delta x = 2(9) - 12 = 6$

3. 在起点P0(2,1)处绘制像素,即(x,y)=(2,1)

4. 接下来,根据Bresenham算法的规则,在主位移方向上逐步增加x值,同时在次要位移方向上根据决策参数d的值决定是否增加y值。

5. 对于每个新的像素位置,根据该像素是否涂色或改变状态来确定决策参数d的更新规则。

6. 重复步骤4和步骤5直到达到终点P1(14,10)。

下面是按照以上步骤为P0(2,1)到P1(14,10)计算出的结果(每个步骤中应该绘制的像素位置):

Step 1: (x,y)=(2,1)

Step 2: (x,y)=(3,1), d=12

Step 3: (x,y)=(4,2), d=18

Step 4: (x,y)=(5,3), d=10

Step 5: (x,y)=(6,4), d=14

Step 6: (x,y)=(7,5), d=6

Step 7: (x,y)=(8,6), d=-2

Step 8: (x,y)=(9,7), d=-8

Step 9: (x,y)=(10,8), d=-12

Step 10: (x,y)=(11,9), d=-14

Step 11: (x,y)=(12,10), d=-14

Step 12: (x,y)=(13,10), d=-18

Step 13: (x,y)=(14,10)

因此,从起点P0(2,1)到终点P1(14,10)的整数Bresenham算法光栅化直线的像素位置为:(2,1), (3,1), (4,2), (5,3), (6,4), (7,5), (8,6), (9,7), (10,8), (11,9), (12,10), (13,10)和(14,10)。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息