Initial implementation of NumberPlane

This commit is contained in:
Grant Sanderson 2015-10-06 15:27:40 -07:00
parent cc6b541f00
commit aa236ea330

View file

@ -11,7 +11,7 @@ class FunctionGraph(Mobject1D):
"color" : "lightblue", "color" : "lightblue",
"x_min" : -10, "x_min" : -10,
"x_max" : 10, "x_max" : 10,
"spacial_radius" : SPACE_WIDTH, "spatial_radius" : SPACE_WIDTH,
} }
def __init__(self, function, **kwargs): def __init__(self, function, **kwargs):
digest_config(self, FunctionGraph, kwargs, locals()) digest_config(self, FunctionGraph, kwargs, locals())
@ -20,7 +20,7 @@ class FunctionGraph(Mobject1D):
def generate_points(self): def generate_points(self):
numerical_radius = (self.x_max - self.x_min)/2 numerical_radius = (self.x_max - self.x_min)/2
numerical_center = (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 epsilon = self.epsilon * ratio
self.add_points([ self.add_points([
np.array([(x-numerical_center)/ratio, self.function(x), 0]) 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) 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): class NumberLine(Mobject1D):
DEFAULT_CONFIG = { DEFAULT_CONFIG = {
"color" : "skyblue", "color" : "skyblue",
"numerical_radius" : SPACE_WIDTH, "numerical_radius" : SPACE_WIDTH,
"unit_length_to_spacial_width" : 1, "unit_length_to_spatial_width" : 1,
"tick_size" : 0.1, "tick_size" : 0.1,
"tick_frequency" : 0.5, "tick_frequency" : 0.5,
"leftmost_tick" : -int(SPACE_WIDTH), "leftmost_tick" : -int(SPACE_WIDTH),
@ -109,15 +77,15 @@ class NumberLine(Mobject1D):
Mobject1D.__init__(self, **kwargs) Mobject1D.__init__(self, **kwargs)
def generate_points(self): 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([ self.add_points([
(b*x, 0, 0) (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] for b in [-1, 1]
]) ])
self.index_of_left = np.argmin(self.points[:,0]) self.index_of_left = np.argmin(self.points[:,0])
self.index_of_right = np.argmax(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([ self.add_points([
(x, y, 0) (x, y, 0)
for num in self.get_tick_numbers() for num in self.get_tick_numbers()
@ -151,7 +119,7 @@ class NumberLine(Mobject1D):
) )
def point_to_number(self, point): 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): def default_numbers_to_display(self):
return self.get_tick_numbers()[::2] return self.get_tick_numbers()[::2]
@ -175,7 +143,7 @@ class NumberLine(Mobject1D):
num_string = str(number)[:num_decimal_places] num_string = str(number)[:num_decimal_places]
mob = tex_mobject(num_string) mob = tex_mobject(num_string)
vert_scale = 2*self.tick_size/mob.get_height() 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.scale(min(vert_scale, hori_scale))
mob.shift(self.number_to_point(number)) mob.shift(self.number_to_point(number))
mob.shift(self.get_vertical_number_offset()) mob.shift(self.get_vertical_number_offset())
@ -192,7 +160,7 @@ class NumberLine(Mobject1D):
class UnitInterval(NumberLine): class UnitInterval(NumberLine):
DEFAULT_CONFIG = { DEFAULT_CONFIG = {
"numerical_radius" : 0.5, "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, "tick_frequency" : 0.1,
"leftmost_tick" : 0, "leftmost_tick" : 0,
"number_at_center" : 0.5, "number_at_center" : 0.5,
@ -210,7 +178,79 @@ class Axes(CompoundMobject):
CompoundMobject.__init__(self, x_axis, y_axis) 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