mirror of
https://github.com/3b1b/manim.git
synced 2025-09-19 04:41:56 +00:00
Implmented ThreeDScene.add_fixed_orientation_mobjects and ThreeDScene.add_fixed_in_frame_mobjects
This commit is contained in:
parent
0149f4a496
commit
7912f6f2d3
6 changed files with 86 additions and 20 deletions
|
@ -341,7 +341,9 @@ class Camera(object):
|
|||
def set_cairo_context_path(self, ctx, vmobject):
|
||||
ctx.new_path()
|
||||
for vmob in it.chain([vmobject], vmobject.get_subpath_mobjects()):
|
||||
points = self.transform_points_pre_display(vmob.points)
|
||||
points = self.transform_points_pre_display(
|
||||
vmob, vmob.points
|
||||
)
|
||||
ctx.new_sub_path()
|
||||
ctx.move_to(*points[0][:2])
|
||||
for triplet in zip(points[1::3], points[2::3], points[3::3]):
|
||||
|
@ -361,7 +363,9 @@ class Camera(object):
|
|||
)
|
||||
else:
|
||||
points = vmobject.get_gradient_start_and_end_points()
|
||||
points = self.transform_points_pre_display(points)
|
||||
points = self.transform_points_pre_display(
|
||||
vmobject, points
|
||||
)
|
||||
pat = cairo.LinearGradient(*it.chain(*[
|
||||
point[:2] for point in points
|
||||
]))
|
||||
|
@ -420,16 +424,19 @@ class Camera(object):
|
|||
def display_multiple_point_cloud_mobjects(self, pmobjects, pixel_array):
|
||||
for pmobject in pmobjects:
|
||||
self.display_point_cloud(
|
||||
pmobject,
|
||||
pmobject.points,
|
||||
pmobject.rgbas,
|
||||
self.adjusted_thickness(pmobject.stroke_width),
|
||||
pixel_array,
|
||||
)
|
||||
|
||||
def display_point_cloud(self, points, rgbas, thickness, pixel_array):
|
||||
def display_point_cloud(self, pmobject, points, rgbas, thickness, pixel_array):
|
||||
if len(points) == 0:
|
||||
return
|
||||
pixel_coords = self.points_to_pixel_coords(points)
|
||||
pixel_coords = self.points_to_pixel_coords(
|
||||
pmobject, points
|
||||
)
|
||||
pixel_coords = self.thickened_coordinates(
|
||||
pixel_coords, thickness
|
||||
)
|
||||
|
@ -461,7 +468,9 @@ class Camera(object):
|
|||
self.display_image_mobject(image_mobject, pixel_array)
|
||||
|
||||
def display_image_mobject(self, image_mobject, pixel_array):
|
||||
corner_coords = self.points_to_pixel_coords(image_mobject.points)
|
||||
corner_coords = self.points_to_pixel_coords(
|
||||
image_mobject, image_mobject.points
|
||||
)
|
||||
ul_coords, ur_coords, dl_coords = corner_coords
|
||||
right_vect = ur_coords - ul_coords
|
||||
down_vect = dl_coords - ul_coords
|
||||
|
@ -538,13 +547,15 @@ class Camera(object):
|
|||
points[violator_indices] = rescaled
|
||||
return points
|
||||
|
||||
def transform_points_pre_display(self, points):
|
||||
def transform_points_pre_display(self, points, mobject):
|
||||
# Subclasses (like ThreeDCamera) may want to
|
||||
# adjust points before they're shown
|
||||
return points
|
||||
|
||||
def points_to_pixel_coords(self, points):
|
||||
points = self.transform_points_pre_display(points)
|
||||
def points_to_pixel_coords(self, mobject, points):
|
||||
points = self.transform_points_pre_display(
|
||||
mobject, points
|
||||
)
|
||||
shifted_points = points - self.get_frame_center()
|
||||
|
||||
result = np.zeros((len(points), 2))
|
||||
|
|
|
@ -6,7 +6,6 @@ from constants import *
|
|||
|
||||
from camera.camera import Camera
|
||||
from mobject.types.point_cloud_mobject import Point
|
||||
from mobject.three_dimensions import ThreeDVMobject
|
||||
from mobject.three_d_utils import get_3d_vmob_start_corner
|
||||
from mobject.three_d_utils import get_3d_vmob_start_corner_unit_normal
|
||||
from mobject.three_d_utils import get_3d_vmob_end_corner
|
||||
|
@ -14,8 +13,10 @@ from mobject.three_d_utils import get_3d_vmob_end_corner_unit_normal
|
|||
from mobject.value_tracker import ValueTracker
|
||||
|
||||
from utils.color import get_shaded_rgb
|
||||
# from utils.config_ops import digest_config
|
||||
from utils.space_ops import rotation_about_z
|
||||
from utils.space_ops import rotation_matrix
|
||||
from utils.space_ops import center_of_mass
|
||||
|
||||
|
||||
class ThreeDCamera(Camera):
|
||||
|
@ -40,6 +41,8 @@ class ThreeDCamera(Camera):
|
|||
self.gamma_tracker = ValueTracker(self.gamma)
|
||||
self.light_source = Point(self.light_source_start_point)
|
||||
self.frame_center = Point(self.frame_center)
|
||||
self.fixed_orientation_mobjects = set()
|
||||
self.fixed_in_frame_mobjects = set()
|
||||
self.reset_rotation_matrix()
|
||||
|
||||
def capture_mobjects(self, mobjects, **kwargs):
|
||||
|
@ -155,15 +158,50 @@ class ThreeDCamera(Camera):
|
|||
result = np.dot(matrix, result)
|
||||
return result
|
||||
|
||||
def transform_points_pre_display(self, points):
|
||||
fc = self.get_frame_center()
|
||||
def project_points(self, points):
|
||||
frame_center = self.get_frame_center()
|
||||
distance = self.get_distance()
|
||||
points -= fc
|
||||
rot_matrix = self.get_rotation_matrix()
|
||||
|
||||
points -= frame_center
|
||||
points = np.dot(points, rot_matrix.T)
|
||||
zs = points[:, 2]
|
||||
zs[zs >= distance] = distance - 0.001
|
||||
for i in 0, 1:
|
||||
points[:, i] *= distance / (distance - zs)
|
||||
points += fc
|
||||
points += frame_center
|
||||
return points
|
||||
|
||||
def project_point(self, point):
|
||||
return self.project_points(point.reshape((1, 3)))[0, :]
|
||||
|
||||
def transform_points_pre_display(self, mobject, points):
|
||||
fixed_orientation = mobject in self.fixed_orientation_mobjects
|
||||
fixed_in_frame = mobject in self.fixed_in_frame_mobjects
|
||||
|
||||
if fixed_in_frame:
|
||||
return points
|
||||
if fixed_orientation:
|
||||
center = center_of_mass(points)
|
||||
new_center = self.project_point(center)
|
||||
return points + (new_center - center)
|
||||
else:
|
||||
return self.project_points(points)
|
||||
|
||||
def add_fixed_orientation_mobjects(self, *mobjects):
|
||||
for mobject in self.extract_mobject_family_members(mobjects):
|
||||
self.fixed_orientation_mobjects.add(mobject)
|
||||
|
||||
def add_fixed_in_frame_mobjects(self, *mobjects):
|
||||
for mobject in self.extract_mobject_family_members(mobjects):
|
||||
self.fixed_in_frame_mobjects.add(mobject)
|
||||
|
||||
def remove_fixed_orientation_mobjects(self, *mobjects):
|
||||
for mobject in self.extract_mobject_family_members(mobjects):
|
||||
if mobject in self.fixed_orientation_mobjects:
|
||||
self.fixed_orientation_mobjects.remove(mobject)
|
||||
|
||||
def remove_fixed_in_frame_mobjects(self, *mobjects):
|
||||
for mobject in self.extract_mobject_family_members(mobjects):
|
||||
if mobject in self.fixed_in_frame_mobjects:
|
||||
self.fixed_in_frame_mobjects.remove(mobject)
|
||||
|
|
|
@ -705,6 +705,8 @@ class Mobject(Container):
|
|||
def get_critical_point(self, direction):
|
||||
result = np.zeros(self.dim)
|
||||
all_points = self.get_all_points()
|
||||
if len(all_points) == 0:
|
||||
return result
|
||||
for dim in range(self.dim):
|
||||
if direction[dim] <= 0:
|
||||
min_val = min(all_points[:, dim])
|
||||
|
|
|
@ -96,16 +96,18 @@ class NumberLine(VMobject):
|
|||
)
|
||||
|
||||
def point_to_number(self, point):
|
||||
left_point, right_point = self.main_line.get_start_and_end()
|
||||
full_vect = right_point - left_point
|
||||
start_point, end_point = self.main_line.get_start_and_end()
|
||||
full_vect = end_point - start_point
|
||||
unit_vect = normalize(full_vect)
|
||||
|
||||
def distance_from_left(p):
|
||||
return np.dot(p - left_point, full_vect) / get_norm(full_vect)
|
||||
def distance_from_start(p):
|
||||
return np.dot(p - start_point, unit_vect)
|
||||
|
||||
return interpolate(
|
||||
self.x_min, self.x_max,
|
||||
distance_from_left(point) / distance_from_left(right_point)
|
||||
proportion = fdiv(
|
||||
distance_from_start(point),
|
||||
distance_from_start(end_point)
|
||||
)
|
||||
return interpolate(self.x_min, self.x_max, proportion)
|
||||
|
||||
def default_numbers_to_display(self):
|
||||
if self.numbers_to_show is not None:
|
||||
|
|
|
@ -72,3 +72,15 @@ class ThreeDScene(Scene):
|
|||
if any([cm in moving_mobjects for cm in camera_mobjects]):
|
||||
return self.mobjects
|
||||
return moving_mobjects
|
||||
|
||||
def add_fixed_orientation_mobjects(self, *mobjects):
|
||||
self.camera.add_fixed_orientation_mobjects(*mobjects)
|
||||
|
||||
def add_fixed_in_frame_mobjects(self, *mobjects):
|
||||
self.camera.add_fixed_in_frame_mobjects(*mobjects)
|
||||
|
||||
def remove_fixed_orientation_mobjects(self, *mobjects):
|
||||
self.camera.remove_fixed_orientation_mobjects(*mobjects)
|
||||
|
||||
def remove_fixed_in_frame_mobjects(self, *mobjects):
|
||||
self.camera.remove_fixed_in_frame_mobjects(*mobjects)
|
||||
|
|
|
@ -6,6 +6,7 @@ from functools import reduce
|
|||
|
||||
# Matrix operations
|
||||
|
||||
|
||||
def get_norm(vect):
|
||||
return sum([x**2 for x in vect])**0.5
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue