[英]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.