@@ -104,18 +104,22 @@ def __init__(self, real: float = 0.0, i_component: float = 0.0,
104
104
# Make all the components read-only attributes.
105
105
@property
106
106
def real (self ) -> float :
107
+ """The real component of the Quaternion."""
107
108
return self ._real
108
109
109
110
@property
110
111
def i (self ) -> float :
112
+ """The i component of the Quaternion."""
111
113
return self ._i
112
114
113
115
@property
114
116
def j (self ) -> float :
117
+ """The j component of the Quaternion."""
115
118
return self ._j
116
119
117
120
@property
118
121
def k (self ) -> float :
122
+ """The k component of the Quaternion."""
119
123
return self ._k
120
124
121
125
### Magic methods. ###
@@ -127,7 +131,7 @@ def __complex__(self) -> complex:
127
131
"""
128
132
Return complex(self).
129
133
130
- If only one of the vector components is nonzero, this returns the
134
+ If only one of the vector components is nonzero, return the
131
135
quaternion as a complex number.
132
136
"""
133
137
if self .is_complex ():
@@ -139,18 +143,18 @@ def __complex__(self) -> complex:
139
143
real , imag = self .real , 0.0
140
144
return complex (real , imag )
141
145
142
- return NotImplemented
146
+ raise ValueError ( f" { self . __class__ . __qualname__ } is not scalar or complex." )
143
147
144
148
def __float__ (self ) -> float :
145
149
"""
146
150
Return float(self).
147
151
148
- If the quaternion is scalar, returns the scalar component.
152
+ If the quaternion is scalar, return the scalar component.
149
153
"""
150
154
if self .is_scalar ():
151
155
return self .real
152
156
153
- return NotImplemented
157
+ raise ValueError ( f" { self . __class__ . __qualname__ } is not scalar." )
154
158
155
159
def __hash__ (self ) -> int :
156
160
"""
@@ -172,13 +176,13 @@ def __int__(self) -> int:
172
176
"""
173
177
Return int(self).
174
178
175
- If the quaternion is scalar, this returns the real component as
179
+ If the quaternion is scalar, return the real component as
176
180
an integer.
177
181
"""
178
182
if self .is_scalar ():
179
183
return int (self .real )
180
184
181
- return NotImplemented
185
+ raise ValueError ( f" { self . __class__ . __qualname__ } is not scalar." )
182
186
183
187
def __iter__ (self ) -> Iterator [float ]:
184
188
"""
@@ -232,7 +236,7 @@ def _sign(x: float) -> str:
232
236
def _num_to_str (x : float ) -> str :
233
237
"""
234
238
Return a string of x as an integer if x is a positive or
235
- negative whole number, otherwise returns a float string.
239
+ negative whole number, otherwise return a float string.
236
240
"""
237
241
if x .is_integer ():
238
242
return str (int (x ))
@@ -460,7 +464,7 @@ def __floordiv__(self, other: Quaternion or float or complex) -> Quaternion:
460
464
"""
461
465
Return self // other.
462
466
463
- If other is an int or float, returns the quaternion with each
467
+ If other is an int or float, return the quaternion with each
464
468
component floor divided by other.
465
469
"""
466
470
if isinstance (other , (int , float )):
@@ -572,7 +576,7 @@ def get_imag(self) -> float:
572
576
"""
573
577
Return the imaginary component of the quaternion if only one
574
578
of the imaginary components is nonzero. If the quaternion is
575
- scalar, this returns 0.0. Otherwise, returns None.
579
+ scalar, return `` 0.0`` . Otherwise, return `` None`` .
576
580
"""
577
581
if self .is_complex ():
578
582
for component in (self .i , self .j , self .k ):
@@ -586,9 +590,7 @@ def get_imag(self) -> float:
586
590
def get_vector_components (self ) -> Tuple [float ]:
587
591
"""
588
592
Return the vector components of the Quaternion as a tuple
589
- formatted as
590
-
591
- (i, j, k).
593
+ formatted as ``(i, j, k)``.
592
594
"""
593
595
return (self .i , self .j , self .k )
594
596
@@ -598,9 +600,7 @@ def inverse(self) -> Quaternion:
598
600
599
601
Return the inverse of the quaternion. The inverse of a
600
602
quaternion is defined as the conjugate divided by the norm
601
- squared:
602
-
603
- .. code-block:: python
603
+ squared::
604
604
605
605
q.inverse() = q.conjugate()/(q.norm)**2
606
606
@@ -627,16 +627,16 @@ def inverse(self) -> Quaternion:
627
627
628
628
return q_inverse
629
629
630
- def unit_quaternion (self ) -> Quaternion or None :
630
+ def unit_quaternion (self ) -> Quaternion :
631
631
"""
632
- Return the quaternion normalized to unity (1).
632
+ Return the quaternion normalized to magnitude one (1).
633
633
634
- If the quaternion is a zero (0) quaternion, returns None .
634
+ If the quaternion is a zero (0) quaternion, return the zero quaternion .
635
635
"""
636
636
if self .__abs__ () != 0.0 :
637
637
return self .versor
638
638
639
- return None
639
+ return Quaternion ( 0 )
640
640
641
641
def unit_vector (self ) -> Quaternion :
642
642
"""
@@ -654,8 +654,8 @@ def unit_vector(self) -> Quaternion:
654
654
#####################
655
655
def is_complex (self ) -> bool :
656
656
"""
657
- Return True if only one of the i, j , and k components is
658
- nonzero. Otherwise, returns False.
657
+ Return `` True`` if only one of the *i*, *j* , and *k* components is
658
+ nonzero. Otherwise, return `` False`` .
659
659
"""
660
660
if (self .i , self .j , self .k ) != (0.0 , 0.0 , 0.0 ):
661
661
if (0.0 , 0.0 ) in (
@@ -666,8 +666,8 @@ def is_complex(self) -> bool:
666
666
667
667
def is_scalar (self ) -> bool :
668
668
"""
669
- Return True if the vector components all equal zero.
670
- Otherwise, returns False.
669
+ Return `` True`` if the vector components all equal zero.
670
+ Otherwise, return `` False`` .
671
671
"""
672
672
if (self .i , self .j , self .k ) == (0.0 , 0.0 , 0.0 ):
673
673
return True
@@ -676,8 +676,8 @@ def is_scalar(self) -> bool:
676
676
677
677
def is_vector (self ) -> bool :
678
678
"""
679
- Return True if the scalar part is zero and at least one of
680
- the vector components is nonzero. Otherwise, returns False.
679
+ Return `` True`` if the scalar part is zero and at least one of
680
+ the vector components is nonzero. Otherwise, return `` False`` .
681
681
"""
682
682
if self .real == 0.0 and (
683
683
self .i != 0.0 or self .j != 0.0 or self .k != 0.0 ):
@@ -689,60 +689,49 @@ def is_vector(self) -> bool:
689
689
################
690
690
@property
691
691
def angle (self ) -> float :
692
- """
693
- Return the angle of the quaternion in radians.
694
-
695
- Quaternions can be expressed as
696
-
697
- ``norm*(cos(theta) + u*sin(theta))``
698
-
699
- where u is a 3D unit vector. This returns the angle theta from
700
- this expression. Can also be called with ``Quaternion.angle_in_radians``.
701
- """
692
+ """The angle of the quaternion in radians."""
702
693
return _atan2 (self .vector .__abs__ (), self .real )
703
694
704
695
@property
705
696
def angle_in_degrees (self ) -> float :
706
- """Return the angle of the quaternion in degrees."""
697
+ """The angle of the quaternion in degrees."""
707
698
return self .angle * 180 / _pi
708
699
709
700
angle_in_radians = angle
710
701
711
702
@property
712
703
def components (self ) -> Tuple [float ]:
713
704
"""
714
- Return the components of the quaternion as a tuple in the order
715
- `real, i, j, k`.
705
+ The components of the quaternion as a tuple in the order
706
+ ``( real, i, j, k)` `.
716
707
"""
717
708
return (self .real , self .i , self .j , self .k )
718
709
719
710
@property
720
711
def norm (self ) -> float :
721
- """Return the norm (magnitude) of the quaternion. Same as using the abs() function."""
712
+ """
713
+ The norm (magnitude) of the quaternion.
714
+ """
722
715
return self .__abs__ ()
723
716
724
717
@property
725
- def scalar (self ) -> float :
726
- """Return the real part of the quaternion."""
727
- return self .real
718
+ def scalar (self ) -> Quaternion :
719
+ """The real part of the quaternion."""
720
+ return Quaternion ( self .real , 0 , 0 , 0 )
728
721
729
722
@property
730
723
def vector (self ) -> Quaternion :
731
- """Return the vector part of the quaternion."""
724
+ """The vector part of the quaternion."""
732
725
return Quaternion (0 , self .i , self .j , self .k )
733
726
734
727
@property
735
728
def vector_norm (self ) -> float :
736
- """Return the norm of the vector part of the quaternion."""
729
+ """The norm of the vector part of the quaternion."""
737
730
return self .vector .__abs__ ()
738
731
739
732
@property
740
733
def versor (self ) -> Quaternion :
741
- """
742
- Return the quaternion normalized to a magnitude of one (1). The rounds
743
- parameter determines the maximum number of times the quaternion is
744
- divided by its norm to get a versor with norm one (1).
745
- """
734
+ """The quaternion normalized to a magnitude of one (1)."""
746
735
versor = self
747
736
for _ in range (10 ): # Prevents an infinite loop.
748
737
# Doesn't always divide to norm 1 on the first division.
@@ -760,14 +749,11 @@ def from_angle(
760
749
"""
761
750
Return a quaternion from an angle and vector.
762
751
763
- Quaternions can be expressed as
764
-
765
- norm*(cos(theta) + u*sin(theta)),
766
-
767
- where u is a 3D unit vector. This function takes an angle and a vector to
752
+ Quaternions can be expressed as ``norm*(cos(theta) + u*sin(theta))``,
753
+ where ``u`` is a 3D unit vector. This function takes an angle and a vector to
768
754
create a quaternion. If you want a quaternion with a different norm than
769
- one (1), you can change the ' norm' argument. By default, angles are entered
770
- in degrees. If you want to enter an angle in radians, set ' degrees' to
755
+ one (1), you can change the `` norm`` argument. By default, angles are entered
756
+ in degrees. If you want to enter an angle in radians, set `` degrees`` to
771
757
False.
772
758
"""
773
759
if degrees :
0 commit comments