如何将Bresenham的画线算法与裁剪一起使用?

编程入门 行业动态 更新时间:2024-10-10 21:30:22
本文介绍了如何将Bresenham的画线算法与裁剪一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

使用 Bresenham画线算法绘制线时,该行可能不在要写入的位图的范围内-剪切结果将很有用,以便它们适合要写入的图像的轴对齐范围内.

When drawing a line with Bresenham line drawing algorithm, where the line may not be within the bounds of the bitmap being written to - it would be useful to clip the results so they fit within the axis aligned bounds of the image being written to.

虽然可以先将线剪裁到矩形,然后再画线.这是不理想的,因为它常常使(假设使用int坐标)线的倾斜度稍有不同.

While its possible to first clip the line to the rectangle, then draw the line. This isn't ideal since it often gives a slightly different slant to the line (assuming int coords are being used).

由于这是原始操作,是否存在在保持相同形状的同时剪切线的方法?

Since this is such a primitive operation, are there established methods for clipping the line while maintaining the same shape?

如果有帮助,请这是该算法的参考实现-它使用int坐标,这样可以避免在绘制直线时进行int/float转换.

In case it helps, here is a reference implementation of the algorithm - it uses int coords, which avoids int/float conversion while drawing the line.

我花了一些时间研究这个问题:

I spent some time looking into this:

  • virtual-dub的网页上详细描述了问题a>.
  • 艾伦·蒂德曼(Alan Tiedemann)可能的解决方案 ...尽管我需要基于文本实现代码-才能查看其效果.
  • 具有内置剪切功能的布雷森汉姆线生成算法 (论文来自1995年,找不到整个文档吗?-PDF是没有参考的C代码的单个页面,看起来像是付费的墙.
推荐答案

让我们重新构造问题,以便我们了解布雷森汉姆算法的真正工作原理...

Let's reframe the problem so we can see how Bresenham's algorithm really works...

让我们说您正在画一条从(x0,y0)到(x1,y1)的基本上是水平的线(该方法对于大多数是垂直的,但是轴已切换):

Lets say you are drawing a mostly horizontal line (the method is the same for mostly vertical, but with the axes switched) from (x0,y0) to (x1,y1):

整行可以用 x (所有整数)描述为 y 的函数:

The full line can be described as a function of y in terms of x (all integers):

y = y0 + round( (x-x0) * (y1-y0) / (x1-x0) )

这精确地描述了绘制整条线时要绘制的每个像素,并且当连续裁剪线时,它 still 精确地描述了要绘制的每个像素-您只需将其应用于较小的 x 值的范围.

This describes precisely each pixel you will paint when drawing the full line, and when you clip the line consistently, it still describes precisely each pixel you will paint -- you just apply it to a smaller range of x values.

我们可以使用所有整数数学,通过分别计算除数和余数来评估此函数.对于 x1> = x0 和 y1> = y0 (否则请进行常规转换):

We can evaluate this function using all integer math, by calculating the divisor and remainder separately. For x1 >= x0 and y1 >= y0 (do the normal transformations otherwise):

let dx = (x1-x0); let dy = (y1-y0); let remlimit = (dx+1)/2; //round up rem = (x-x0) * dy % dx; y = y0 + (x-x0) * dy / dx; if (rem >= remlimit) { rem-=dx; y+=1; }

布雷森纳姆(Bresenham)算法是在更新 x 时递增地更新此公式结果的一种快速方法.

Bresenham's algorithm is a just a fast way to update the result of this formula incrementally as you update x.

在这里,我们可以利用增量更新来绘制从x = xs到x = xe的同一行的一部分:

Here's how we can make use of incremental updates to draw the portion of the very same line from x=xs to x=xe:

let dx = (x1-x0); let dy = (y1-y0); let remlimit = (dx+1)/2; //round up x=xs; rem = (x-x0) * dy % dx; y = y0 + (x-x0) * dy / dx; if (rem >= remlimit) { rem-=dx; y+=1; } paint(x,y); while(x < xe) { x+=1; rem+=dy; if (rem >= remlimit) { rem-=dx; y+=1; } paint(x,y); }

如果要对0进行余数比较,则可以在开始时将其偏移:

If you want do to your remainder comparisons against 0, you can just offset it at the beginning:

let dx = (x1-x0); let dy = (y1-y0); let remlimit = (dx+1)/2; //round up x=xs; rem = ( (x-x0) * dy % dx ) - remlimit; y = y0 + (x-x0) * dy / dx; if (rem >= 0) { rem-=dx; y+=1; } paint(x,y); while(x < xe) { x+=1; rem+=dy; if (rem >= 0) { rem-=dx; y+=1; } paint(x,y); }

更多推荐

如何将Bresenham的画线算法与裁剪一起使用?

本文发布于:2023-11-29 07:01:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1645677.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何将   算法   画线   Bresenham

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!