[英]Drawing an almost straight line
我得到的这些数组代表方形纸,如果你愿意,也可能是像素。 为了在该线程中保持一致,让“1”表示黑色单元格,“0”表示白色单元格。
现在,我想绘制从A点到B点的(黑色)直线。我不能只使用香草http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm ,因为我需要将每个单元格变黑如果它是一张方形纸并且你从方形A的中心到方形B的中心画一条线就会被击中。
所以这些应该如下:
+—+—+—+ +—+—+—+
|A| | | |█| | |
+—+—+—+ +—+—+—+
| | | | |█|█| |
+—+—+—+ +—+—+—+
| | | | → | |█|█|
+—+—+—+ +—+—+—+
| | |B| | | |█|
+—+—+—+ +—+—+—+
+—+—+—+ +—+—+—+
|A| | | |█| | |
+—+—+—+ +—+—+—+
| | | | → | |█| |
+—+—+—+ +—+—+—+
| | |B| | | |█|
+—+—+—+ +—+—+—+
+—+—+—+ +—+—+—+
|A| | | → |█|█| |
+—+—+—+ +—+—+—+
| | |B| | |█|█|
+—+—+—+ +—+—+—+
随意想象这些草图更像方形,或者在一张方形纸上实际绘制草图! 它可能会搞清楚。
和往常一样,随意发布可能有用的任何内容。 谢谢!
(一个解法
也使用这个例子。 并使用我的框架使用的索引,所以它看起来与答案中的索引略有不同。
X 0 1 2 X 0 1 2
Y +—+—+—+ → Y +—+—+—+
0 |A| | | → 0 |█| | |
+—+—+—+ → +—+—+—+
1 | | | | → 1 |█|█| |
+—+—+—+ → +—+—+—+
2 | | | | → 2 | |█|█|
+—+—+—+ → +—+—+—+
3 | | |B| → 3 | | |█|
+—+—+—+ → +—+—+—+
A(0,0)= :( a1,a2),B是(2,3)= :( b1,b2),因此预期的点集是{(0,0),(0,1), (1,1),(1,2),(2,2),(2,3)}
首先,我们将在实际纸张上绘制的直线形式化。
Therefore first define constant m which holds our slope:
(b2 - a2)
m = —————————
(b1 - a1)
For arbitrary (A, B), the straight is now defined by:
g: y = (x - a1) · m + a2
and inverted:
ǵ: x = (y - a2) / m + a1
Note that for m = 0, the whole thing does fail. But a straight-to-the-right line does not only sound like a straightforward thing.
在这个例子中,直道是
m = 3/2
g: y = x * 3/2
ǵ: x = y * 2/3
我们将在边界框内使用“线值”(恰好在2个整数x和x + 1之间,广泛称为“x和a halve”)来提供这些函数。 首先,我们将介于a1和b1之间(饲料g),然后介于a2和b2之间(饲料ǵ):
g(0.5) = 1/2 * 3/2 = 0.75 // 1 < g(0.5) + 0.5 < 2
g(1.5) = 3/2 * 3/2 = 2.25 // 2 < g(1.5) + 0.5 < 3
ǵ(0.5) = 1/2 * 2/3 = 0.33 // 0 < ǵ(0.5) + 0.5 < 1
ǵ(1.5) = 3/2 * 2/3 = 1 // 1 < ǵ(1.5) + 0.5 < 2
ǵ(2.5) = 5/2 * 2/3 = 1.66 // 2 < ǵ(2.5) + 0.5 < 3
所有点:{(0,1),(1,1),(1,2),(2,2),(0,0), (0,1) , (1,1) , (1,2) ) , (2,2) ,(2,3)}
没有重复 :{(0,0),(0,1),(1,1),(1,2),(2,2),(2,3)}(这与预期完全一样)
感觉对,这是我的想法。
有什么想法吗? 请评论!
~LDer~
让我们假设我们正在使用这个例子:
+—+—+—+ +—+—+—+
|A| | | |█| | |
+—+—+—+ +—+—+—+
| | | | |█|█| |
+—+—+—+ +—+—+—+
| | | | → | |█|█|
+—+—+—+ +—+—+—+
| | |B| | | |█|
+—+—+—+ +—+—+—+
这是一个3x4
的矩形。
我们需要定义两个函数:
y(x) = 4 * (1 - x/3)
x(y) = 3 * (1 - y/4)
。
现在让我们将矩形内的所有整数x
和y
传递给它们。
在每一步我们用坐标绘制黑色像素
[x; ceil(y(x)) - 1]
[x; ceil(y(x)) - 1]
和[ceil(x(y)) - 1; y - 1]
[ceil(x(y)) - 1; y - 1]
:
y(0) == 4 # paint 0;3
y(1) == 2.(6) # paint 1;2
y(2) == 1.(3) # paint 2;1
x(0) == 3 # paint 2;-1 (-1 is not a valid pixel coordinate,
# so we may just throw away this, as there are no pixels below y=0)
x(1) == 2.25 # paint 2;0
x(2) == 1.5 # paint 1;1
x(3) == 0.75 # paint 0;2
x(y)
和y(x)
函数都给出了对角线上一个点的第二个坐标,当我们将整数值传递给它们时,我们找到了对角线与网格的交点。
y
函数将为我们提供每个垂直线和x
函数的所有像素 - 低于每个水平线(这就是y - 1
的原因)。 唯一的问题是角落交叉点,它可以通过一个有条件的解决。
初始化给出“正方形”坐标(x,y)
的顶点。 对于每个方格, v1是左上角, v2是右上角, v3是右下角, v4是左下角。 计算你的线的方程y = a*x + b
。
算法
For each square do
for each vertex of the square do
calculate valueOfVertex = y - a*x - b
if two valueOfVertex have an opposite sign
then cellColor == 1
else cellcolor == 0
输出应该是您所期望的。 唯一的问题是,如果一个valueOfVertex = 0
而所有其他的都是严格正面或负面的。 但它很容易处理。
说明如果线穿过正方形(或像素),则可以找到两个不在线的同一侧的顶点。 因此,一个位于正半平面中,另一个位于负半平面中。
改进一些简单的技巧将阻止您测试边界框的每个方块。 如果你发现一个完全在半平面上的正方形,你可以丢弃一些正方形。 在您的示例中,如果测试的方格在线上方,则可以丢弃上方和右方的所有方格。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.