4
4
5
5
__all__ = ["ValueTracker" , "ComplexValueTracker" ]
6
6
7
+ from typing import TYPE_CHECKING , Any
7
8
8
9
import numpy as np
9
10
10
11
from manim .mobject .mobject import Mobject
11
12
from manim .mobject .opengl .opengl_compatibility import ConvertToOpenGL
12
13
from manim .utils .paths import straight_path
13
14
15
+ if TYPE_CHECKING :
16
+ from typing_extensions import Self
17
+
18
+ from manim .typing import PathFuncType
19
+
14
20
15
21
class ValueTracker (Mobject , metaclass = ConvertToOpenGL ):
16
22
"""A mobject that can be used for tracking (real-valued) parameters.
@@ -69,76 +75,102 @@ def construct(self):
69
75
70
76
"""
71
77
72
- def __init__ (self , value = 0 , ** kwargs ) :
78
+ def __init__ (self , value : float = 0 , ** kwargs : Any ) -> None :
73
79
super ().__init__ (** kwargs )
74
80
self .set (points = np .zeros ((1 , 3 )))
75
81
self .set_value (value )
76
82
77
83
def get_value (self ) -> float :
78
84
"""Get the current value of this ValueTracker."""
79
- return self .points [0 , 0 ]
85
+ value : float = self .points [0 , 0 ]
86
+ return value
80
87
81
- def set_value (self , value : float ):
82
- """Sets a new scalar value to the ValueTracker"""
88
+ def set_value (self , value : float ) -> Self :
89
+ """Sets a new scalar value to the ValueTracker. """
83
90
self .points [0 , 0 ] = value
84
91
return self
85
92
86
- def increment_value (self , d_value : float ):
87
- """Increments (adds) a scalar value to the ValueTracker"""
93
+ def increment_value (self , d_value : float ) -> Self :
94
+ """Increments (adds) a scalar value to the ValueTracker. """
88
95
self .set_value (self .get_value () + d_value )
89
96
return self
90
97
91
- def __bool__ (self ):
92
- """Return whether the value of this value tracker evaluates as true."""
98
+ def __bool__ (self ) -> bool :
99
+ """Return whether the value of this ValueTracker evaluates as true."""
93
100
return bool (self .get_value ())
94
101
95
- def __iadd__ (self , d_value : float ):
96
- """adds ``+=`` syntax to increment the value of the ValueTracker"""
97
- self .increment_value (d_value )
102
+ def __iadd__ (self , d_value : float | Mobject ) -> Self :
103
+ """adds ``+=`` syntax to increment the value of the ValueTracker."""
104
+ if isinstance (d_value , Mobject ):
105
+ raise ValueError (
106
+ "Cannot increment ValueTracker by a Mobject. Please provide a scalar value."
107
+ )
108
+ else :
109
+ self .increment_value (d_value )
98
110
return self
99
111
100
- def __ifloordiv__ (self , d_value : float ):
101
- """Set the value of this value tracker to the floor division of the current value by ``d_value``."""
112
+ def __ifloordiv__ (self , d_value : float ) -> Self :
113
+ """Set the value of this ValueTracker to the floor division of the current value by ``d_value``."""
102
114
self .set_value (self .get_value () // d_value )
103
115
return self
104
116
105
- def __imod__ (self , d_value : float ):
106
- """Set the value of this value tracker to the current value modulo ``d_value``."""
117
+ def __imod__ (self , d_value : float ) -> Self :
118
+ """Set the value of this ValueTracker to the current value modulo ``d_value``."""
107
119
self .set_value (self .get_value () % d_value )
108
120
return self
109
121
110
- def __imul__ (self , d_value : float ):
111
- """Set the value of this value tracker to the product of the current value and ``d_value``."""
122
+ def __imul__ (self , d_value : float ) -> Self :
123
+ """Set the value of this ValueTracker to the product of the current value and ``d_value``."""
112
124
self .set_value (self .get_value () * d_value )
113
125
return self
114
126
115
- def __ipow__ (self , d_value : float ):
116
- """Set the value of this value tracker to the current value raised to the power of ``d_value``."""
127
+ def __ipow__ (self , d_value : float ) -> Self :
128
+ """Set the value of this ValueTracker to the current value raised to the power of ``d_value``."""
117
129
self .set_value (self .get_value () ** d_value )
118
130
return self
119
131
120
- def __isub__ (self , d_value : float ):
121
- """adds ``-=`` syntax to decrement the value of the ValueTracker"""
122
- self .increment_value (- d_value )
132
+ def __sub__ (self , d_value : float | Mobject ) -> Self :
133
+ """Decrements the ValueTracker by ``d_value``."""
134
+ if isinstance (d_value , Mobject ):
135
+ raise ValueError (
136
+ "Cannot decrement ValueTracker by a Mobject. Please provide a scalar value."
137
+ )
138
+ else :
139
+ self .increment_value (- d_value )
123
140
return self
124
141
125
- def __itruediv__ (self , d_value : float ):
126
- """Sets the value of this value tracker to the current value divided by ``d_value``."""
142
+ def __isub__ (self , d_value : float | Mobject ) -> Self :
143
+ """Adds ``-=`` syntax to decrement the value of the ValueTracker."""
144
+ if isinstance (d_value , Mobject ):
145
+ raise ValueError (
146
+ "Cannot decrement ValueTracker by a Mobject. Please provide a scalar value."
147
+ )
148
+ else :
149
+ self .increment_value (- d_value )
150
+ return self
151
+
152
+ def __itruediv__ (self , d_value : float ) -> Self :
153
+ """Sets the value of this ValueTracker to the current value divided by ``d_value``."""
127
154
self .set_value (self .get_value () / d_value )
128
155
return self
129
156
130
- def interpolate (self , mobject1 , mobject2 , alpha , path_func = straight_path ()):
131
- """
132
- Turns self into an interpolation between mobject1
133
- and mobject2.
134
- """
157
+ def interpolate (
158
+ self ,
159
+ mobject1 : Mobject ,
160
+ mobject2 : Mobject ,
161
+ alpha : float ,
162
+ path_func : PathFuncType = straight_path (),
163
+ ) -> Self :
164
+ """Turns ``self`` into an interpolation between ``mobject1`` and ``mobject2``."""
135
165
self .set (points = path_func (mobject1 .points , mobject2 .points , alpha ))
136
166
return self
137
167
138
168
139
169
class ComplexValueTracker (ValueTracker ):
140
170
"""Tracks a complex-valued parameter.
141
171
172
+ The value is internally stored as a points array [a, b, 0]. This can be accessed directly
173
+ to represent the value geometrically, see the usage example.
142
174
When the value is set through :attr:`animate`, the value will take a straight path from the
143
175
source point to the destination point.
144
176
@@ -161,16 +193,12 @@ def construct(self):
161
193
self.play(tracker.animate.set_value(tracker.get_value() / (-2 + 3j)))
162
194
"""
163
195
164
- def get_value (self ):
165
- """Get the current value of this value tracker as a complex number.
166
-
167
- The value is internally stored as a points array [a, b, 0]. This can be accessed directly
168
- to represent the value geometrically, see the usage example.
169
- """
196
+ def get_value (self ) -> complex : # type: ignore [override]
197
+ """Get the current value of this ComplexValueTracker as a complex number."""
170
198
return complex (* self .points [0 , :2 ])
171
199
172
- def set_value (self , z ) :
173
- """Sets a new complex value to the ComplexValueTracker"""
174
- z = complex (z )
200
+ def set_value (self , value : complex | float ) -> Self :
201
+ """Sets a new complex value to the ComplexValueTracker. """
202
+ z = complex (value )
175
203
self .points [0 , :2 ] = (z .real , z .imag )
176
204
return self
0 commit comments