Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/mpl_toolkits/mplot3d/proj3d.py: 28%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

110 statements  

1""" 

2Various transforms used for by the 3D code 

3""" 

4 

5import numpy as np 

6 

7from matplotlib import _api 

8 

9 

10def world_transformation(xmin, xmax, 

11 ymin, ymax, 

12 zmin, zmax, pb_aspect=None): 

13 """ 

14 Produce a matrix that scales homogeneous coords in the specified ranges 

15 to [0, 1], or [0, pb_aspect[i]] if the plotbox aspect ratio is specified. 

16 """ 

17 dx = xmax - xmin 

18 dy = ymax - ymin 

19 dz = zmax - zmin 

20 if pb_aspect is not None: 

21 ax, ay, az = pb_aspect 

22 dx /= ax 

23 dy /= ay 

24 dz /= az 

25 

26 return np.array([[1/dx, 0, 0, -xmin/dx], 

27 [0, 1/dy, 0, -ymin/dy], 

28 [0, 0, 1/dz, -zmin/dz], 

29 [0, 0, 0, 1]]) 

30 

31 

32@_api.deprecated("3.8") 

33def rotation_about_vector(v, angle): 

34 """ 

35 Produce a rotation matrix for an angle in radians about a vector. 

36 """ 

37 return _rotation_about_vector(v, angle) 

38 

39 

40def _rotation_about_vector(v, angle): 

41 """ 

42 Produce a rotation matrix for an angle in radians about a vector. 

43 """ 

44 vx, vy, vz = v / np.linalg.norm(v) 

45 s = np.sin(angle) 

46 c = np.cos(angle) 

47 t = 2*np.sin(angle/2)**2 # more numerically stable than t = 1-c 

48 

49 R = np.array([ 

50 [t*vx*vx + c, t*vx*vy - vz*s, t*vx*vz + vy*s], 

51 [t*vy*vx + vz*s, t*vy*vy + c, t*vy*vz - vx*s], 

52 [t*vz*vx - vy*s, t*vz*vy + vx*s, t*vz*vz + c]]) 

53 

54 return R 

55 

56 

57def _view_axes(E, R, V, roll): 

58 """ 

59 Get the unit viewing axes in data coordinates. 

60 

61 Parameters 

62 ---------- 

63 E : 3-element numpy array 

64 The coordinates of the eye/camera. 

65 R : 3-element numpy array 

66 The coordinates of the center of the view box. 

67 V : 3-element numpy array 

68 Unit vector in the direction of the vertical axis. 

69 roll : float 

70 The roll angle in radians. 

71 

72 Returns 

73 ------- 

74 u : 3-element numpy array 

75 Unit vector pointing towards the right of the screen. 

76 v : 3-element numpy array 

77 Unit vector pointing towards the top of the screen. 

78 w : 3-element numpy array 

79 Unit vector pointing out of the screen. 

80 """ 

81 w = (E - R) 

82 w = w/np.linalg.norm(w) 

83 u = np.cross(V, w) 

84 u = u/np.linalg.norm(u) 

85 v = np.cross(w, u) # Will be a unit vector 

86 

87 # Save some computation for the default roll=0 

88 if roll != 0: 

89 # A positive rotation of the camera is a negative rotation of the world 

90 Rroll = _rotation_about_vector(w, -roll) 

91 u = np.dot(Rroll, u) 

92 v = np.dot(Rroll, v) 

93 return u, v, w 

94 

95 

96def _view_transformation_uvw(u, v, w, E): 

97 """ 

98 Return the view transformation matrix. 

99 

100 Parameters 

101 ---------- 

102 u : 3-element numpy array 

103 Unit vector pointing towards the right of the screen. 

104 v : 3-element numpy array 

105 Unit vector pointing towards the top of the screen. 

106 w : 3-element numpy array 

107 Unit vector pointing out of the screen. 

108 E : 3-element numpy array 

109 The coordinates of the eye/camera. 

110 """ 

111 Mr = np.eye(4) 

112 Mt = np.eye(4) 

113 Mr[:3, :3] = [u, v, w] 

114 Mt[:3, -1] = -E 

115 M = np.dot(Mr, Mt) 

116 return M 

117 

118 

119@_api.deprecated("3.8") 

120def view_transformation(E, R, V, roll): 

121 """ 

122 Return the view transformation matrix. 

123 

124 Parameters 

125 ---------- 

126 E : 3-element numpy array 

127 The coordinates of the eye/camera. 

128 R : 3-element numpy array 

129 The coordinates of the center of the view box. 

130 V : 3-element numpy array 

131 Unit vector in the direction of the vertical axis. 

132 roll : float 

133 The roll angle in radians. 

134 """ 

135 u, v, w = _view_axes(E, R, V, roll) 

136 M = _view_transformation_uvw(u, v, w, E) 

137 return M 

138 

139 

140@_api.deprecated("3.8") 

141def persp_transformation(zfront, zback, focal_length): 

142 return _persp_transformation(zfront, zback, focal_length) 

143 

144 

145def _persp_transformation(zfront, zback, focal_length): 

146 e = focal_length 

147 a = 1 # aspect ratio 

148 b = (zfront+zback)/(zfront-zback) 

149 c = -2*(zfront*zback)/(zfront-zback) 

150 proj_matrix = np.array([[e, 0, 0, 0], 

151 [0, e/a, 0, 0], 

152 [0, 0, b, c], 

153 [0, 0, -1, 0]]) 

154 return proj_matrix 

155 

156 

157@_api.deprecated("3.8") 

158def ortho_transformation(zfront, zback): 

159 return _ortho_transformation(zfront, zback) 

160 

161 

162def _ortho_transformation(zfront, zback): 

163 # note: w component in the resulting vector will be (zback-zfront), not 1 

164 a = -(zfront + zback) 

165 b = -(zfront - zback) 

166 proj_matrix = np.array([[2, 0, 0, 0], 

167 [0, 2, 0, 0], 

168 [0, 0, -2, 0], 

169 [0, 0, a, b]]) 

170 return proj_matrix 

171 

172 

173def _proj_transform_vec(vec, M): 

174 vecw = np.dot(M, vec) 

175 w = vecw[3] 

176 # clip here.. 

177 txs, tys, tzs = vecw[0]/w, vecw[1]/w, vecw[2]/w 

178 return txs, tys, tzs 

179 

180 

181def _proj_transform_vec_clip(vec, M): 

182 vecw = np.dot(M, vec) 

183 w = vecw[3] 

184 # clip here. 

185 txs, tys, tzs = vecw[0] / w, vecw[1] / w, vecw[2] / w 

186 tis = (0 <= vecw[0]) & (vecw[0] <= 1) & (0 <= vecw[1]) & (vecw[1] <= 1) 

187 if np.any(tis): 

188 tis = vecw[1] < 1 

189 return txs, tys, tzs, tis 

190 

191 

192def inv_transform(xs, ys, zs, invM): 

193 """ 

194 Transform the points by the inverse of the projection matrix, *invM*. 

195 """ 

196 vec = _vec_pad_ones(xs, ys, zs) 

197 vecr = np.dot(invM, vec) 

198 if vecr.shape == (4,): 

199 vecr = vecr.reshape((4, 1)) 

200 for i in range(vecr.shape[1]): 

201 if vecr[3][i] != 0: 

202 vecr[:, i] = vecr[:, i] / vecr[3][i] 

203 return vecr[0], vecr[1], vecr[2] 

204 

205 

206def _vec_pad_ones(xs, ys, zs): 

207 return np.array([xs, ys, zs, np.ones_like(xs)]) 

208 

209 

210def proj_transform(xs, ys, zs, M): 

211 """ 

212 Transform the points by the projection matrix *M*. 

213 """ 

214 vec = _vec_pad_ones(xs, ys, zs) 

215 return _proj_transform_vec(vec, M) 

216 

217 

218transform = _api.deprecated( 

219 "3.8", obj_type="function", name="transform", 

220 alternative="proj_transform")(proj_transform) 

221 

222 

223def proj_transform_clip(xs, ys, zs, M): 

224 """ 

225 Transform the points by the projection matrix 

226 and return the clipping result 

227 returns txs, tys, tzs, tis 

228 """ 

229 vec = _vec_pad_ones(xs, ys, zs) 

230 return _proj_transform_vec_clip(vec, M) 

231 

232 

233@_api.deprecated("3.8") 

234def proj_points(points, M): 

235 return _proj_points(points, M) 

236 

237 

238def _proj_points(points, M): 

239 return np.column_stack(_proj_trans_points(points, M)) 

240 

241 

242@_api.deprecated("3.8") 

243def proj_trans_points(points, M): 

244 return _proj_trans_points(points, M) 

245 

246 

247def _proj_trans_points(points, M): 

248 xs, ys, zs = zip(*points) 

249 return proj_transform(xs, ys, zs, M) 

250 

251 

252@_api.deprecated("3.8") 

253def rot_x(V, alpha): 

254 cosa, sina = np.cos(alpha), np.sin(alpha) 

255 M1 = np.array([[1, 0, 0, 0], 

256 [0, cosa, -sina, 0], 

257 [0, sina, cosa, 0], 

258 [0, 0, 0, 1]]) 

259 return np.dot(M1, V)