[BREAKING][Ref / Label / Pattern] Make rotate/mirror consistent intrinsic transfomations
offset and repetition are extrinsic; use rotate_around() and flip() to alter both mirror() and rotate() only affect the object's intrinsic properties
This commit is contained in:
parent
db22237369
commit
5f91bd9c6c
6 changed files with 204 additions and 25 deletions
133
masque/test/test_rotation_consistency.py
Normal file
133
masque/test/test_rotation_consistency.py
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
|
||||
from typing import cast
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
from ..pattern import Pattern
|
||||
from ..ref import Ref
|
||||
from ..label import Label
|
||||
from ..repetition import Grid
|
||||
|
||||
def test_ref_rotate_intrinsic() -> None:
|
||||
# Intrinsic rotate() should NOT affect repetition
|
||||
rep = Grid(a_vector=(10, 0), a_count=2)
|
||||
ref = Ref(repetition=rep)
|
||||
|
||||
ref.rotate(np.pi/2)
|
||||
|
||||
assert_allclose(ref.rotation, np.pi/2, atol=1e-10)
|
||||
# Grid vector should still be (10, 0)
|
||||
assert ref.repetition is not None
|
||||
assert_allclose(cast('Grid', ref.repetition).a_vector, [10, 0], atol=1e-10)
|
||||
|
||||
def test_ref_rotate_around_extrinsic() -> None:
|
||||
# Extrinsic rotate_around() SHOULD affect repetition
|
||||
rep = Grid(a_vector=(10, 0), a_count=2)
|
||||
ref = Ref(repetition=rep)
|
||||
|
||||
ref.rotate_around((0, 0), np.pi/2)
|
||||
|
||||
assert_allclose(ref.rotation, np.pi/2, atol=1e-10)
|
||||
# Grid vector should be rotated to (0, 10)
|
||||
assert ref.repetition is not None
|
||||
assert_allclose(cast('Grid', ref.repetition).a_vector, [0, 10], atol=1e-10)
|
||||
|
||||
def test_pattern_rotate_around_extrinsic() -> None:
|
||||
# Pattern.rotate_around() SHOULD affect repetition of its elements
|
||||
rep = Grid(a_vector=(10, 0), a_count=2)
|
||||
ref = Ref(repetition=rep)
|
||||
|
||||
pat = Pattern()
|
||||
pat.refs['cell'].append(ref)
|
||||
|
||||
pat.rotate_around((0, 0), np.pi/2)
|
||||
|
||||
# Check the ref inside the pattern
|
||||
ref_in_pat = pat.refs['cell'][0]
|
||||
assert_allclose(ref_in_pat.rotation, np.pi/2, atol=1e-10)
|
||||
# Grid vector should be rotated to (0, 10)
|
||||
assert ref_in_pat.repetition is not None
|
||||
assert_allclose(cast('Grid', ref_in_pat.repetition).a_vector, [0, 10], atol=1e-10)
|
||||
|
||||
def test_label_rotate_around_extrinsic() -> None:
|
||||
# Extrinsic rotate_around() SHOULD affect repetition of labels
|
||||
rep = Grid(a_vector=(10, 0), a_count=2)
|
||||
lbl = Label("test", repetition=rep, offset=(5, 0))
|
||||
|
||||
lbl.rotate_around((0, 0), np.pi/2)
|
||||
|
||||
# Label offset should be (0, 5)
|
||||
assert_allclose(lbl.offset, [0, 5], atol=1e-10)
|
||||
# Grid vector should be rotated to (0, 10)
|
||||
assert lbl.repetition is not None
|
||||
assert_allclose(cast('Grid', lbl.repetition).a_vector, [0, 10], atol=1e-10)
|
||||
|
||||
def test_pattern_rotate_elements_intrinsic() -> None:
|
||||
# rotate_elements() should NOT affect repetition
|
||||
rep = Grid(a_vector=(10, 0), a_count=2)
|
||||
ref = Ref(repetition=rep)
|
||||
|
||||
pat = Pattern()
|
||||
pat.refs['cell'].append(ref)
|
||||
|
||||
pat.rotate_elements(np.pi/2)
|
||||
|
||||
ref_in_pat = pat.refs['cell'][0]
|
||||
assert_allclose(ref_in_pat.rotation, np.pi/2, atol=1e-10)
|
||||
# Grid vector should still be (10, 0)
|
||||
assert ref_in_pat.repetition is not None
|
||||
assert_allclose(cast('Grid', ref_in_pat.repetition).a_vector, [10, 0], atol=1e-10)
|
||||
|
||||
def test_pattern_rotate_element_centers_extrinsic() -> None:
|
||||
# rotate_element_centers() SHOULD affect repetition and offset
|
||||
rep = Grid(a_vector=(10, 0), a_count=2)
|
||||
ref = Ref(repetition=rep, offset=(5, 0))
|
||||
|
||||
pat = Pattern()
|
||||
pat.refs['cell'].append(ref)
|
||||
|
||||
pat.rotate_element_centers(np.pi/2)
|
||||
|
||||
ref_in_pat = pat.refs['cell'][0]
|
||||
# Offset should be (0, 5)
|
||||
assert_allclose(ref_in_pat.offset, [0, 5], atol=1e-10)
|
||||
# Grid vector should be rotated to (0, 10)
|
||||
assert ref_in_pat.repetition is not None
|
||||
assert_allclose(cast('Grid', ref_in_pat.repetition).a_vector, [0, 10], atol=1e-10)
|
||||
# Ref rotation should NOT be changed
|
||||
assert_allclose(ref_in_pat.rotation, 0, atol=1e-10)
|
||||
|
||||
def test_pattern_mirror_elements_intrinsic() -> None:
|
||||
# mirror_elements() should NOT affect repetition or offset
|
||||
rep = Grid(a_vector=(10, 5), a_count=2)
|
||||
ref = Ref(repetition=rep, offset=(5, 2))
|
||||
|
||||
pat = Pattern()
|
||||
pat.refs['cell'].append(ref)
|
||||
|
||||
pat.mirror_elements(axis=0) # Mirror across x (flip y)
|
||||
|
||||
ref_in_pat = pat.refs['cell'][0]
|
||||
assert ref_in_pat.mirrored is True
|
||||
# Repetition and offset should be unchanged
|
||||
assert ref_in_pat.repetition is not None
|
||||
assert_allclose(cast('Grid', ref_in_pat.repetition).a_vector, [10, 5], atol=1e-10)
|
||||
assert_allclose(ref_in_pat.offset, [5, 2], atol=1e-10)
|
||||
|
||||
def test_pattern_mirror_element_centers_extrinsic() -> None:
|
||||
# mirror_element_centers() SHOULD affect repetition and offset
|
||||
rep = Grid(a_vector=(10, 5), a_count=2)
|
||||
ref = Ref(repetition=rep, offset=(5, 2))
|
||||
|
||||
pat = Pattern()
|
||||
pat.refs['cell'].append(ref)
|
||||
|
||||
pat.mirror_element_centers(axis=0) # Mirror across x (flip y)
|
||||
|
||||
ref_in_pat = pat.refs['cell'][0]
|
||||
# Offset should be (5, -2)
|
||||
assert_allclose(ref_in_pat.offset, [5, -2], atol=1e-10)
|
||||
# Grid vector should be (10, -5)
|
||||
assert ref_in_pat.repetition is not None
|
||||
assert_allclose(cast('Grid', ref_in_pat.repetition).a_vector, [10, -5], atol=1e-10)
|
||||
# Ref mirrored state should NOT be changed
|
||||
assert ref_in_pat.mirrored is False
|
||||
Loading…
Add table
Add a link
Reference in a new issue