回答編集履歴
1
あ
answer
CHANGED
@@ -11,30 +11,30 @@
|
|
11
11
|
```python
|
12
12
|
import numpy as np
|
13
13
|
|
14
|
-
def calc_points(x1, y1, x2, y2):
|
14
|
+
def calc_points(x1, y1, x2, y2, ax):
|
15
15
|
'''ピクセル (x1, y1) と ピクセル (x2, y2) が通るピクセルの一覧を返す
|
16
16
|
'''
|
17
17
|
points = []
|
18
|
+
|
19
|
+
# ピクセル座標を実2次元座標に変換する。
|
20
|
+
# 例: ピクセル (1, 1) から (3, 2) へ線を引く場合、実2次元座標で点 (1.5, 1.5) から
|
21
|
+
# (3.5, 2.5) を結ぶ線とする。
|
18
22
|
x1, y1 = x1 + 0.5, y1 + 0.5 # ピクセルの中心
|
19
23
|
x2, y2 = x2 + 0.5, y2 + 0.5 # ピクセルの中心
|
24
|
+
|
25
|
+
# 初期化
|
20
26
|
x, y = x1, y1
|
21
|
-
|
22
|
-
cell_w, cell_h = 1, 1
|
27
|
+
cell_w, cell_h = 1, 1 # セルの大きさ、今回はピクセルなので (1, 1)
|
23
|
-
step_x = np.sign(x2 - x1)
|
28
|
+
step_x = np.sign(x2 - x1) # (x1, y1) から (x2, y2) へ進むときの x 方向のステップ数
|
24
|
-
step_y = np.sign(y2 - y1)
|
29
|
+
step_y = np.sign(y2 - y1) # (x1, y1) から (x2, y2) へ進むときの y 方向のステップ数
|
25
30
|
delta_x = cell_w / abs(x2 - x1)
|
26
31
|
delta_y = cell_h / abs(y2 - y1)
|
32
|
+
# a / b % 1 は a / b の計算値の小数部分 (例: 3 / 2 % 1 = 1.5 % 1 = 0.5)
|
33
|
+
max_x = delta_x * (x1 / cell_w % 1)
|
34
|
+
max_y = delta_y * (y1 / cell_h % 1)
|
27
35
|
|
28
|
-
tmp = x1 / cell_w
|
29
|
-
max_x = delta_x * (1.0 - (tmp - int(tmp)))
|
30
|
-
tmp = y1 / cell_h
|
31
|
-
max_y = delta_y * (1.0 - (tmp - int(tmp)))
|
32
|
-
|
33
|
-
#print('delta_x: {}, step_x: {}'.format(delta_x, step_x)) # delta_x: 0.2, step_x: 1
|
34
|
-
#print('delta_x: {}, step_x: {}'.format(delta_y, step_y)) # delta_x: 0.2, step_x: 1
|
35
|
-
|
36
36
|
points.append([x, y]) # 開始点
|
37
|
-
reached_x, reached_y = False, False
|
37
|
+
reached_x, reached_y = False, False # 到達判定用フラグ
|
38
38
|
while not (reached_x and reached_y):
|
39
39
|
if max_x < max_y:
|
40
40
|
max_x += delta_x
|
@@ -42,6 +42,7 @@
|
|
42
42
|
else:
|
43
43
|
max_y += delta_y
|
44
44
|
y += step_y
|
45
|
+
|
45
46
|
points.append([x, y]) # 点を追加
|
46
47
|
|
47
48
|
# 終点に到達したかどうか
|
@@ -56,51 +57,41 @@
|
|
56
57
|
## 描画結果
|
57
58
|
|
58
59
|
```python
|
59
|
-
import matplotlib.pyplot as plt
|
60
|
-
from matplotlib.lines import Line2D
|
61
60
|
|
62
|
-
def show_image(ax, img):
|
63
|
-
ax.imshow(img, interpolation='none')
|
64
|
-
ax.grid(which='minor', color='b', linestyle='-', linewidth=1)
|
65
|
-
# Major ticks
|
66
|
-
ax.set_xticks(np.arange(0, 10, 1))
|
67
|
-
ax.set_yticks(np.arange(0, 10, 1))
|
68
|
-
# Labels for major ticks
|
69
|
-
ax.set_xticklabels(np.arange(10))
|
70
|
-
ax.set_yticklabels(np.arange(10))
|
71
|
-
# Minor ticks
|
72
|
-
ax.set_xticks(np.arange(-.5, 10, 1), minor=True)
|
73
|
-
ax.set_yticks(np.arange(-.5, 10, 1), minor=True)
|
74
|
-
|
75
|
-
def draw_line(img, p1, p2, color=[255, 0, 0]):
|
76
|
-
x1, y1 = p1
|
77
|
-
x2, y2 = p2
|
78
|
-
|
79
|
-
slope = (y2 - y1) / (x2 - x1)
|
80
|
-
|
81
|
-
xs = np.arange(x1, x2 + 1, 0.01)
|
82
|
-
ys = y1 + slope * (xs - x1)
|
83
|
-
pts = np.vstack([xs, ys]).T
|
84
|
-
print(pts.shape)
|
85
|
-
|
86
|
-
pts = np.ceil(pts).astype(int) # 離散化する。
|
87
|
-
pts = np.unique(pts, axis=0) # 重複する点を削除
|
88
|
-
|
89
61
|
# 白紙の画像を作成する。
|
90
62
|
img = np.full((10, 10, 3), 255, dtype=np.uint8)
|
91
63
|
|
92
64
|
# 点が通るピクセル一覧を計算する。
|
93
|
-
x1, y1 =
|
65
|
+
x1, y1 = 8, 5
|
94
|
-
x2, y2 =
|
66
|
+
x2, y2 = 1, 1
|
95
67
|
|
68
|
+
# 点を計算する。
|
96
|
-
points = calc_points(x1, y1, x2, y2)
|
69
|
+
points = calc_points(x1, y1, x2, y2, ax)
|
70
|
+
print(points)
|
97
71
|
for x, y in points:
|
98
72
|
img[y, x] = [255, 0, 0] # 赤
|
73
|
+
|
74
|
+
# 描画部分
|
75
|
+
##################################################
|
76
|
+
import matplotlib.pyplot as plt
|
77
|
+
from matplotlib.lines import Line2D
|
78
|
+
fig, ax = plt.subplots(figsize=(8, 8), facecolor='w')
|
99
79
|
|
80
|
+
# 画像を表示する。
|
100
|
-
|
81
|
+
ax.imshow(img, interpolation='none')
|
82
|
+
# 線を描画する。
|
101
83
|
ax.add_line(Line2D([x1, x2], [y1, y2], color='g'))
|
84
|
+
# グリッド
|
85
|
+
ax.grid(which='minor', color='b', linestyle='-', linewidth=1)
|
86
|
+
# x、y 軸の目盛りのラベル
|
102
|
-
|
87
|
+
ax.set_xticks(np.arange(0, 10, 1))
|
88
|
+
ax.set_yticks(np.arange(0, 10, 1))
|
103
|
-
|
89
|
+
ax.set_xticklabels(np.arange(10))
|
90
|
+
ax.set_yticklabels(np.arange(10))
|
91
|
+
# x、y 軸の目盛りの位置
|
92
|
+
ax.set_xticks(np.arange(-.5, 10, 1), minor=True)
|
93
|
+
ax.set_yticks(np.arange(-.5, 10, 1), minor=True)
|
94
|
+
plt.show()
|
104
95
|
```
|
105
96
|
|
106
97
|

|