Skip to content

Commit 6b6866e

Browse files
committed
Fix torus mesh parameterization
1 parent 9ee6655 commit 6b6866e

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

tests/test_geometry_smoke.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from __future__ import annotations
22

3+
import math
4+
35
import pytest
46
import torch
57

6-
from witwin.core import Box, Cylinder, Mesh, Sphere
8+
from witwin.core import Box, Cylinder, Mesh, Sphere, Torus
79

810

911
def _grid():
@@ -71,6 +73,26 @@ def test_geometry_construction_to_mesh_and_to_mask(geometry, segments, inside_po
7173
assert torch.any(occupancy < 0.5)
7274

7375

76+
def test_torus_mesh_matches_analytic_extents_and_volume():
77+
major_radius = 0.8
78+
minor_radius = 0.2
79+
torus = Torus(major_radius=major_radius, minor_radius=minor_radius, axis="z")
80+
vertices, faces = torus.to_mesh(segments=48)
81+
82+
expected_extents = torch.tensor(
83+
[major_radius + minor_radius, major_radius + minor_radius, minor_radius],
84+
dtype=vertices.dtype,
85+
)
86+
torch.testing.assert_close(vertices.abs().amax(dim=0), expected_extents, rtol=1e-6, atol=1e-6)
87+
88+
triangles = vertices[faces].to(torch.float64)
89+
signed_volume = torch.sum(
90+
torch.sum(triangles[:, 0] * torch.cross(triangles[:, 1], triangles[:, 2], dim=1), dim=1)
91+
) / 6.0
92+
expected_volume = 2.0 * math.pi**2 * major_radius * minor_radius**2
93+
assert abs(float(signed_volume)) == pytest.approx(expected_volume, rel=1e-2)
94+
95+
7496
def test_mesh_roundtrip_preserves_world_vertices_and_faces():
7597
base = Box(position=(0.25, -0.15, 0.4), size=(0.5, 0.3, 0.7))
7698
vertices, faces = base.to_mesh()

witwin/core/geometry/primitives.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def to_mesh(self, segments=16):
427427
for minor in range(minor_segments):
428428
phi = 2 * np.pi * minor / minor_segments
429429
vertices.append([
430-
np.cos(phi) * np.cos(theta),
430+
np.cos(phi),
431431
np.cos(phi) * np.sin(theta),
432432
np.sin(phi),
433433
np.cos(theta),

0 commit comments

Comments
 (0)