Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scipy/spatial/transform/_rotation_groups.py: 14%
56 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-12 06:31 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-12 06:31 +0000
1import numpy as np
2from scipy.constants import golden as phi
5def icosahedral(cls):
6 g1 = tetrahedral(cls).as_quat()
7 a = 0.5
8 b = 0.5 / phi
9 c = phi / 2
10 g2 = np.array([[+a, +b, +c, 0],
11 [+a, +b, -c, 0],
12 [+a, +c, 0, +b],
13 [+a, +c, 0, -b],
14 [+a, -b, +c, 0],
15 [+a, -b, -c, 0],
16 [+a, -c, 0, +b],
17 [+a, -c, 0, -b],
18 [+a, 0, +b, +c],
19 [+a, 0, +b, -c],
20 [+a, 0, -b, +c],
21 [+a, 0, -b, -c],
22 [+b, +a, 0, +c],
23 [+b, +a, 0, -c],
24 [+b, +c, +a, 0],
25 [+b, +c, -a, 0],
26 [+b, -a, 0, +c],
27 [+b, -a, 0, -c],
28 [+b, -c, +a, 0],
29 [+b, -c, -a, 0],
30 [+b, 0, +c, +a],
31 [+b, 0, +c, -a],
32 [+b, 0, -c, +a],
33 [+b, 0, -c, -a],
34 [+c, +a, +b, 0],
35 [+c, +a, -b, 0],
36 [+c, +b, 0, +a],
37 [+c, +b, 0, -a],
38 [+c, -a, +b, 0],
39 [+c, -a, -b, 0],
40 [+c, -b, 0, +a],
41 [+c, -b, 0, -a],
42 [+c, 0, +a, +b],
43 [+c, 0, +a, -b],
44 [+c, 0, -a, +b],
45 [+c, 0, -a, -b],
46 [0, +a, +c, +b],
47 [0, +a, +c, -b],
48 [0, +a, -c, +b],
49 [0, +a, -c, -b],
50 [0, +b, +a, +c],
51 [0, +b, +a, -c],
52 [0, +b, -a, +c],
53 [0, +b, -a, -c],
54 [0, +c, +b, +a],
55 [0, +c, +b, -a],
56 [0, +c, -b, +a],
57 [0, +c, -b, -a]])
58 return cls.from_quat(np.concatenate((g1, g2)))
61def octahedral(cls):
62 g1 = tetrahedral(cls).as_quat()
63 c = np.sqrt(2) / 2
64 g2 = np.array([[+c, 0, 0, +c],
65 [0, +c, 0, +c],
66 [0, 0, +c, +c],
67 [0, 0, -c, +c],
68 [0, -c, 0, +c],
69 [-c, 0, 0, +c],
70 [0, +c, +c, 0],
71 [0, -c, +c, 0],
72 [+c, 0, +c, 0],
73 [-c, 0, +c, 0],
74 [+c, +c, 0, 0],
75 [-c, +c, 0, 0]])
76 return cls.from_quat(np.concatenate((g1, g2)))
79def tetrahedral(cls):
80 g1 = np.eye(4)
81 c = 0.5
82 g2 = np.array([[c, -c, -c, +c],
83 [c, -c, +c, +c],
84 [c, +c, -c, +c],
85 [c, +c, +c, +c],
86 [c, -c, -c, -c],
87 [c, -c, +c, -c],
88 [c, +c, -c, -c],
89 [c, +c, +c, -c]])
90 return cls.from_quat(np.concatenate((g1, g2)))
93def dicyclic(cls, n, axis=2):
94 g1 = cyclic(cls, n, axis).as_rotvec()
96 thetas = np.linspace(0, np.pi, n, endpoint=False)
97 rv = np.pi * np.vstack([np.zeros(n), np.cos(thetas), np.sin(thetas)]).T
98 g2 = np.roll(rv, axis, axis=1)
99 return cls.from_rotvec(np.concatenate((g1, g2)))
102def cyclic(cls, n, axis=2):
103 thetas = np.linspace(0, 2 * np.pi, n, endpoint=False)
104 rv = np.vstack([thetas, np.zeros(n), np.zeros(n)]).T
105 return cls.from_rotvec(np.roll(rv, axis, axis=1))
108def create_group(cls, group, axis='Z'):
109 if not isinstance(group, str):
110 raise ValueError("`group` argument must be a string")
112 permitted_axes = ['x', 'y', 'z', 'X', 'Y', 'Z']
113 if axis not in permitted_axes:
114 raise ValueError("`axis` must be one of " + ", ".join(permitted_axes))
116 if group in ['I', 'O', 'T']:
117 symbol = group
118 order = 1
119 elif group[:1] in ['C', 'D'] and group[1:].isdigit():
120 symbol = group[:1]
121 order = int(group[1:])
122 else:
123 raise ValueError("`group` must be one of 'I', 'O', 'T', 'Dn', 'Cn'")
125 if order < 1:
126 raise ValueError("Group order must be positive")
128 axis = 'xyz'.index(axis.lower())
129 if symbol == 'I':
130 return icosahedral(cls)
131 elif symbol == 'O':
132 return octahedral(cls)
133 elif symbol == 'T':
134 return tetrahedral(cls)
135 elif symbol == 'D':
136 return dicyclic(cls, order, axis=axis)
137 elif symbol == 'C':
138 return cyclic(cls, order, axis=axis)
139 else:
140 assert False