mirror of
https://github.com/gumyr/build123d.git
synced 2026-03-07 14:22:03 -08:00
Fix Issue #586 translate/rotate
Some checks are pending
benchmarks / benchmarks (macos-14, 3.12) (push) Waiting to run
benchmarks / benchmarks (macos-15-intel, 3.12) (push) Waiting to run
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Waiting to run
benchmarks / benchmarks (windows-latest, 3.12) (push) Waiting to run
Upload coverage reports to Codecov / run (push) Waiting to run
pylint / lint (3.10) (push) Waiting to run
Wheel building and publishing / Build wheel on ubuntu-latest (push) Waiting to run
Wheel building and publishing / upload_pypi (push) Blocked by required conditions
tests / tests (macos-14, 3.10) (push) Waiting to run
tests / tests (macos-14, 3.14) (push) Waiting to run
tests / tests (macos-15-intel, 3.10) (push) Waiting to run
tests / tests (macos-15-intel, 3.14) (push) Waiting to run
tests / tests (ubuntu-latest, 3.10) (push) Waiting to run
tests / tests (ubuntu-latest, 3.14) (push) Waiting to run
tests / tests (windows-latest, 3.10) (push) Waiting to run
tests / tests (windows-latest, 3.14) (push) Waiting to run
Run type checking / typecheck (3.10) (push) Waiting to run
Run type checking / typecheck (3.14) (push) Waiting to run
Some checks are pending
benchmarks / benchmarks (macos-14, 3.12) (push) Waiting to run
benchmarks / benchmarks (macos-15-intel, 3.12) (push) Waiting to run
benchmarks / benchmarks (ubuntu-latest, 3.12) (push) Waiting to run
benchmarks / benchmarks (windows-latest, 3.12) (push) Waiting to run
Upload coverage reports to Codecov / run (push) Waiting to run
pylint / lint (3.10) (push) Waiting to run
Wheel building and publishing / Build wheel on ubuntu-latest (push) Waiting to run
Wheel building and publishing / upload_pypi (push) Blocked by required conditions
tests / tests (macos-14, 3.10) (push) Waiting to run
tests / tests (macos-14, 3.14) (push) Waiting to run
tests / tests (macos-15-intel, 3.10) (push) Waiting to run
tests / tests (macos-15-intel, 3.14) (push) Waiting to run
tests / tests (ubuntu-latest, 3.10) (push) Waiting to run
tests / tests (ubuntu-latest, 3.14) (push) Waiting to run
tests / tests (windows-latest, 3.10) (push) Waiting to run
tests / tests (windows-latest, 3.14) (push) Waiting to run
Run type checking / typecheck (3.10) (push) Waiting to run
Run type checking / typecheck (3.14) (push) Waiting to run
This commit is contained in:
parent
ce0d99a4d1
commit
992de4074b
3 changed files with 61 additions and 10 deletions
|
|
@ -113,15 +113,15 @@ Transformation a.k.a. Translation and Rotation
|
|||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. note::
|
||||
These methods don't work in the same way as the previous methods in that they don't just change
|
||||
the object's internal :class:`~geometry.Location` but transform the base object itself which
|
||||
is quite slow and potentially problematic.
|
||||
These methods have an optional ``transform`` parameter which allows the user to transform the base
|
||||
object itself which is quite slow and potentially problematic as opposed to just changing the
|
||||
object's internal :class:`~geometry.Location`.
|
||||
|
||||
- **Translation:** Move a shape relative to its current position.
|
||||
|
||||
.. code-block:: build123d
|
||||
|
||||
relocated_shape = shape.translate(x, y, z)
|
||||
relocated_shape = shape.translate((x, y, z))
|
||||
|
||||
- **Rotation:** Rotate a shape around a specified axis by a given angle.
|
||||
|
||||
|
|
|
|||
|
|
@ -1711,7 +1711,7 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
|||
self.wrapped = tcast(TOPODS, downcast(builder.Shape()))
|
||||
self.wrapped.Location(loc.wrapped)
|
||||
|
||||
def rotate(self, axis: Axis, angle: float) -> Self:
|
||||
def rotate(self, axis: Axis, angle: float, transform: bool = False) -> Self:
|
||||
"""rotate a copy
|
||||
|
||||
Rotates a shape around an axis.
|
||||
|
|
@ -1719,14 +1719,23 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
|||
Args:
|
||||
axis (Axis): rotation Axis
|
||||
angle (float): angle to rotate, in degrees
|
||||
transform (bool): regenerate the shape instead of just changing its location.
|
||||
Defaults to False.
|
||||
|
||||
Returns:
|
||||
a copy of the shape, rotated
|
||||
"""
|
||||
if self._wrapped is None: # For backwards compatibility
|
||||
return self
|
||||
|
||||
transformation = gp_Trsf()
|
||||
transformation.SetRotation(axis.wrapped, angle * DEG2RAD)
|
||||
|
||||
return self._apply_transform(transformation)
|
||||
if transform:
|
||||
rotated_self = self._apply_transform(transformation)
|
||||
else:
|
||||
rotated_self = self.moved(Location(TopLoc_Location(transformation)))
|
||||
return rotated_self
|
||||
|
||||
def scale(self, factor: float) -> Self:
|
||||
"""Scales this shape through a transformation.
|
||||
|
|
@ -2239,20 +2248,28 @@ class Shape(NodeMixin, Generic[TOPODS]):
|
|||
t_o.SetTranslation(Vector(offset).wrapped)
|
||||
return self._apply_transform(t_o * t_rx * t_ry * t_rz)
|
||||
|
||||
def translate(self, vector: VectorLike) -> Self:
|
||||
def translate(self, vector: VectorLike, transform: bool = False) -> Self:
|
||||
"""Translates this shape through a transformation.
|
||||
|
||||
Args:
|
||||
vector: VectorLike:
|
||||
vector (VectorLike): relative movement vector
|
||||
transform (bool): regenerate the shape instead of just changing its location
|
||||
Defaults to False.
|
||||
|
||||
Returns:
|
||||
|
||||
object with a relative move applied
|
||||
"""
|
||||
if self._wrapped is None: # For backwards compatibility
|
||||
return self
|
||||
|
||||
transformation = gp_Trsf()
|
||||
transformation.SetTranslation(Vector(vector).wrapped)
|
||||
|
||||
return self._apply_transform(transformation)
|
||||
if transform:
|
||||
self_translated = self._apply_transform(transformation)
|
||||
else:
|
||||
self_translated = self.moved(Location(TopLoc_Location(transformation)))
|
||||
return self_translated
|
||||
|
||||
def wire(self) -> Wire | None:
|
||||
"""Return the Wire"""
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ license:
|
|||
|
||||
# Always equal to any other object, to test that __eq__ cooperation is working
|
||||
import unittest
|
||||
import math
|
||||
from random import uniform
|
||||
from unittest.mock import PropertyMock, patch
|
||||
|
||||
|
|
@ -634,6 +635,39 @@ class TestShape(unittest.TestCase):
|
|||
self.assertIsNone(Vertex(1, 1, 1).solid())
|
||||
self.assertIsNone(Vertex(1, 1, 1).compound())
|
||||
|
||||
def test_rotate(self):
|
||||
line = Edge.make_line((0, 0), (1, 0))
|
||||
rotated_line = line.rotate(Axis((1, 0, 0), (0, 0, 1)), 45)
|
||||
root_2o2 = math.sqrt(2) / 2
|
||||
self.assertAlmostEqual(rotated_line @ 0, (1 - root_2o2, -root_2o2))
|
||||
self.assertAlmostEqual(rotated_line @ 1, (1, 0))
|
||||
self.assertTrue(line.wrapped.IsPartner(rotated_line.wrapped))
|
||||
|
||||
rotated_line = line.rotate(Axis((1, 0, 0), (0, 0, 1)), 45, transform=True)
|
||||
self.assertAlmostEqual(rotated_line @ 0, (1 - root_2o2, -root_2o2))
|
||||
self.assertAlmostEqual(rotated_line @ 1, (1, 0))
|
||||
self.assertFalse(line.wrapped.IsPartner(rotated_line.wrapped))
|
||||
|
||||
line._wrapped = None
|
||||
rotated_line = line.rotate(Axis((1, 0, 0), (0, 0, 1)), 45)
|
||||
self.assertIsNone(rotated_line._wrapped)
|
||||
|
||||
def test_translate(self):
|
||||
line = Edge.make_line((0, 0), (1, 0))
|
||||
translated_line = line.translate((0, 1, 0))
|
||||
self.assertAlmostEqual(translated_line @ 0, (0, 1, 0))
|
||||
self.assertAlmostEqual(translated_line @ 1, (1, 1, 0))
|
||||
self.assertTrue(line.wrapped.IsPartner(translated_line.wrapped))
|
||||
|
||||
translated_line = line.translate((0, 1, 0), transform=True)
|
||||
self.assertAlmostEqual(translated_line @ 0, (0, 1, 0))
|
||||
self.assertAlmostEqual(translated_line @ 1, (1, 1, 0))
|
||||
self.assertFalse(line.wrapped.IsPartner(translated_line.wrapped))
|
||||
|
||||
line._wrapped = None
|
||||
translated_line = line.translate((0, 1, 0))
|
||||
self.assertIsNone(translated_line._wrapped)
|
||||
|
||||
|
||||
class TestGlobalLocation(unittest.TestCase):
|
||||
def test_global_location_hierarchy(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue