This commit is contained in:
Yizuki_Ame 2026-06-20 19:23:16 +00:00 committed by GitHub
commit d08001ebf4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 18 deletions

View file

@ -187,7 +187,7 @@ class TipableVMobject(VMobject, metaclass=ConvertToOpenGL):
angles = cartesian_to_spherical(handle - anchor)
tip.rotate(
angles[1] - PI - tip.tip_angle,
) # Rotates the tip along the azimuthal
) # Rotates the tip by the azimuthal angle
if not hasattr(self, "_init_positioning_axis"):
axis = np.array(
[
@ -199,7 +199,7 @@ class TipableVMobject(VMobject, metaclass=ConvertToOpenGL):
tip.rotate(
-angles[2] + PI / 2,
axis=axis,
) # Rotates the tip along the vertical wrt the axis
) # Rotates the tip by the polar angle about the perpendicular axis
self._init_positioning_axis = axis
tip.shift(anchor - tip.tip_point)

View file

@ -809,21 +809,28 @@ def earclip_triangulation(verts: np.ndarray, ring_ends: list) -> list:
def cartesian_to_spherical(vec: Vector3DLike) -> np.ndarray:
"""Returns an array of numbers corresponding to each
polar coordinate value (distance, phi, theta).
"""Returns spherical coordinates in the order
``[distance, azimuthal_angle, polar_angle]``.
Parameters
----------
vec
A numpy array or a sequence of floats ``[x, y, z]``.
Returns
-------
np.ndarray
A numpy array ``[r, azimuthal_angle, polar_angle]`` where
``azimuthal_angle`` is measured in the xy-plane from the positive
x-axis, and ``polar_angle`` is measured from the positive z-axis.
"""
norm = np.linalg.norm(vec)
if norm == 0:
return np.zeros(3)
r = norm
phi = np.arccos(vec[2] / r)
theta = np.arctan2(vec[1], vec[0])
return np.array([r, theta, phi])
polar_angle = np.arccos(vec[2] / r)
azimuthal_angle = np.arctan2(vec[1], vec[0])
return np.array([r, azimuthal_angle, polar_angle])
def spherical_to_cartesian(spherical: Sequence[float]) -> np.ndarray:
@ -837,16 +844,17 @@ def spherical_to_cartesian(spherical: Sequence[float]) -> np.ndarray:
r - The distance between the point and the origin.
theta - The azimuthal angle of the point to the positive x-axis.
azimuthal_angle - The angle in the xy-plane measured from the
positive x-axis.
phi - The vertical angle of the point to the positive z-axis.
polar_angle - The angle measured from the positive z-axis.
"""
r, theta, phi = spherical
r, azimuthal_angle, polar_angle = spherical
return np.array(
[
r * np.cos(theta) * np.sin(phi),
r * np.sin(theta) * np.sin(phi),
r * np.cos(phi),
r * np.cos(azimuthal_angle) * np.sin(polar_angle),
r * np.sin(azimuthal_angle) * np.sin(polar_angle),
r * np.cos(polar_angle),
],
)

View file

@ -112,13 +112,13 @@ def test_shoelace():
assert shoelace(np.array([[1, 2], [3, 4]])) == 6
def test_polar_coords():
a = np.array([1, 1, 0])
b = (2, np.pi / 2, np.pi / 2)
def test_spherical_coords():
cartesian_point = np.array([1, 1, 0])
spherical_point = (2, np.pi / 2, np.pi / 2)
np.testing.assert_array_equal(
np.round(cartesian_to_spherical(a), 4),
np.round(cartesian_to_spherical(cartesian_point), 4),
np.round([2**0.5, np.pi / 4, np.pi / 2], 4),
)
np.testing.assert_array_equal(
np.round(spherical_to_cartesian(b), 4), np.array([0, 2, 0])
np.round(spherical_to_cartesian(spherical_point), 4), np.array([0, 2, 0])
)