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