回答編集履歴
3
GitHubリンク追記
answer
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
@tiitoiさんの回答にある論文はさっぱり分かりませんが、引用したコードの条件式を手探りで発見し要件を満たす結果が得られたことはとても満足しています。
|
8
8
|
@tiitoiさんの描画部分のコードのおかげで試行錯誤とテストが捗りとても感謝しています。
|
9
9
|
|
10
|
+
|
10
11
|
変更した判定条件式
|
11
12
|
```
|
12
13
|
chk = a * p.x + b * p.y + c
|
@@ -121,4 +122,5 @@
|
|
121
122
|
ax.add_line(Line2D([s.x, e.x], [s.y, e.y], color='g'))
|
122
123
|
show_image(ax, img)
|
123
124
|
# plt.savefig('test.png')
|
124
|
-
```
|
125
|
+
```
|
126
|
+
[GitHub](https://github.com/opyon/public/blob/master/Python3/qa149396.ipynb)
|
2
条件式改修+描画部分引用
answer
CHANGED
@@ -1,30 +1,43 @@
|
|
1
1
|
[線分の上に点が載っているか判定する](https://www.pandanoir.info/entry/2016/11/08/130504)
|
2
2
|
|
3
|
-
~~検証していませんが、上記サンプルコードに線分と判定する座標を与えれば判定出来そうですね。~~
|
4
|
-
~~実装頑張ってみてください。~~
|
5
|
-
|
6
|
-
判定部分
|
3
|
+
判定部分は上記から引用し改修しました。
|
4
|
+
描画部分は@tiitoiさんコードから引用し改修しました。
|
7
5
|
上記参考コードをそのまま移植するだけでは判定出来ませんでした。
|
8
|
-
試行錯誤したところ、判定条件式 `a * p.x + b * p.y + c == 0`
|
6
|
+
試行錯誤したところ、判定条件式 `a * p.x + b * p.y + c == 0` から下記のように変更することで欲しい結果が得られました。
|
7
|
+
@tiitoiさんの回答にある論文はさっぱり分かりませんが、引用したコードの条件式を手探りで発見し要件を満たす結果が得られたことはとても満足しています。
|
8
|
+
@tiitoiさんの描画部分のコードのおかげで試行錯誤とテストが捗りとても感謝しています。
|
9
9
|
|
10
10
|
変更した判定条件式
|
11
11
|
```
|
12
|
-
chk = a * p.x + b * p.y + c
|
12
|
+
chk = a * p.x + b * p.y + c
|
13
|
+
|
14
|
+
len_x = e.x - s.x
|
15
|
+
len_y = e.y - s.y
|
16
|
+
if len_x == len_y:
|
17
|
+
v = 0
|
18
|
+
else:
|
19
|
+
v = len_x // 2 + len_y // 2
|
20
|
+
|
13
|
-
if chk >= -
|
21
|
+
if chk >= v * -1 and chk <= v:
|
22
|
+
return True
|
23
|
+
else:
|
24
|
+
return False
|
14
25
|
```
|
26
|
+

|
15
27
|
|
16
|
-
但し計算根拠に基づいた式を作ったわけではなく手探りで見つけただけなので正しいアルゴリズムかどうかは分かりません。
|
17
|
-
|
28
|
+
```Python3
|
29
|
+
import sys
|
18
|
-
|
30
|
+
import numpy as np
|
31
|
+
print(sys.version)
|
19
32
|
|
20
|
-
```Python3
|
21
33
|
class Point_():
|
22
34
|
|
23
35
|
def __init__(self, x_init, y_init):
|
24
36
|
self.x = x_init
|
25
37
|
self.y = y_init
|
26
38
|
|
39
|
+
|
27
|
-
def chk(s,e,p):
|
40
|
+
def chk(s, e, p):
|
28
41
|
if s.x <= p.x and p.x <= e.x:
|
29
42
|
if s.y <= e.y \
|
30
43
|
and (s.y <= p.y and p.y <= e.y) \
|
@@ -36,43 +49,76 @@
|
|
36
49
|
b = s.x - e.x
|
37
50
|
c = s.x * (s.y - e.y) - s.y * (s.x - e.x)
|
38
51
|
|
52
|
+
#以下判定条件式を追加改修
|
39
53
|
chk = a * p.x + b * p.y + c
|
54
|
+
|
55
|
+
len_x = e.x - s.x
|
56
|
+
len_y = e.y - s.y
|
57
|
+
if len_x == len_y:
|
58
|
+
v = 0
|
59
|
+
else:
|
60
|
+
v = len_x // 2 + len_y // 2
|
61
|
+
|
40
|
-
if chk >= -
|
62
|
+
if chk >= v * -1 and chk <= v:
|
41
63
|
return True
|
42
64
|
else:
|
43
|
-
pass
|
44
65
|
return False
|
66
|
+
#追加改修以上
|
45
67
|
|
46
|
-
|
68
|
+
# 描画部分は@tiitoiさんコードから引用しコードに合わせて改修
|
47
|
-
|
69
|
+
import matplotlib.pyplot as plt
|
48
|
-
|
70
|
+
from matplotlib.lines import Line2D
|
49
|
-
e_y = 3
|
50
71
|
|
51
|
-
|
72
|
+
def show_image(ax, img):
|
73
|
+
ax.imshow(img, interpolation='none')
|
74
|
+
ax.grid(which='minor', color='b', linestyle='-', linewidth=1)
|
75
|
+
# Major ticks
|
76
|
+
ax.set_xticks(np.arange(0, 10, 1))
|
77
|
+
ax.set_yticks(np.arange(0, 10, 1))
|
52
|
-
|
78
|
+
# Labels for major ticks
|
79
|
+
ax.set_xticklabels(np.arange(10))
|
80
|
+
ax.set_yticklabels(np.arange(10))
|
81
|
+
# Minor ticks
|
82
|
+
ax.set_xticks(np.arange(-.5, 10, 1), minor=True)
|
83
|
+
ax.set_yticks(np.arange(-.5, 10, 1), minor=True)
|
53
84
|
|
85
|
+
def draw_line(img, p1, p2, color=[255, 0, 0]):
|
86
|
+
x1, y1 = p1
|
87
|
+
x2, y2 = p2
|
88
|
+
|
89
|
+
slope = (y2 - y1) / (x2 - x1)
|
90
|
+
|
91
|
+
xs = np.arange(x1, x2 + 1, 0.01)
|
92
|
+
ys = y1 + slope * (xs - x1)
|
93
|
+
pts = np.vstack([xs, ys]).T
|
94
|
+
print(pts.shape)
|
95
|
+
|
96
|
+
pts = np.ceil(pts).astype(int) # 離散化する。
|
97
|
+
pts = np.unique(pts, axis=0) # 重複する点を削除
|
98
|
+
|
99
|
+
# 座標入力
|
100
|
+
s = Point_(1, 2)
|
101
|
+
e = Point_(8, 7)
|
102
|
+
|
54
|
-
print(f'直線({
|
103
|
+
print(f'直線({s.x},{s.y})-({e.x},{e.y})')
|
104
|
+
points = []
|
55
|
-
for p_x in range(
|
105
|
+
for p_x in range(s.x,e.x+1,1):
|
56
|
-
for p_y in range(
|
106
|
+
for p_y in range(s.y,e.y+1,1):
|
57
107
|
p = Point_(p_x, p_y)
|
108
|
+
ret = chk(s,e,p)
|
109
|
+
if ret:
|
58
|
-
|
110
|
+
points.append([p_x,p_y])
|
59
111
|
|
60
|
-
|
112
|
+
points = np.array(points)
|
61
113
|
|
62
|
-
|
114
|
+
# 白紙の画像を作成する。
|
115
|
+
img = np.full((10, 10, 3), 255, dtype=np.uint8)
|
116
|
+
|
63
|
-
|
117
|
+
for x, y in points:
|
118
|
+
img[y, x] = [255, 0, 0] # 赤
|
119
|
+
|
120
|
+
fig, ax = plt.subplots(figsize=(8, 8), facecolor='w')
|
64
|
-
|
121
|
+
ax.add_line(Line2D([s.x, e.x], [s.y, e.y], color='g'))
|
65
|
-
|
122
|
+
show_image(ax, img)
|
66
|
-
点(0,0) True
|
67
|
-
点(0,1) True
|
68
|
-
|
123
|
+
# plt.savefig('test.png')
|
69
|
-
点(0,3) False
|
70
|
-
点(1,0) False
|
71
|
-
点(1,1) True
|
72
|
-
点(1,2) True
|
73
|
-
点(1,3) False
|
74
|
-
点(2,0) False
|
75
|
-
点(2,1) False
|
76
|
-
点(2,2) True
|
77
|
-
点(2,3) True
|
78
124
|
```
|
1
実装してみた
answer
CHANGED
@@ -1,4 +1,78 @@
|
|
1
1
|
[線分の上に点が載っているか判定する](https://www.pandanoir.info/entry/2016/11/08/130504)
|
2
2
|
|
3
|
-
検証していませんが、上記サンプルコードに線分と判定する座標を与えれば判定出来そうですね。
|
3
|
+
~~検証していませんが、上記サンプルコードに線分と判定する座標を与えれば判定出来そうですね。~~
|
4
|
-
実装頑張ってみてください。
|
4
|
+
~~実装頑張ってみてください。~~
|
5
|
+
|
6
|
+
判定部分のみ実装してみました。
|
7
|
+
上記参考コードをそのまま移植するだけでは判定出来ませんでした。
|
8
|
+
試行錯誤したところ、判定条件式 `a * p.x + b * p.y + c == 0` を変更することで欲しい結果が得られました。
|
9
|
+
|
10
|
+
変更した判定条件式
|
11
|
+
```
|
12
|
+
chk = a * p.x + b * p.y + c
|
13
|
+
if chk >= -2 and chk <= 2:
|
14
|
+
```
|
15
|
+
|
16
|
+
但し計算根拠に基づいた式を作ったわけではなく手探りで見つけただけなので正しいアルゴリズムかどうかは分かりません。
|
17
|
+
検証範囲も始点固定(0,0)で、終点(1,3)終点(2,3)終点(3,3)だけです。
|
18
|
+
この範囲なら要件通りの判定出来ています。
|
19
|
+
|
20
|
+
```Python3
|
21
|
+
class Point_():
|
22
|
+
|
23
|
+
def __init__(self, x_init, y_init):
|
24
|
+
self.x = x_init
|
25
|
+
self.y = y_init
|
26
|
+
|
27
|
+
def chk(s,e,p):
|
28
|
+
if s.x <= p.x and p.x <= e.x:
|
29
|
+
if s.y <= e.y \
|
30
|
+
and (s.y <= p.y and p.y <= e.y) \
|
31
|
+
or s.y >= e.y \
|
32
|
+
and (s.y >= p.y \
|
33
|
+
and p.y >= e.y) \
|
34
|
+
:
|
35
|
+
a = e.y - s.y
|
36
|
+
b = s.x - e.x
|
37
|
+
c = s.x * (s.y - e.y) - s.y * (s.x - e.x)
|
38
|
+
|
39
|
+
chk = a * p.x + b * p.y + c
|
40
|
+
if chk >= -2 and chk <= 2:
|
41
|
+
return True
|
42
|
+
else:
|
43
|
+
pass
|
44
|
+
return False
|
45
|
+
|
46
|
+
s_x = 0
|
47
|
+
s_y = 0
|
48
|
+
e_x = 2
|
49
|
+
e_y = 3
|
50
|
+
|
51
|
+
s = Point_(s_x, s_y)
|
52
|
+
e = Point_(e_x, e_y)
|
53
|
+
|
54
|
+
print(f'直線({s_x},{s_y})-({e_x},{e_y})')
|
55
|
+
for p_x in range(e_x+1):
|
56
|
+
for p_y in range(e_y+1):
|
57
|
+
p = Point_(p_x, p_y)
|
58
|
+
print(f'点({p_x},{p_y}) {chk(s,e,p)} ')
|
59
|
+
|
60
|
+
```
|
61
|
+
|
62
|
+
出力例
|
63
|
+
```
|
64
|
+
3.7.0 (default, Jun 28 2018, 08:04:48) [MSC v.1912 64 bit (AMD64)]
|
65
|
+
直線(0,0)-(2,3)
|
66
|
+
点(0,0) True
|
67
|
+
点(0,1) True
|
68
|
+
点(0,2) False
|
69
|
+
点(0,3) False
|
70
|
+
点(1,0) False
|
71
|
+
点(1,1) True
|
72
|
+
点(1,2) True
|
73
|
+
点(1,3) False
|
74
|
+
点(2,0) False
|
75
|
+
点(2,1) False
|
76
|
+
点(2,2) True
|
77
|
+
点(2,3) True
|
78
|
+
```
|