我该如何创建一个行中使用布氏任意厚度的?(how do I create a line of arb

2019-06-17 23:37发布

我目前使用的布氏算法来画线,但它们是(当然)厚的一个像素。 我的问题是什么是绘制任意厚度的线路最有效的方法是什么?

我使用的语言是C.

Answer 1:

我认为最好的办法是绘制一个矩形,而不是一致的,因为有宽度的线是二维对象。 特林绘制组平行线,以避免透支(以减少写入带宽)和underdraw(缺失像素)将是非常复杂的。 这不是太难以从起点和终点和宽度计算矩形的角点。

所以,下面跟随评论,过程要做到这一点是: -

  1. 创建一个矩形相同的长度所需要的线和宽度等于期望的宽度,所以(0,0)至(宽度,长度)
  2. 旋转和使用2D转换翻译矩形角坐标到所需的位置
  3. Rasterise旋转的矩形,或者使用硬件加速渲染器(例如*一个OpenGL四元组)或使用软件光栅化。 它可以使用一个四栅格化器或作为一对三角形的(左上和例如右下)被呈现。

注*:如果您正在使用OpenGL,你也可以做在同一时间第2步。 当然,使用OpenGL是否意味着理解的OpenGL(大和复杂的),这应用可能会做出一个棘手的事情要在发展这样一个后期阶段实施。



Answer 2:

采取另一个循环布氏并使用它来修改在矩形方向原始行的开始和结束位置。 问题是要efficently找到合适的出发点和不绘制任何像素的两倍(或跳过的像素),同时绘制下一行。

工作和测试C代码可从GitHub C代码 。

这里测试页,包括这段代码创建了几个示例行。 黑色像素的算法的起点。



Answer 3:

这里是一个纸张和Delphi实现绘制增厚线的布氏算法的修改版本。

您可能还需要看一看反谷物几何 ,高品质和2D图形的高性能软件渲染库。 看一看的演示页来获得它可以做些什么的想法。



Answer 4:

为了获得最佳的精度,以及特别是较粗的线条也不错的表现,你就可以绘制线作为多边形。 一些伪代码:

draw_line(x1,y1,x2,y2,thickness)
  Point p[4];
  angle = atan2(y2-y1,x2-x1);
  p[0].x = x1 + thickness*cos(angle+PI/2);
  p[0].y = y1 + thickness*sin(angle+PI/2);
  p[1].x = x1 + thickness*cos(angle-PI/2);
  p[1].y = y1 + thickness*sin(angle-PI/2);
  p[2].x = x2 + thickness*cos(angle-PI/2);
  p[2].y = y2 + thickness*sin(angle-PI/2);
  p[3].x = x2 + thickness*cos(angle+PI/2);
  p[3].y = y2 + thickness*sin(angle+PI/2);
  draw_polygon(p,4)

和可选的圆圈可以在每个端点绘制。



Answer 5:

一些简单的航线使用:

  1. 对于任何宽度n,其中n为奇数。 对于任何点p绘制的还积高于/低于它对于n / 2(如果行是> 45度角绘制侧而不是到另一侧)的点。
    • 没有真正合适的厚度合适的线路,更像是一个斜体的钢笔,但速度非常快。
  2. 为开始点P(X,Y)挑点T0和b,使得它们在页码但n个像素为中心开。 为终点做同样导致T1 B1。 从t0画线 - > t1时,T1-> B1,B1 - > T0,B0 - > T1。 填写结果矩形。
    • 这里的技巧是捡点使得它们看起来垂直于路径方向。
  3. 为上线,而不是绘制点的每个点p画一个圆。
    • 这具有使端点“干净”无论什么方向的优势。
    • 应该没有必要使固体的所有圈子除了第一。
    • 有点慢


Answer 6:

我认为你会画水平跨度从一个分界线到另一个,和你走(在单回路)由布氏的方法计算每一行的x值。

还没有尝试过。

终点可能需要一些注意事项,以免它们看起来奇怪截止。



Answer 7:

http://members.chello.at/~easyfilter/bresenham.html

在此连结的底部的例子是JavaScript的,但应该很容易适应C.这是一个相当简单的算法抗锯齿画出可变厚度的线。



Answer 8:

我这样做是经常来生成多孔介质模拟光纤照片和球体。 我有一个好简单的方式做到这一点使用一个非常标准的图像分析技术所知的“距离变换”。 这需要有机会获得一些图像分析软件包。 我用Python和SciPy的,所以这是没有问题的。 这里是一个演示,随机分布的点转换为球:

import scipy as sp
import scipy.ndimage as spim

im1 = sp.rand(100, 100) < 0.995  # Create random points in space
dt = spim.distance_transform_edt(im1)
im2 = dt < 5  # To create sphere with a radius of 5

这就是它! 距离转换可以是非常大的图像慢,但也有有效的版本在那里。 例如,ImageJ的有并行的。 显然,创建粗纤维你刚才创建薄的图像,然后应用步骤2和3以上。



Answer 9:

创造出符合几乎任意厚度的最简单的方法是首先做一个布氏,然后应用尽可能多的扩张 ,你想迭代。 每个扩张垫的线的两侧相等,但通过使用不同的面具,你甚至可以达到和厚薄不均:

厚度为1:

面具:

1 1 1
1 1 1
1 1 1

所得厚度:3

面具:

0 1 0
1 1 1
0 1 0

所得厚度:2



Answer 10:

对于我的嵌入式热敏打印机应用程序,使用布氏算法,该行是太单薄。 我没有GL或任何幻想。 最后我简单地递减的Y值下的第一个绘制更多的线路。 厚度中的每一个号码添加另一条线。 非常快速实施和所期望的结果打印从单色位图到热发。



Answer 11:

我正面临同样的问题,前一段时间。 在此基础上纸 ,我创建了一个Matlab的参考实现,我想上共享GitHub上 。



文章来源: how do I create a line of arbitrary thickness using Bresenham?