Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed a few bugs in Quaternion #1328

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Changed to implementation of `Mesh.unify_cycles` to use the corresponding function of `compas.topology.orientation`.
* Fixed bug in `compas.topology.orientation.unify_cycles`.
* Fixed bug in `Mesh.thickened`.
* Fixed various bugs in `compas.geometry.Quaternion`.


### Removed

Expand Down
18 changes: 10 additions & 8 deletions src/compas/geometry/quaternion.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def __getitem__(self, key):
return self.y
if key == 3:
return self.z
raise KeyError
raise KeyError(key)

def __setitem__(self, key, value):
if key == 0:
Expand All @@ -170,9 +170,11 @@ def __setitem__(self, key, value):
return
if key == 2:
self.y = value
return
if key == 3:
self.z = value
raise KeyError
return
raise KeyError(key)

def __iter__(self):
return iter(self.wxyz)
Expand Down Expand Up @@ -367,7 +369,7 @@ def unitize(self):
True

"""
qu = quaternion_unitize(self)
qu = quaternion_unitize(list(self))
self.w, self.x, self.y, self.z = qu

def unitized(self):
Expand All @@ -387,7 +389,7 @@ def unitized(self):
True

"""
qu = quaternion_unitize(self)
qu = quaternion_unitize(list(self))
return Quaternion(*qu)

def canonize(self):
Expand All @@ -408,7 +410,7 @@ def canonize(self):
Quaternion(0.500, -0.500, -0.500, -0.500)

"""
qc = quaternion_canonize(self)
qc = quaternion_canonize(list(self))
self.w, self.x, self.y, self.z = qc # type: ignore

def canonized(self):
Expand All @@ -430,7 +432,7 @@ def canonized(self):
Quaternion(0.500, -0.500, -0.500, -0.500)

"""
qc = quaternion_canonize(self)
qc = quaternion_canonize(list(self))
return Quaternion(*qc) # type: ignore

def conjugate(self):
Expand All @@ -448,7 +450,7 @@ def conjugate(self):
Quaternion(1.000, -1.000, -1.000, -1.000)

"""
qc = quaternion_conjugate(self)
qc = quaternion_conjugate(list(self))
self.w, self.x, self.y, self.z = qc

def conjugated(self):
Expand All @@ -469,5 +471,5 @@ def conjugated(self):
Quaternion(1.000, -1.000, -1.000, -1.000)

"""
qc = quaternion_conjugate(self)
qc = quaternion_conjugate(list(self))
return Quaternion(*qc)
78 changes: 73 additions & 5 deletions tests/compas/geometry/test_quaternion.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from compas.geometry import Quaternion
from compas.geometry import close
from compas.geometry import Frame


@pytest.mark.parametrize(
Expand Down Expand Up @@ -63,22 +64,89 @@ def test_quaternion_data():
assert Quaternion.validate_data(other.__data__)


# =============================================================================
# Constructors
# =============================================================================

# =============================================================================
# Properties and Geometry
# =============================================================================


def test_quaternion_properties():
w = 1.0
x = 2.0
y = 3.0
z = 4.0

quaternion = Quaternion(w, x, y, z)

assert quaternion.wxyz == [w, x, y, z]
assert quaternion.xyzw == [x, y, z, w]
assert close(quaternion.norm, 5.4772255)
assert quaternion.is_unit is False

quaternion = Quaternion(0.0, 0.0, 0.0, 1.0)
assert quaternion.norm == 1.0


# =============================================================================
# Accessors
# =============================================================================


def test_quaternion_accessors():
w = 1.0
x = 2.0
y = 3.0
z = 4.0

quaternion = Quaternion(w, x, y, z)

assert quaternion[0] == w
assert quaternion[1] == x
assert quaternion[2] == y
assert quaternion[3] == z

quaternion[0] = 5.0
quaternion[1] = 6.0
quaternion[2] = 7.0
quaternion[3] = 8.0

assert quaternion.w == 5.0
assert quaternion.x == 6.0
assert quaternion.y == 7.0
assert quaternion.z == 8.0


# =============================================================================
# Comparison
# =============================================================================


def test_quaternion_comparison():
quaternion1 = Quaternion(1.0, 2.0, 3.0, 4.0)
quaternion2 = Quaternion(1.0, 2.0, 3.0, 4.0)
quaternion3 = Quaternion(5.0, 6.0, 7.0, 8.0)

assert quaternion1 == quaternion2
assert quaternion1 != quaternion3


# =============================================================================
# Other Methods
# Methods
# =============================================================================


def test_quaternion_other_methods():
quaternion = Quaternion(1.0, 2.0, 3.0, 4.0)

conjugate = quaternion.conjugated()
assert conjugate.w == 1.0
assert conjugate.x == -2.0
assert conjugate.y == -3.0
assert conjugate.z == -4.0

unitized = quaternion.unitized()
assert unitized.is_unit

quaternion = Quaternion.from_frame(Frame.worldZX())
canonized = quaternion.canonized()

assert str(canonized) == str("Quaternion(0.5, -0.5, -0.5, -0.5)")
Loading