5
5
__all__ = ["ThreeDCamera" ]
6
6
7
7
8
- from typing import Callable
8
+ from collections .abc import Callable , Iterable
9
+ from typing import Any
9
10
10
11
import numpy as np
11
12
16
17
get_3d_vmob_start_corner ,
17
18
get_3d_vmob_start_corner_unit_normal ,
18
19
)
20
+ from manim .mobject .types .vectorized_mobject import VMobject
19
21
from manim .mobject .value_tracker import ValueTracker
22
+ from manim .typing import (
23
+ MatrixMN ,
24
+ Point3D ,
25
+ Point3D_Array ,
26
+ Point3DLike ,
27
+ )
20
28
21
29
from .. import config
22
30
from ..camera .camera import Camera
30
38
class ThreeDCamera (Camera ):
31
39
def __init__ (
32
40
self ,
33
- focal_distance = 20.0 ,
34
- shading_factor = 0.2 ,
35
- default_distance = 5.0 ,
36
- light_source_start_point = 9 * DOWN + 7 * LEFT + 10 * OUT ,
37
- should_apply_shading = True ,
38
- exponential_projection = False ,
39
- phi = 0 ,
40
- theta = - 90 * DEGREES ,
41
- gamma = 0 ,
42
- zoom = 1 ,
43
- ** kwargs ,
41
+ focal_distance : float = 20.0 ,
42
+ shading_factor : float = 0.2 ,
43
+ default_distance : float = 5.0 ,
44
+ light_source_start_point : Point3DLike = 9 * DOWN + 7 * LEFT + 10 * OUT ,
45
+ should_apply_shading : bool = True ,
46
+ exponential_projection : bool = False ,
47
+ phi : float = 0 ,
48
+ theta : float = - 90 * DEGREES ,
49
+ gamma : float = 0 ,
50
+ zoom : float = 1 ,
51
+ ** kwargs : Any ,
44
52
):
45
53
"""Initializes the ThreeDCamera
46
54
@@ -68,23 +76,23 @@ def __init__(
68
76
self .focal_distance_tracker = ValueTracker (self .focal_distance )
69
77
self .gamma_tracker = ValueTracker (self .gamma )
70
78
self .zoom_tracker = ValueTracker (self .zoom )
71
- self .fixed_orientation_mobjects = {}
72
- self .fixed_in_frame_mobjects = set ()
79
+ self .fixed_orientation_mobjects : dict [ Mobject , Callable [[], Point3D ]] = {}
80
+ self .fixed_in_frame_mobjects : set [ Mobject ] = set ()
73
81
self .reset_rotation_matrix ()
74
82
75
83
@property
76
- def frame_center (self ):
84
+ def frame_center (self ) -> Point3D :
77
85
return self ._frame_center .points [0 ]
78
86
79
87
@frame_center .setter
80
- def frame_center (self , point ) :
88
+ def frame_center (self , point : Point3DLike ) -> None :
81
89
self ._frame_center .move_to (point )
82
90
83
- def capture_mobjects (self , mobjects , ** kwargs ) :
91
+ def capture_mobjects (self , mobjects : Iterable [ Mobject ] , ** kwargs : Any ) -> None :
84
92
self .reset_rotation_matrix ()
85
93
super ().capture_mobjects (mobjects , ** kwargs )
86
94
87
- def get_value_trackers (self ):
95
+ def get_value_trackers (self ) -> list [ ValueTracker ] :
88
96
"""A list of :class:`ValueTrackers <.ValueTracker>` of phi, theta, focal_distance,
89
97
gamma and zoom.
90
98
@@ -101,7 +109,7 @@ def get_value_trackers(self):
101
109
self .zoom_tracker ,
102
110
]
103
111
104
- def modified_rgbas (self , vmobject , rgbas ) :
112
+ def modified_rgbas (self , vmobject : VMobject , rgbas : MatrixMN ) -> MatrixMN :
105
113
if not self .should_apply_shading :
106
114
return rgbas
107
115
if vmobject .shade_in_3d and (vmobject .get_num_points () > 0 ):
@@ -127,28 +135,33 @@ def modified_rgbas(self, vmobject, rgbas):
127
135
128
136
def get_stroke_rgbas (
129
137
self ,
130
- vmobject ,
131
- background = False ,
132
- ): # NOTE : DocStrings From parent
138
+ vmobject : VMobject ,
139
+ background : bool = False ,
140
+ ) -> MatrixMN : # NOTE : DocStrings From parent
133
141
return self .modified_rgbas (vmobject , vmobject .get_stroke_rgbas (background ))
134
142
135
- def get_fill_rgbas (self , vmobject ): # NOTE : DocStrings From parent
143
+ def get_fill_rgbas (
144
+ self , vmobject : VMobject
145
+ ) -> MatrixMN : # NOTE : DocStrings From parent
136
146
return self .modified_rgbas (vmobject , vmobject .get_fill_rgbas ())
137
147
138
- def get_mobjects_to_display (self , * args , ** kwargs ): # NOTE : DocStrings From parent
148
+ def get_mobjects_to_display (
149
+ self , * args : Any , ** kwargs : Any
150
+ ) -> list [Mobject ]: # NOTE : DocStrings From parent
139
151
mobjects = super ().get_mobjects_to_display (* args , ** kwargs )
140
152
rot_matrix = self .get_rotation_matrix ()
141
153
142
- def z_key (mob ) :
154
+ def z_key (mob : Mobject ) -> float :
143
155
if not (hasattr (mob , "shade_in_3d" ) and mob .shade_in_3d ):
144
- return np .inf
156
+ return np .inf # type: ignore[no-any-return]
145
157
# Assign a number to a three dimensional mobjects
146
158
# based on how close it is to the camera
147
- return np .dot (mob .get_z_index_reference_point (), rot_matrix .T )[2 ]
159
+ distance : float = np .dot (mob .get_z_index_reference_point (), rot_matrix .T )[2 ]
160
+ return distance
148
161
149
162
return sorted (mobjects , key = z_key )
150
163
151
- def get_phi (self ):
164
+ def get_phi (self ) -> float :
152
165
"""Returns the Polar angle (the angle off Z_AXIS) phi.
153
166
154
167
Returns
@@ -158,7 +171,7 @@ def get_phi(self):
158
171
"""
159
172
return self .phi_tracker .get_value ()
160
173
161
- def get_theta (self ):
174
+ def get_theta (self ) -> float :
162
175
"""Returns the Azimuthal i.e the angle that spins the camera around the Z_AXIS.
163
176
164
177
Returns
@@ -168,7 +181,7 @@ def get_theta(self):
168
181
"""
169
182
return self .theta_tracker .get_value ()
170
183
171
- def get_focal_distance (self ):
184
+ def get_focal_distance (self ) -> float :
172
185
"""Returns focal_distance of the Camera.
173
186
174
187
Returns
@@ -178,7 +191,7 @@ def get_focal_distance(self):
178
191
"""
179
192
return self .focal_distance_tracker .get_value ()
180
193
181
- def get_gamma (self ):
194
+ def get_gamma (self ) -> float :
182
195
"""Returns the rotation of the camera about the vector from the ORIGIN to the Camera.
183
196
184
197
Returns
@@ -189,7 +202,7 @@ def get_gamma(self):
189
202
"""
190
203
return self .gamma_tracker .get_value ()
191
204
192
- def get_zoom (self ):
205
+ def get_zoom (self ) -> float :
193
206
"""Returns the zoom amount of the camera.
194
207
195
208
Returns
@@ -199,7 +212,7 @@ def get_zoom(self):
199
212
"""
200
213
return self .zoom_tracker .get_value ()
201
214
202
- def set_phi (self , value : float ):
215
+ def set_phi (self , value : float ) -> None :
203
216
"""Sets the polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians.
204
217
205
218
Parameters
@@ -209,7 +222,7 @@ def set_phi(self, value: float):
209
222
"""
210
223
self .phi_tracker .set_value (value )
211
224
212
- def set_theta (self , value : float ):
225
+ def set_theta (self , value : float ) -> None :
213
226
"""Sets the azimuthal angle i.e the angle that spins the camera around Z_AXIS in radians.
214
227
215
228
Parameters
@@ -219,7 +232,7 @@ def set_theta(self, value: float):
219
232
"""
220
233
self .theta_tracker .set_value (value )
221
234
222
- def set_focal_distance (self , value : float ):
235
+ def set_focal_distance (self , value : float ) -> None :
223
236
"""Sets the focal_distance of the Camera.
224
237
225
238
Parameters
@@ -229,7 +242,7 @@ def set_focal_distance(self, value: float):
229
242
"""
230
243
self .focal_distance_tracker .set_value (value )
231
244
232
- def set_gamma (self , value : float ):
245
+ def set_gamma (self , value : float ) -> None :
233
246
"""Sets the angle of rotation of the camera about the vector from the ORIGIN to the Camera.
234
247
235
248
Parameters
@@ -239,7 +252,7 @@ def set_gamma(self, value: float):
239
252
"""
240
253
self .gamma_tracker .set_value (value )
241
254
242
- def set_zoom (self , value : float ):
255
+ def set_zoom (self , value : float ) -> None :
243
256
"""Sets the zoom amount of the camera.
244
257
245
258
Parameters
@@ -249,13 +262,13 @@ def set_zoom(self, value: float):
249
262
"""
250
263
self .zoom_tracker .set_value (value )
251
264
252
- def reset_rotation_matrix (self ):
265
+ def reset_rotation_matrix (self ) -> None :
253
266
"""Sets the value of self.rotation_matrix to
254
267
the matrix corresponding to the current position of the camera
255
268
"""
256
269
self .rotation_matrix = self .generate_rotation_matrix ()
257
270
258
- def get_rotation_matrix (self ):
271
+ def get_rotation_matrix (self ) -> MatrixMN :
259
272
"""Returns the matrix corresponding to the current position of the camera.
260
273
261
274
Returns
@@ -265,7 +278,7 @@ def get_rotation_matrix(self):
265
278
"""
266
279
return self .rotation_matrix
267
280
268
- def generate_rotation_matrix (self ):
281
+ def generate_rotation_matrix (self ) -> MatrixMN :
269
282
"""Generates a rotation matrix based off the current position of the camera.
270
283
271
284
Returns
@@ -286,7 +299,7 @@ def generate_rotation_matrix(self):
286
299
result = np .dot (matrix , result )
287
300
return result
288
301
289
- def project_points (self , points : np . ndarray | list ) :
302
+ def project_points (self , points : Point3D_Array ) -> Point3D_Array :
290
303
"""Applies the current rotation_matrix as a projection
291
304
matrix to the passed array of points.
292
305
@@ -323,7 +336,7 @@ def project_points(self, points: np.ndarray | list):
323
336
points [:, i ] *= factor * zoom
324
337
return points
325
338
326
- def project_point (self , point : list | np . ndarray ) :
339
+ def project_point (self , point : Point3D ) -> Point3D :
327
340
"""Applies the current rotation_matrix as a projection
328
341
matrix to the passed point.
329
342
@@ -341,9 +354,9 @@ def project_point(self, point: list | np.ndarray):
341
354
342
355
def transform_points_pre_display (
343
356
self ,
344
- mobject ,
345
- points ,
346
- ): # TODO: Write Docstrings for this Method.
357
+ mobject : Mobject ,
358
+ points : Point3D_Array ,
359
+ ) -> Point3D_Array : # TODO: Write Docstrings for this Method.
347
360
points = super ().transform_points_pre_display (mobject , points )
348
361
fixed_orientation = mobject in self .fixed_orientation_mobjects
349
362
fixed_in_frame = mobject in self .fixed_in_frame_mobjects
@@ -362,8 +375,8 @@ def add_fixed_orientation_mobjects(
362
375
self ,
363
376
* mobjects : Mobject ,
364
377
use_static_center_func : bool = False ,
365
- center_func : Callable [[], np . ndarray ] | None = None ,
366
- ):
378
+ center_func : Callable [[], Point3D ] | None = None ,
379
+ ) -> None :
367
380
"""This method allows the mobject to have a fixed orientation,
368
381
even when the camera moves around.
369
382
E.G If it was passed through this method, facing the camera, it
@@ -384,7 +397,7 @@ def add_fixed_orientation_mobjects(
384
397
385
398
# This prevents the computation of mobject.get_center
386
399
# every single time a projection happens
387
- def get_static_center_func (mobject ) :
400
+ def get_static_center_func (mobject : Mobject ) -> Callable [[], Point3D ] :
388
401
point = mobject .get_center ()
389
402
return lambda : point
390
403
@@ -398,7 +411,7 @@ def get_static_center_func(mobject):
398
411
for submob in mobject .get_family ():
399
412
self .fixed_orientation_mobjects [submob ] = func
400
413
401
- def add_fixed_in_frame_mobjects (self , * mobjects : Mobject ):
414
+ def add_fixed_in_frame_mobjects (self , * mobjects : Mobject ) -> None :
402
415
"""This method allows the mobject to have a fixed position,
403
416
even when the camera moves around.
404
417
E.G If it was passed through this method, at the top of the frame, it
@@ -414,7 +427,7 @@ def add_fixed_in_frame_mobjects(self, *mobjects: Mobject):
414
427
for mobject in extract_mobject_family_members (mobjects ):
415
428
self .fixed_in_frame_mobjects .add (mobject )
416
429
417
- def remove_fixed_orientation_mobjects (self , * mobjects : Mobject ):
430
+ def remove_fixed_orientation_mobjects (self , * mobjects : Mobject ) -> None :
418
431
"""If a mobject was fixed in its orientation by passing it through
419
432
:meth:`.add_fixed_orientation_mobjects`, then this undoes that fixing.
420
433
The Mobject will no longer have a fixed orientation.
@@ -428,7 +441,7 @@ def remove_fixed_orientation_mobjects(self, *mobjects: Mobject):
428
441
if mobject in self .fixed_orientation_mobjects :
429
442
del self .fixed_orientation_mobjects [mobject ]
430
443
431
- def remove_fixed_in_frame_mobjects (self , * mobjects : Mobject ):
444
+ def remove_fixed_in_frame_mobjects (self , * mobjects : Mobject ) -> None :
432
445
"""If a mobject was fixed in frame by passing it through
433
446
:meth:`.add_fixed_in_frame_mobjects`, then this undoes that fixing.
434
447
The Mobject will no longer be fixed in frame.
0 commit comments