回答編集履歴
2
d
test
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
|
1
|
+
fana さんが回答してくださった方法で実装してみました。
|
2
2
|
|
3
3
|
|
4
|
-
|
5
|
-
行列の各要素を4点で構成される正方形と考え、回転している x 軸に垂直な直線が交わる正方形を求めて、その値の平均をとる。
|
6
4
|
|
7
5
|
|
8
6
|
|
@@ -13,6 +11,10 @@
|
|
13
11
|
|
14
12
|
|
15
13
|
```python
|
14
|
+
|
15
|
+
import matplotlib.pyplot as plt
|
16
|
+
|
17
|
+
from matplotlib.patches import Rectangle
|
16
18
|
|
17
19
|
import numpy as np
|
18
20
|
|
@@ -30,11 +32,21 @@
|
|
30
32
|
|
31
33
|
[7, 2, 1, 6, 2, 8]], dtype=float)
|
32
34
|
|
35
|
+
angle = 10 # x 軸の回転角度 (degree)
|
36
|
+
|
33
|
-
|
37
|
+
radius = np.array(mat.shape) // 2 # 半径
|
34
38
|
|
35
39
|
|
36
40
|
|
41
|
+
def create_rotation_matrix(angle):
|
42
|
+
|
37
|
-
t
|
43
|
+
t = np.deg2rad(angle)
|
44
|
+
|
45
|
+
return np.array([[np.cos(t), -np.sin(t)],
|
46
|
+
|
47
|
+
[np.sin(t), np.cos(t)]])
|
48
|
+
|
49
|
+
R = create_rotation_matrix(-angle) # x 軸の回転方向とは逆の方向に回転する回転行列
|
38
50
|
|
39
51
|
```
|
40
52
|
|
@@ -42,21 +54,105 @@
|
|
42
54
|
|
43
55
|
```
|
44
56
|
|
57
|
+
# 各セルの4点の座標を作成する。
|
58
|
+
|
45
59
|
cells = []
|
60
|
+
|
61
|
+
id_ = 0 # あとでどのセルが含まれているのか確認するための識別子 (デバッグ用)
|
46
62
|
|
47
63
|
for (i, j), value in np.ndenumerate(mat):
|
48
64
|
|
49
|
-
#
|
65
|
+
# セルの左下の点 (x, y) を定義する。
|
50
66
|
|
51
|
-
|
67
|
+
x, y = j - radius[1], radius[0] - i - 1
|
52
68
|
|
53
|
-
x, y = j - mat.shape[1] // 2, i - mat.shape[0] // 2
|
54
|
-
|
55
|
-
# セルを構成する点
|
69
|
+
# セルを構成する4点を作成する。
|
56
70
|
|
57
71
|
rect = np.array([[x, y], [x + 1, y], [x + 1, y + 1], [x, y + 1], [x, y]])
|
58
72
|
|
73
|
+
# セルを構成する4点を回転させる。
|
74
|
+
|
75
|
+
rect = rect.dot(R.T)
|
76
|
+
|
77
|
+
|
78
|
+
|
59
|
-
cells.append(
|
79
|
+
cells.append((id_, rect, value))
|
80
|
+
|
81
|
+
id_ += 1
|
82
|
+
|
83
|
+
```
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
各区別 [x_i, x_{i + 1}] に含まれるセルを見つけて、その値の平均を計算する。
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
```
|
92
|
+
|
93
|
+
edges = np.arange(-radius[1], radius[1] + 1)
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
for left, right in zip(edges, edges[1:]):
|
98
|
+
|
99
|
+
values = []
|
100
|
+
|
101
|
+
for id_, rect, value in cells:
|
102
|
+
|
103
|
+
if np.any((left <= rect[:, 0]) & (rect[:, 0] <= right)):
|
104
|
+
|
105
|
+
values.append((id_, value)) # セルの4隅の1点でも [left, right] に含まれる場合
|
106
|
+
|
107
|
+
values = sorted(values, key=lambda x: x[0]) # 見やすいように id でソートする。
|
108
|
+
|
109
|
+
mean = np.mean([x[1] for x in values]) # 平均
|
110
|
+
|
111
|
+
print('{} <= x <= {}:\n value: {}\n mean: {}'.format(
|
112
|
+
|
113
|
+
left, right, values, mean))
|
114
|
+
|
115
|
+
```
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
```
|
120
|
+
|
121
|
+
-3 <= x <= -2:
|
122
|
+
|
123
|
+
value: [(0, 3.0), (6, 2.0), (12, 4.0), (18, 0.0), (19, 4.0), (24, 4.0), (25, 2.0), (30, 7.0), (31, 2.0)]
|
124
|
+
|
125
|
+
mean: 3.111111111111111
|
126
|
+
|
127
|
+
-2 <= x <= -1:
|
128
|
+
|
129
|
+
value: [(0, 3.0), (1, 4.0), (6, 2.0), (7, 8.0), (12, 4.0), (13, 8.0), (18, 0.0), (19, 4.0), (20, 3.0), (25, 2.0), (26, 6.0), (31, 2.0), (32, 1.0)]
|
130
|
+
|
131
|
+
mean: 3.6153846153846154
|
132
|
+
|
133
|
+
-1 <= x <= 0:
|
134
|
+
|
135
|
+
value: [(1, 4.0), (2, 6.0), (7, 8.0), (8, 5.0), (13, 8.0), (14, 1.0), (15, 0.0), (19, 4.0), (20, 3.0), (21, 7.0), (26, 6.0), (27, 1.0), (32, 1.0), (33, 6.0)]
|
136
|
+
|
137
|
+
mean: 4.285714285714286
|
138
|
+
|
139
|
+
0 <= x <= 1:
|
140
|
+
|
141
|
+
value: [(2, 6.0), (3, 9.0), (8, 5.0), (9, 0.0), (14, 1.0), (15, 0.0), (16, 3.0), (20, 3.0), (21, 7.0), (22, 1.0), (27, 1.0), (28, 0.0), (33, 6.0), (34, 2.0)]
|
142
|
+
|
143
|
+
mean: 3.142857142857143
|
144
|
+
|
145
|
+
1 <= x <= 2:
|
146
|
+
|
147
|
+
value: [(3, 9.0), (4, 0.0), (9, 0.0), (10, 3.0), (15, 0.0), (16, 3.0), (17, 1.0), (22, 1.0), (23, 2.0), (28, 0.0), (29, 9.0), (34, 2.0), (35, 8.0)]
|
148
|
+
|
149
|
+
mean: 2.923076923076923
|
150
|
+
|
151
|
+
2 <= x <= 3:
|
152
|
+
|
153
|
+
value: [(4, 0.0), (5, 8.0), (10, 3.0), (11, 5.0), (16, 3.0), (17, 1.0), (23, 2.0), (29, 9.0), (35, 8.0)]
|
154
|
+
|
155
|
+
mean: 4.333333333333333
|
60
156
|
|
61
157
|
```
|
62
158
|
|
@@ -68,66 +164,34 @@
|
|
68
164
|
|
69
165
|
###################################################################
|
70
166
|
|
71
|
-
from matplotlib.patches import Rectangle
|
72
|
-
|
73
|
-
import matplotlib.pyplot as plt
|
74
|
-
|
75
167
|
fig, ax = plt.subplots(figsize=(6, 6))
|
76
168
|
|
77
169
|
|
78
170
|
|
79
171
|
# 各セルを描画する。
|
80
172
|
|
81
|
-
for rect, value in cells:
|
173
|
+
for id_, rect, value in cells:
|
82
174
|
|
83
175
|
ax.plot(rect[:, 0], rect[:, 1], c='gray', alpha=0.5) # セルの枠線
|
84
176
|
|
85
177
|
cx, cy = (rect[0] + rect[2]) / 2 # セルの中心
|
86
178
|
|
179
|
+
s = '{}:{}'.format(id_, value)
|
180
|
+
|
87
|
-
ax.text(cx, cy,
|
181
|
+
ax.text(cx, cy, s, ha='center', va='center', rotation=-angle) # 値
|
88
182
|
|
89
183
|
ax.autoscale(False)
|
90
184
|
|
185
|
+
# x 軸、y 軸を引く。
|
91
186
|
|
187
|
+
ax.axhline(), ax.axvline()
|
92
188
|
|
93
|
-
#
|
189
|
+
# 垂直線を引く
|
94
190
|
|
95
|
-
# theta だけ回転させた場合、x 軸の傾きは tan(theta), y 軸の傾きは tan(theta + 90) となることに注意すると
|
96
|
-
|
97
|
-
for j in range(mat.shape[1]):
|
98
|
-
|
99
|
-
x = j - mat.shape[1] // 2 + 0.5
|
100
|
-
|
101
|
-
# (x', y') を通り、傾き m の直線 ===> (y - y') = m (x - x')
|
102
|
-
|
103
|
-
|
191
|
+
ax.vlines(edges, *ax.get_xlim(), alpha=0.5)
|
104
|
-
|
105
|
-
ys = (xs - x) * np.tan(np.radians(theta + 90))
|
106
|
-
|
107
|
-
ax.plot(xs, ys, c='b', lw=1)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# 回転後の x 軸、y 軸を描画する。
|
112
|
-
|
113
|
-
xs = np.linspace(*ax.get_xlim(), 100)
|
114
|
-
|
115
|
-
ys = xs * np.tan(np.radians(theta))
|
116
|
-
|
117
|
-
ax.plot(xs, ys, c='k', lw=3)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
ys = xs * np.tan(np.radians(theta + 90))
|
122
|
-
|
123
|
-
ax.plot(xs, ys, c='k', lw=3)
|
124
192
|
|
125
193
|
```
|
126
194
|
|
127
195
|
|
128
196
|
|
129
|
-
![イメージ説明](
|
197
|
+
![イメージ説明](45ac21cb6f1209e2647976c8bc85f0ae.png)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
青い直線が通るセルを調べてその値の平均をとる。
|
1
d
test
CHANGED
@@ -34,7 +34,7 @@
|
|
34
34
|
|
35
35
|
|
36
36
|
|
37
|
-
theta =
|
37
|
+
theta = 10
|
38
38
|
|
39
39
|
```
|
40
40
|
|
@@ -44,9 +44,9 @@
|
|
44
44
|
|
45
45
|
cells = []
|
46
46
|
|
47
|
-
for (i, j), v in np.ndenumerate(mat):
|
47
|
+
for (i, j), value in np.ndenumerate(mat):
|
48
48
|
|
49
|
-
# 行列の (i, j) 成分を行列の中心を原点とする標準座標系の点 (x, y) に変換する式
|
49
|
+
# 行列の (i, j) 成分を行列の中心を原点とする標準座標系の点 (x, y) に変換する式
|
50
50
|
|
51
51
|
# (x, y) = j - rows // 2, i - cols // 2
|
52
52
|
|
@@ -54,9 +54,9 @@
|
|
54
54
|
|
55
55
|
# セルを構成する点
|
56
56
|
|
57
|
-
r = np.array([[x, y], [x + 1, y], [x + 1, y + 1], [x, y + 1], [x, y]])
|
57
|
+
rect = np.array([[x, y], [x + 1, y], [x + 1, y + 1], [x, y + 1], [x, y]])
|
58
58
|
|
59
|
-
cells.append([r, v])
|
59
|
+
cells.append([rect, value])
|
60
60
|
|
61
61
|
```
|
62
62
|
|
@@ -78,13 +78,13 @@
|
|
78
78
|
|
79
79
|
# 各セルを描画する。
|
80
80
|
|
81
|
-
for r, v in cells:
|
81
|
+
for rect, value in cells:
|
82
82
|
|
83
|
-
ax.plot(r[:, 0], r[:, 1], c='gray', alpha=0.5) # セルの枠線
|
83
|
+
ax.plot(rect[:, 0], rect[:, 1], c='gray', alpha=0.5) # セルの枠線
|
84
84
|
|
85
|
-
cx, cy = (r[0] + r[2]) / 2 # セルの中心
|
85
|
+
cx, cy = (rect[0] + rect[2]) / 2 # セルの中心
|
86
86
|
|
87
|
-
ax.text(cx, cy, v, ha='center', va='center') # 値
|
87
|
+
ax.text(cx, cy, value, ha='center', va='center') # 値
|
88
88
|
|
89
89
|
ax.autoscale(False)
|
90
90
|
|
@@ -94,11 +94,11 @@
|
|
94
94
|
|
95
95
|
# theta だけ回転させた場合、x 軸の傾きは tan(theta), y 軸の傾きは tan(theta + 90) となることに注意すると
|
96
96
|
|
97
|
-
for j in range(mat.shape[1]
|
97
|
+
for j in range(mat.shape[1]):
|
98
|
+
|
99
|
+
x = j - mat.shape[1] // 2 + 0.5
|
98
100
|
|
99
101
|
# (x', y') を通り、傾き m の直線 ===> (y - y') = m (x - x')
|
100
|
-
|
101
|
-
x = j - mat.shape[1] // 2
|
102
102
|
|
103
103
|
xs = np.linspace(*ax.get_xlim(), 100)
|
104
104
|
|
@@ -126,7 +126,7 @@
|
|
126
126
|
|
127
127
|
|
128
128
|
|
129
|
-
![イメージ説明](e84
|
129
|
+
![イメージ説明](e52a938e4633f9fea57ff1dc413a6e33.png)
|
130
130
|
|
131
131
|
|
132
132
|
|