mirror of
https://github.com/3b1b/manim.git
synced 2025-07-28 20:43:56 +08:00
CoordinateSystem updates
This commit is contained in:
@ -5,6 +5,7 @@ from manimlib.constants import *
|
|||||||
from manimlib.mobject.functions import ParametricCurve
|
from manimlib.mobject.functions import ParametricCurve
|
||||||
from manimlib.mobject.geometry import Arrow
|
from manimlib.mobject.geometry import Arrow
|
||||||
from manimlib.mobject.geometry import Line
|
from manimlib.mobject.geometry import Line
|
||||||
|
from manimlib.mobject.geometry import DashedLine
|
||||||
from manimlib.mobject.geometry import Rectangle
|
from manimlib.mobject.geometry import Rectangle
|
||||||
from manimlib.mobject.number_line import NumberLine
|
from manimlib.mobject.number_line import NumberLine
|
||||||
from manimlib.mobject.svg.tex_mobject import Tex
|
from manimlib.mobject.svg.tex_mobject import Tex
|
||||||
@ -24,8 +25,8 @@ class CoordinateSystem():
|
|||||||
"""
|
"""
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"dimension": 2,
|
"dimension": 2,
|
||||||
"x_range": [-8, 8, 1],
|
"x_range": np.array([-8, 8, 1]),
|
||||||
"y_range": [-4, 4, 1],
|
"y_range": np.array([-4, 4, 1]),
|
||||||
"width": None,
|
"width": None,
|
||||||
"height": None,
|
"height": None,
|
||||||
"num_sampled_graph_points_per_tick": 5,
|
"num_sampled_graph_points_per_tick": 5,
|
||||||
@ -88,12 +89,26 @@ class CoordinateSystem():
|
|||||||
)
|
)
|
||||||
return self.axis_labels
|
return self.axis_labels
|
||||||
|
|
||||||
|
def get_line_from_axis_to_point(self, index, point,
|
||||||
|
line_func=DashedLine,
|
||||||
|
color=GREY_A,
|
||||||
|
stroke_width=2):
|
||||||
|
axis = self.get_axis(index)
|
||||||
|
line = line_func(axis.get_projection(point), point)
|
||||||
|
line.set_stroke(color, stroke_width)
|
||||||
|
return line
|
||||||
|
|
||||||
|
def get_v_line(self, point, **kwargs):
|
||||||
|
return self.get_line_from_axis_to_point(0, point, **kwargs)
|
||||||
|
|
||||||
|
def get_h_line(self, point, **kwargs):
|
||||||
|
return self.get_line_from_axis_to_point(1, point, **kwargs)
|
||||||
|
|
||||||
# Useful for graphing
|
# Useful for graphing
|
||||||
def get_graph(self, function, x_range=None, **kwargs):
|
def get_graph(self, function, x_range=None, **kwargs):
|
||||||
t_range = list(self.x_range)
|
t_range = np.array(self.x_range, dtype=float)
|
||||||
if x_range is not None:
|
if x_range is not None:
|
||||||
for i in range(len(x_range)):
|
t_range[:len(x_range)] = x_range
|
||||||
t_range[i] = x_range[i]
|
|
||||||
# For axes, the third coordinate of x_range indicates
|
# For axes, the third coordinate of x_range indicates
|
||||||
# tick frequency. But for functions, it indicates a
|
# tick frequency. But for functions, it indicates a
|
||||||
# sample frequency
|
# sample frequency
|
||||||
@ -134,7 +149,7 @@ class CoordinateSystem():
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def itgp(self, x, graph):
|
def i2gp(self, x, graph):
|
||||||
"""
|
"""
|
||||||
Alias for input_to_graph_point
|
Alias for input_to_graph_point
|
||||||
"""
|
"""
|
||||||
@ -157,7 +172,7 @@ class CoordinateSystem():
|
|||||||
max_y = FRAME_Y_RADIUS - label.get_height()
|
max_y = FRAME_Y_RADIUS - label.get_height()
|
||||||
max_x = FRAME_X_RADIUS - label.get_width()
|
max_x = FRAME_X_RADIUS - label.get_width()
|
||||||
for x0 in np.arange(*self.x_range)[::-1]:
|
for x0 in np.arange(*self.x_range)[::-1]:
|
||||||
pt = self.itgp(x0, graph)
|
pt = self.i2gp(x0, graph)
|
||||||
if abs(pt[0]) < max_x and abs(pt[1]) < max_y:
|
if abs(pt[0]) < max_x and abs(pt[1]) < max_y:
|
||||||
x = x0
|
x = x0
|
||||||
break
|
break
|
||||||
@ -173,18 +188,11 @@ class CoordinateSystem():
|
|||||||
label.shift_onto_screen()
|
label.shift_onto_screen()
|
||||||
return label
|
return label
|
||||||
|
|
||||||
def get_v_line_to_graph(self, x, graph, line_func=Line):
|
def get_v_line_to_graph(self, x, graph, **kwargs):
|
||||||
return line_func(
|
return self.get_v_line(self.i2gp(x, graph), **kwargs)
|
||||||
self.coords_to_point(x, 0),
|
|
||||||
self.input_to_graph_point(x, graph),
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_h_line_to_graph(self, x, graph, line_func=Line):
|
def get_h_line_to_graph(self, x, graph, **kwargs):
|
||||||
y = self.get_y_axis().p2n(self.itgp(x, graph))
|
return self.get_h_line(self.i2gp(x, graph), **kwargs)
|
||||||
return line_func(
|
|
||||||
self.coords_to_point(0, y),
|
|
||||||
self.input_to_graph_point(x, graph),
|
|
||||||
)
|
|
||||||
|
|
||||||
# For calculus
|
# For calculus
|
||||||
def angle_of_tangent(self, x, graph, dx=EPSILON):
|
def angle_of_tangent(self, x, graph, dx=EPSILON):
|
||||||
@ -231,7 +239,7 @@ class CoordinateSystem():
|
|||||||
else:
|
else:
|
||||||
raise Exception("Invalid input sample type")
|
raise Exception("Invalid input sample type")
|
||||||
height = get_norm(
|
height = get_norm(
|
||||||
self.itgp(sample, graph) - self.c2p(sample, 0)
|
self.i2gp(sample, graph) - self.c2p(sample, 0)
|
||||||
)
|
)
|
||||||
rect = Rectangle(width=x1 - x0, height=height)
|
rect = Rectangle(width=x1 - x0, height=height)
|
||||||
rect.move_to(self.c2p(x0, 0), DL)
|
rect.move_to(self.c2p(x0, 0), DL)
|
||||||
@ -254,21 +262,25 @@ class Axes(VGroup, CoordinateSystem):
|
|||||||
CONFIG = {
|
CONFIG = {
|
||||||
"axis_config": {
|
"axis_config": {
|
||||||
"include_tip": True,
|
"include_tip": True,
|
||||||
|
"numbers_to_exclude": [0],
|
||||||
},
|
},
|
||||||
"x_axis_config": {},
|
"x_axis_config": {},
|
||||||
"y_axis_config": {
|
"y_axis_config": {
|
||||||
"line_to_number_direction": LEFT,
|
"line_to_number_direction": LEFT,
|
||||||
},
|
},
|
||||||
|
"height": FRAME_HEIGHT - 2,
|
||||||
|
"width": FRAME_WIDTH - 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, x_range=None, y_range=None, **kwargs):
|
def __init__(self,
|
||||||
VGroup.__init__(self, **kwargs)
|
x_range=None,
|
||||||
|
y_range=None,
|
||||||
|
**kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
if x_range is not None:
|
if x_range is not None:
|
||||||
for i in range(len(x_range)):
|
self.x_range[:len(x_range)] = x_range
|
||||||
self.x_range[i] = x_range[i]
|
|
||||||
if y_range is not None:
|
if y_range is not None:
|
||||||
for i in range(len(y_range)):
|
self.y_range[:len(x_range)] = y_range
|
||||||
self.y_range[i] = y_range[i]
|
|
||||||
|
|
||||||
self.x_axis = self.create_axis(
|
self.x_axis = self.create_axis(
|
||||||
self.x_range, self.x_axis_config, self.width,
|
self.x_range, self.x_axis_config, self.width,
|
||||||
@ -310,24 +322,21 @@ class Axes(VGroup, CoordinateSystem):
|
|||||||
def add_coordinate_labels(self,
|
def add_coordinate_labels(self,
|
||||||
x_values=None,
|
x_values=None,
|
||||||
y_values=None,
|
y_values=None,
|
||||||
excluding=[0],
|
|
||||||
**kwargs):
|
**kwargs):
|
||||||
axes = self.get_axes()
|
axes = self.get_axes()
|
||||||
self.coordinate_labels = VGroup()
|
self.coordinate_labels = VGroup()
|
||||||
for axis, values in zip(axes, [x_values, y_values]):
|
for axis, values in zip(axes, [x_values, y_values]):
|
||||||
numbers = axis.add_numbers(
|
labels = axis.add_numbers(values, **kwargs)
|
||||||
values, excluding=excluding, **kwargs
|
self.coordinate_labels.add(labels)
|
||||||
)
|
|
||||||
self.coordinate_labels.add(numbers)
|
|
||||||
return self.coordinate_labels
|
return self.coordinate_labels
|
||||||
|
|
||||||
|
|
||||||
class ThreeDAxes(Axes):
|
class ThreeDAxes(Axes):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"dimension": 3,
|
"dimension": 3,
|
||||||
"x_range": (-6, 6, 1),
|
"x_range": np.array([-6, 6, 1]),
|
||||||
"y_range": (-5, 5, 1),
|
"y_range": np.array([-5, 5, 1]),
|
||||||
"z_range": (-4, 4, 1),
|
"z_range": np.array([-4, 4, 1]),
|
||||||
"z_axis_config": {},
|
"z_axis_config": {},
|
||||||
"z_normal": DOWN,
|
"z_normal": DOWN,
|
||||||
"depth": None,
|
"depth": None,
|
||||||
@ -375,6 +384,8 @@ class NumberPlane(Axes):
|
|||||||
"stroke_width": 2,
|
"stroke_width": 2,
|
||||||
"stroke_opacity": 1,
|
"stroke_opacity": 1,
|
||||||
},
|
},
|
||||||
|
"height": None,
|
||||||
|
"width": None,
|
||||||
# Defaults to a faded version of line_config
|
# Defaults to a faded version of line_config
|
||||||
"faded_line_style": None,
|
"faded_line_style": None,
|
||||||
"faded_line_ratio": 1,
|
"faded_line_ratio": 1,
|
||||||
|
Reference in New Issue
Block a user