mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Refactor`Mobject.put_start_and_end_on() to shift Mobject to start when it's a closed curve (#4658)
* fix: preserve geometry in put_start_and_end_on for zero-vector mobjects * fix: preserve geometry in put_start_and_end_on for zero-vector mobjects * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixed asser_array_equal line * removed commets in mobject.py and opengl_mobject.py as suggested * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * added stacklevel=2 suggestion --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Francisco Manríquez Novoa <49853152+chopan050@users.noreply.github.com>
This commit is contained in:
parent
af70b6fef2
commit
c45724989d
3 changed files with 41 additions and 28 deletions
|
|
@ -1941,30 +1941,33 @@ class Mobject:
|
|||
return self
|
||||
|
||||
def put_start_and_end_on(self, start: Point3DLike, end: Point3DLike) -> Self:
|
||||
curr_start, curr_end = self.get_start_and_end()
|
||||
curr_vect = curr_end - curr_start
|
||||
if np.all(curr_vect == 0):
|
||||
# TODO: this looks broken. It makes self.points a Point3D instead
|
||||
# of a Point3D_Array. However, modifying this breaks some tests
|
||||
# where this is currently expected.
|
||||
self.points = np.array(start)
|
||||
current_start, current_end = self.get_start_and_end()
|
||||
current_vector = current_end - current_start
|
||||
if np.all(current_vector == 0):
|
||||
warnings.warn(
|
||||
"put_start_and_end_on has been called on a closed loop or zero-length mobject. "
|
||||
f"{type(self).__name__} will be shifted to start point instead.",
|
||||
stacklevel=2,
|
||||
)
|
||||
self.shift(np.asarray(start) - current_start)
|
||||
return self
|
||||
target_vect = np.asarray(end) - np.asarray(start)
|
||||
|
||||
target_vector = np.asarray(end) - np.asarray(start)
|
||||
axis = (
|
||||
normalize(np.cross(curr_vect, target_vect))
|
||||
if np.linalg.norm(np.cross(curr_vect, target_vect)) != 0
|
||||
normalize(np.cross(current_vector, target_vector))
|
||||
if np.linalg.norm(np.cross(current_vector, target_vector)) != 0
|
||||
else OUT
|
||||
)
|
||||
self.scale(
|
||||
np.linalg.norm(target_vect) / np.linalg.norm(curr_vect),
|
||||
about_point=curr_start,
|
||||
np.linalg.norm(target_vector) / np.linalg.norm(current_vector),
|
||||
about_point=current_start,
|
||||
)
|
||||
self.rotate(
|
||||
angle_between_vectors(curr_vect, target_vect),
|
||||
about_point=curr_start,
|
||||
angle_between_vectors(current_vector, target_vector),
|
||||
about_point=current_start,
|
||||
axis=axis,
|
||||
)
|
||||
self.shift(start - curr_start)
|
||||
self.shift(np.asarray(start) - current_start)
|
||||
return self
|
||||
|
||||
# Background rectangle
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import itertools as it
|
|||
import random
|
||||
import sys
|
||||
import types
|
||||
import warnings
|
||||
from collections.abc import Callable, Iterable, Iterator, Sequence
|
||||
from functools import partialmethod, wraps
|
||||
from math import ceil
|
||||
|
|
@ -2134,26 +2135,33 @@ class OpenGLMobject:
|
|||
return self
|
||||
|
||||
def put_start_and_end_on(self, start: Point3DLike, end: Point3DLike) -> Self:
|
||||
curr_start, curr_end = self.get_start_and_end()
|
||||
curr_vect = curr_end - curr_start
|
||||
if np.all(curr_vect == 0):
|
||||
raise Exception("Cannot position endpoints of closed loop")
|
||||
target_vect = np.array(end) - np.array(start)
|
||||
current_start, current_end = self.get_start_and_end()
|
||||
current_vector = current_end - current_start
|
||||
if np.all(current_vector == 0):
|
||||
warnings.warn(
|
||||
"put_start_and_end_on has been called on a closed loop or zero-length mobject. "
|
||||
f"{type(self).__name__} will be shifted to start point instead.",
|
||||
stacklevel=2,
|
||||
)
|
||||
self.shift(np.asarray(start) - current_start)
|
||||
return self
|
||||
|
||||
target_vector = np.asarray(end) - np.asarray(start)
|
||||
axis = (
|
||||
normalize(np.cross(curr_vect, target_vect))
|
||||
if np.linalg.norm(np.cross(curr_vect, target_vect)) != 0
|
||||
normalize(np.cross(current_vector, target_vector))
|
||||
if np.linalg.norm(np.cross(current_vector, target_vector)) != 0
|
||||
else OUT
|
||||
)
|
||||
self.scale(
|
||||
float(np.linalg.norm(target_vect) / np.linalg.norm(curr_vect)),
|
||||
about_point=curr_start,
|
||||
np.linalg.norm(target_vector) / np.linalg.norm(current_vector),
|
||||
about_point=current_start,
|
||||
)
|
||||
self.rotate(
|
||||
angle_between_vectors(curr_vect, target_vect),
|
||||
about_point=curr_start,
|
||||
angle_between_vectors(current_vector, target_vector),
|
||||
about_point=current_start,
|
||||
axis=axis,
|
||||
)
|
||||
self.shift(start - curr_start)
|
||||
self.shift(np.asarray(start) - current_start)
|
||||
return self
|
||||
|
||||
# Color functions
|
||||
|
|
|
|||
|
|
@ -129,4 +129,6 @@ def test_start_and_end_at_same_point():
|
|||
line = DashedLine(np.zeros(3), np.zeros(3))
|
||||
line.put_start_and_end_on(np.zeros(3), np.array([0, 0, 0]))
|
||||
|
||||
np.testing.assert_array_equal(np.round(np.zeros(3), 4), np.round(line.points, 4))
|
||||
np.testing.assert_array_equal(
|
||||
np.round(line.points, 4), np.round(np.zeros((4, 3)), 4)
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue