teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

2018/10/01 08:51

投稿

tiitoi
tiitoi

スコア21960

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 = 1, 1
65
+ x1, y1 = 8, 5
94
- x2, y2 = 8, 5
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
- fig, ax = plt.subplots(figsize=(8, 8), facecolor='w')
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
- show_image(ax, img)
87
+ ax.set_xticks(np.arange(0, 10, 1))
88
+ ax.set_yticks(np.arange(0, 10, 1))
103
- plt.savefig('test.png')
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
  ![イメージ説明](1cfbcaeaf8b1b2cf9ab5057bedf0cc3c.png)