mirror of
https://github.com/3b1b/manim.git
synced 2025-11-14 04:47:47 +00:00
Initial implementation of NumberPlane
This commit is contained in:
parent
cc6b541f00
commit
aa236ea330
1 changed files with 82 additions and 42 deletions
|
|
@ -11,7 +11,7 @@ class FunctionGraph(Mobject1D):
|
|||
"color" : "lightblue",
|
||||
"x_min" : -10,
|
||||
"x_max" : 10,
|
||||
"spacial_radius" : SPACE_WIDTH,
|
||||
"spatial_radius" : SPACE_WIDTH,
|
||||
}
|
||||
def __init__(self, function, **kwargs):
|
||||
digest_config(self, FunctionGraph, kwargs, locals())
|
||||
|
|
@ -20,7 +20,7 @@ class FunctionGraph(Mobject1D):
|
|||
def generate_points(self):
|
||||
numerical_radius = (self.x_max - self.x_min)/2
|
||||
numerical_center = (self.x_max + self.x_min)/2
|
||||
ratio = numerical_radius / self.spacial_radius
|
||||
ratio = numerical_radius / self.spatial_radius
|
||||
epsilon = self.epsilon * ratio
|
||||
self.add_points([
|
||||
np.array([(x-numerical_center)/ratio, self.function(x), 0])
|
||||
|
|
@ -58,43 +58,11 @@ class ParametricFunction(Mobject):
|
|||
for s in np.arange(-1, 1, self.epsilon)
|
||||
])
|
||||
|
||||
class Grid(Mobject1D):
|
||||
DEFAULT_CONFIG = {
|
||||
"color" : "green",
|
||||
"radius" : max(SPACE_HEIGHT, SPACE_WIDTH),
|
||||
"interval_size" : 1.0,
|
||||
"subinterval_size" : 0.5,
|
||||
}
|
||||
def __init__(self, **kwargs):
|
||||
digest_config(self, Grid, kwargs)
|
||||
Mobject1D.__init__(self, **kwargs)
|
||||
|
||||
def generate_points(self):
|
||||
self.add_points([
|
||||
(sgns[0] * x, sgns[1] * y, 0)
|
||||
for beta in np.arange(0, self.radius, self.interval_size)
|
||||
for alpha in np.arange(0, self.radius, self.epsilon)
|
||||
for sgns in it.product((-1, 1), (-1, 1))
|
||||
for x, y in [(alpha, beta), (beta, alpha)]
|
||||
])
|
||||
if self.subinterval_size:
|
||||
si = self.subinterval_size
|
||||
color = Color(self.color)
|
||||
color.set_rgb([x/2 for x in color.get_rgb()])
|
||||
self.add_points([
|
||||
(sgns[0] * x, sgns[1] * y, 0)
|
||||
for beta in np.arange(0, self.radius, si)
|
||||
if abs(beta % self.interval_size) > self.epsilon
|
||||
for alpha in np.arange(0, self.radius, self.epsilon)
|
||||
for sgns in it.product((-1, 1), (-1, 1))
|
||||
for x, y in [(alpha, beta), (beta, alpha)]
|
||||
], color = color)
|
||||
|
||||
class NumberLine(Mobject1D):
|
||||
DEFAULT_CONFIG = {
|
||||
"color" : "skyblue",
|
||||
"numerical_radius" : SPACE_WIDTH,
|
||||
"unit_length_to_spacial_width" : 1,
|
||||
"unit_length_to_spatial_width" : 1,
|
||||
"tick_size" : 0.1,
|
||||
"tick_frequency" : 0.5,
|
||||
"leftmost_tick" : -int(SPACE_WIDTH),
|
||||
|
|
@ -109,15 +77,15 @@ class NumberLine(Mobject1D):
|
|||
Mobject1D.__init__(self, **kwargs)
|
||||
|
||||
def generate_points(self):
|
||||
spacial_radius = self.numerical_radius*self.unit_length_to_spacial_width
|
||||
spatial_radius = self.numerical_radius*self.unit_length_to_spatial_width
|
||||
self.add_points([
|
||||
(b*x, 0, 0)
|
||||
for x in np.arange(0, spacial_radius, self.epsilon)
|
||||
for x in np.arange(0, spatial_radius, self.epsilon)
|
||||
for b in [-1, 1]
|
||||
])
|
||||
self.index_of_left = np.argmin(self.points[:,0])
|
||||
self.index_of_right = np.argmax(self.points[:,0])
|
||||
spacial_tick_frequency = self.tick_frequency*self.unit_length_to_spacial_width
|
||||
spatial_tick_frequency = self.tick_frequency*self.unit_length_to_spatial_width
|
||||
self.add_points([
|
||||
(x, y, 0)
|
||||
for num in self.get_tick_numbers()
|
||||
|
|
@ -151,7 +119,7 @@ class NumberLine(Mobject1D):
|
|||
)
|
||||
|
||||
def point_to_number(self, point):
|
||||
return self.number_at_center + point[0]/self.unit_length_to_spacial_width
|
||||
return self.number_at_center + point[0]/self.unit_length_to_spatial_width
|
||||
|
||||
def default_numbers_to_display(self):
|
||||
return self.get_tick_numbers()[::2]
|
||||
|
|
@ -175,7 +143,7 @@ class NumberLine(Mobject1D):
|
|||
num_string = str(number)[:num_decimal_places]
|
||||
mob = tex_mobject(num_string)
|
||||
vert_scale = 2*self.tick_size/mob.get_height()
|
||||
hori_scale = self.tick_frequency*self.unit_length_to_spacial_width/mob.get_width()
|
||||
hori_scale = self.tick_frequency*self.unit_length_to_spatial_width/mob.get_width()
|
||||
mob.scale(min(vert_scale, hori_scale))
|
||||
mob.shift(self.number_to_point(number))
|
||||
mob.shift(self.get_vertical_number_offset())
|
||||
|
|
@ -192,7 +160,7 @@ class NumberLine(Mobject1D):
|
|||
class UnitInterval(NumberLine):
|
||||
DEFAULT_CONFIG = {
|
||||
"numerical_radius" : 0.5,
|
||||
"unit_length_to_spacial_width" : 2*(SPACE_WIDTH-1),
|
||||
"unit_length_to_spatial_width" : 2*(SPACE_WIDTH-1),
|
||||
"tick_frequency" : 0.1,
|
||||
"leftmost_tick" : 0,
|
||||
"number_at_center" : 0.5,
|
||||
|
|
@ -210,7 +178,79 @@ class Axes(CompoundMobject):
|
|||
CompoundMobject.__init__(self, x_axis, y_axis)
|
||||
|
||||
|
||||
|
||||
class NumberPlane(Mobject1D):
|
||||
DEFAULT_CONFIG = {
|
||||
"color" : "skyblue",
|
||||
"x_radius" : SPACE_WIDTH,
|
||||
"y_radius" : SPACE_HEIGHT,
|
||||
"x_unit_to_spatial_width" : 1,
|
||||
"y_uint_to_spatial_height" : 1,
|
||||
"x_line_frequency" : 1,
|
||||
"x_faded_line_frequency" : 0.5,
|
||||
"y_line_frequency" : 1,
|
||||
"y_faded_line_frequency" : 0.5,
|
||||
"fade_factor" : 0.3,
|
||||
"number_scale_factor" : 0.25,
|
||||
"num_pair_at_center" : np.array((0, 0)),
|
||||
}
|
||||
def __init__(self, **kwargs):
|
||||
digest_config(self, NumberPlane, kwargs)
|
||||
Mobject1D.__init__(self, **kwargs)
|
||||
|
||||
def generate_points(self):
|
||||
color = self.color
|
||||
faded = Color(rgb = self.fade_factor*np.array(color.get_rgb()))
|
||||
colors = iter([faded, color])
|
||||
for freq in self.x_faded_line_frequency, self.x_line_frequency:
|
||||
self.add_points([
|
||||
(sgns[0]*self.x_unit_to_spatial_width*x, sgns[1]*y, 0)
|
||||
for x in np.arange(0, self.x_radius, freq)
|
||||
for y in np.arange(0, self.y_radius, self.epsilon)
|
||||
for sgns in it.product([-1, 1], [-1, 1])
|
||||
], color = colors.next())
|
||||
#Horizontal lines
|
||||
colors = iter([faded, color])
|
||||
for freq in self.y_faded_line_frequency, self.y_line_frequency:
|
||||
self.add_points([
|
||||
(sgns[0]*x, sgns[1]*self.y_uint_to_spatial_height*y, 0)
|
||||
for x in np.arange(0, self.x_radius, self.epsilon)
|
||||
for y in np.arange(0, self.y_radius, freq)
|
||||
for sgns in it.product([-1, 1], [-1, 1])
|
||||
], color = colors.next())
|
||||
self.shift(self.get_center_point())
|
||||
|
||||
def get_center_point(self):
|
||||
return self.num_pair_to_point(self.num_pair_at_center)
|
||||
|
||||
def num_pair_to_point(self, pair):
|
||||
pair = pair + self.num_pair_at_center
|
||||
return pair[0]*self.x_unit_to_spatial_width*RIGHT + \
|
||||
pair[1]*self.y_uint_to_spatial_height*UP
|
||||
|
||||
def get_coordinate_labels(self, x_vals = None, y_vals = None):
|
||||
result = []
|
||||
nudge = 0.1*(DOWN+RIGHT)
|
||||
if x_vals == None and y_vals == None:
|
||||
x_vals = range(-int(self.x_radius), int(self.x_radius))
|
||||
y_vals = range(-int(self.y_radius), int(self.y_radius))
|
||||
for index, vals in zip([0, 1], [x_vals, y_vals]):
|
||||
num_pair = [0, 0]
|
||||
for val in vals:
|
||||
num_pair[index] = val
|
||||
point = self.num_pair_to_point(num_pair)
|
||||
num = tex_mobject(str(val))
|
||||
num.scale(self.number_scale_factor)
|
||||
num.shift(point-num.get_corner(UP+LEFT)+nudge)
|
||||
result.append(num)
|
||||
return result
|
||||
|
||||
def add_coordinates(self, x_vals = None, y_vals = None):
|
||||
self.add(*self.get_coordinate_labels(x_vals, y_vals))
|
||||
return self
|
||||
|
||||
class ComplexPlane(NumberPlane):
|
||||
#TODO
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue