ご質問の処理は要するに格子を画素とみなし「線分を構成する画素をプロットする」というたぐいのものの一つであると考えられます。
最近の質問に「線分が通過する画素を残らずプロットする」という似た条件のものがあります。
別質問1
https://teratail.com/questions/149396
こちらに参考になりそうな回答がいくつかあると思います。しかしながら上記に書かれているのはかなり最適化を意識した論理であり内容も若干込み入っています。また本件は「端点の座標が整数ではなく実数」のため別質問1の論理を応用するにしても若干の調整が必要です。
そこで・・・結果の精度や効率は別質問1の方法に対してイマイチ劣るものの、「わかりやすそう」な方式を一つご紹介してみます。
考え方は単純でして「一方の端点から始めて格子の大きさに対して十分小さな刻み幅で線分上の座標を次々に求めてその座標に該当する格子に対してプロットする(1に変える)」というものです。
例えば刻み幅を0.1にしてみましょうか。a=(ax, ay)からb=(bx, by)までの線分のx, y座標それぞれの差分を考えれば
x方向の差分はbx - ax
y方向の差分はby - ay
線分の長さ(aとbの距離)はline_len = numpy.sqrt((bx - ax) ** 2 + (by - ay) ** 2)
です。
以上よりaからbの方向へ0.1だけ移動したときの座標の差分は
delta_x = (bx - ax) * 0.1 / line_len
delta_y = (by - by) * 0.1 / line_len
ですね。
ということで次のようにするととりあえずお望みのことに近いことができます。
Python
1import numpy as np
2import matplotlib.pyplot as plt
3import matplotlib.patches as patches
4
5
6A = np.full((10, 10), 0) # 格子の持つ情報0
7
8x = [2.2, 6.8]
9y = [1.2, 7.8]
10dist_x = x[1] - x[0]
11dist_y = y[1] - y[0]
12line_len = np.sqrt(dist_x ** 2 + dist_y ** 2)
13delta_line_len = 0.1
14delta_x = dist_x * delta_line_len / line_len
15delta_y = dist_y * delta_line_len / line_len
16
17cx, cy = x[0], y[0]
18for _ in np.arange(0, line_len + delta_line_len, delta_line_len):
19 ix = int(np.floor(cx))
20 iy = int(np.floor(cy))
21 A[ix, iy] = 1
22 cx += delta_x
23 cy += delta_y
24
25
26fig = plt.figure()
27ax = fig.add_subplot(111)
28plt.scatter(x, y)
29for iy in range(A.shape[1]):
30 for ix in range(A.shape[0]):
31 if A[ix, iy]:
32 sq = patches.Rectangle(xy=(ix, iy), width=1, height=1, fill=True, alpha=0.5)
33 ax.add_patch(sq)
34
35plt.plot(x, y)
36plt.xticks(np.arange(0, 11))
37plt.yticks(np.arange(0, 11))
38plt.grid()
39plt.show()
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/10/23 06:12