我得到的这些数组代表方形纸,或者你喜欢的像素。为了在该线程中保持一致,让“1”表示黑色单元格,“0”表示白色单元格。
现在,我想绘制从A点到B点的(黑色)直线。我不能只使用香草http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm,因为我需要将每个被击中的单元变黑。一张方格纸,你从广场A的中心到广场B的中心画了一条线。
所以这些应该如下:
+—+—+—+ +—+—+—+
|A| | | |█| | |
+—+—+—+ +—+—+—+
| | | | |█|█| |
+—+—+—+ +—+—+—+
| | | | → | |█|█|
+—+—+—+ +—+—+—+
| | |B| | | |█|
+—+—+—+ +—+—+—+
+—+—+—+ +—+—+—+
|A| | | |█| | |
+—+—+—+ +—+—+—+
| | | | → | |█| |
+—+—+—+ +—+—+—+
| | |B| | | |█|
+—+—+—+ +—+—+—+
+—+—+—+ +—+—+—+
|A| | | → |█|█| |
+—+—+—+ +—+—+—+
| | |B| | |█|█|
+—+—+—+ +—+—+—+
随意想象这些草图更像方形,或者在一张方形纸上实际绘制草图!它可能会让事情变得清晰。
和往常一样,随意发布可能有用的任何内容。谢谢!
(A)解决方案
也使用这个例子。并使用我的框架使用的索引,所以它看起来与答案中的索引略有不同。
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~
答案 0 :(得分:2)
我们假设我们正在使用这个例子:
+—+—+—+ +—+—+—+
|A| | | |█| | |
+—+—+—+ +—+—+—+
| | | | |█|█| |
+—+—+—+ +—+—+—+
| | | | → | |█|█|
+—+—+—+ +—+—+—+
| | |B| | | |█|
+—+—+—+ +—+—+—+
这是一个矩形3x4
。
我们需要定义两个功能:
y(x) = 4 * (1 - x/3)
x(y) = 3 * (1 - y/4)
。
现在让我们将矩形内的所有整数x
和y
传递给它们
在每一步,我们用坐标
来绘制黑色像素
[x; ceil(y(x)) - 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
的原因)。唯一的问题是角落交叉点,它可以通过一个有条件的解决。
答案 1 :(得分: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
和所有其他问题都是严格的正面或负面的。但它很容易处理。
解释如果线穿过正方形(或像素),则可以找到两个不在线的同一侧的顶点。所以一个位于正半平面,另一个位于负半平面。
改进一些简单的技巧会阻止您测试边界框的每个方块。如果你发现一个完全在半平面上的正方形,你可以丢弃一些正方形。在您的示例中,如果测试的方格位于线上方,则可以丢弃上方和右方的所有方格。