Skip to content

Commit

Permalink
Fixed Arrow3D.put_start_and_end_on() to use the actual end of the a…
Browse files Browse the repository at this point in the history
…rrow (#3706)

* my test is not passing, i need to add a little bit of docs. except that everything is fine. Issue is solved!

* fixed the issue #3655

* removed comments

* fix: 3706 original issue, without adding unnecessary dot
added: i added self.height parameter in Cone class
my tests passes

* Changes that way how end point of Arrow3D is calculated.

* I've improved the methods get_start and get_end for the Cone class, and get_end for the Arrow3D class to ensure they return accurate geometrical points after transformations. Additionally, I've included unit tests to verify the correctness of these methods for the Cone class.

* Finished! Replaced VMobject by VectorizedPoint as Ben suggested while ago

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Francisco Manríquez Novoa <[email protected]>
  • Loading branch information
3 people authored Jun 26, 2024
1 parent 93a20cd commit 0d21a7e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
46 changes: 34 additions & 12 deletions manim/mobject/three_d/three_dimensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from manim.mobject.mobject import *
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
from manim.mobject.types.vectorized_mobject import VectorizedPoint, VGroup, VMobject
from manim.utils.color import (
ManimColor,
ParsableManimColor,
Expand Down Expand Up @@ -616,17 +616,18 @@ def __init__(
**kwargs,
)
# used for rotations
self.new_height = height
self._current_theta = 0
self._current_phi = 0

self.base_circle = Circle(
radius=base_radius,
color=self.fill_color,
fill_opacity=self.fill_opacity,
stroke_width=0,
)
self.base_circle.shift(height * IN)
self._set_start_and_end_attributes(direction)
if show_base:
self.base_circle = Circle(
radius=base_radius,
color=self.fill_color,
fill_opacity=self.fill_opacity,
stroke_width=0,
)
self.base_circle.shift(height * IN)
self.add(self.base_circle)

self._rotate_to_direction()
Expand Down Expand Up @@ -656,6 +657,12 @@ def func(self, u: float, v: float) -> np.ndarray:
],
)

def get_start(self) -> np.ndarray:
return self.start_point.get_center()

def get_end(self) -> np.ndarray:
return self.end_point.get_center()

def _rotate_to_direction(self) -> None:
x, y, z = self.direction

Expand Down Expand Up @@ -710,6 +717,15 @@ def get_direction(self) -> np.ndarray:
"""
return self.direction

def _set_start_and_end_attributes(self, direction):
normalized_direction = direction * np.linalg.norm(direction)

start = self.base_circle.get_center()
end = start + normalized_direction * self.new_height
self.start_point = VectorizedPoint(start)
self.end_point = VectorizedPoint(end)
self.add(self.start_point, self.end_point)


class Cylinder(Surface):
"""A cylinder, defined by its height, radius and direction,
Expand Down Expand Up @@ -1150,14 +1166,20 @@ def __init__(
self.end - height * self.direction,
**kwargs,
)

self.cone = Cone(
direction=self.direction, base_radius=base_radius, height=height, **kwargs
direction=self.direction,
base_radius=base_radius,
height=height,
**kwargs,
)
self.cone.shift(end)
self.add(self.cone)
self.end_point = VectorizedPoint(end)
self.add(self.end_point, self.cone)
self.set_color(color)

def get_end(self) -> np.ndarray:
return self.end_point.get_center()


class Torus(Surface):
"""A torus.
Expand Down
23 changes: 23 additions & 0 deletions tests/test_graphical_units/test_threed.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ def test_Cone(scene):
scene.add(Cone(resolution=16))


def test_Cone_get_start_and_get_end():
cone = Cone().shift(RIGHT).rotate(PI / 4, about_point=ORIGIN, about_edge=OUT)
start = [0.70710678, 0.70710678, -1.0]
end = [0.70710678, 0.70710678, 0.0]
assert np.allclose(
cone.get_start(), start, atol=0.01
), "start points of Cone do not match"
assert np.allclose(
cone.get_end(), end, atol=0.01
), "end points of Cone do not match"


@frames_comparison(base_scene=ThreeDScene)
def test_Cylinder(scene):
scene.add(Cylinder())
Expand Down Expand Up @@ -149,3 +161,14 @@ def param_surface(u, v):
axes=axes, colorscale=[(RED, -0.4), (YELLOW, 0), (GREEN, 0.4)], axis=1
)
scene.add(axes, surface_plane)


def test_get_start_and_end_Arrow3d():
start, end = ORIGIN, np.array([2, 1, 0])
arrow = Arrow3D(start, end)
assert np.allclose(
arrow.get_start(), start, atol=0.01
), "start points of Arrow3D do not match"
assert np.allclose(
arrow.get_end(), end, atol=0.01
), "end points of Arrow3D do not match"

0 comments on commit 0d21a7e

Please sign in to comment.