예제 #1
0
    def __isub__(self, q) :
        """
        Subtraction operator (-=) that subtracts a quaternion from this one and assigns the difference to itself.
        
        Input:
        q - quaternion or a float value to be subtracted from this one
        
        Return:
        a reference to itself
        
        A QuaternionException is raised if 'q' is not an instance of 
        Quaternion, float or int.
        """
        
        # For a definition of quaternion subtraction, see __sub__

        if Quaternion.isQuaternion(q) :
            self.o -= q.o
            self.i -= q.i
            self.j -= q.j
            self.k -= q.k
        elif InstanceCheck.isFloat(q) :
            self.o -= q
        else:
            raise QuaternionException("Input must be a quaternion or a float")
        return self
예제 #2
0
    def __add__(self, q) :
        """
        Implementation of the addition operator '+' of two quaternions.
        
        Input:
        q - quaternion or a float value to be added to this one
        
        Return:
        a new instance of Quaternion
        
        A QuaternionException is raised if 'q' is not an instance of
        Quaternion, float or int.
        """

        # Addition of quaternions is trivial:
        #
        #   (a1 + b1*i + c1*j + d1*k) + (a2 + b2*i + c2*j + d2*k) =
        # = ( (a1+a2) + (b1+b2)*i + (c1+c2)*j + (d1+d2)*k )

        if Quaternion.isQuaternion(q) :
            return Quaternion(
                self.o + q.o,
                self.i + q.i,
                self.j + q.j,
                self.k + q.k )
        elif InstanceCheck.isFloat(q) :
            return Quaternion(
                self.o + q,
                self.i,
                self.j,
                self.k )
        else:
            raise QuaternionException("Input must be a quaternion or a float")
예제 #3
0
    def __iadd__(self, q) :
        """
        Addition operator (+=) that adds a quaternion to this one and assigns the sum to itself.
        
        Input:
        q - quaternion or a float value to be added to this one
        
        Return:
        a reference to itself
        
        A QuaternionException is raised if 'q' is not an instance of 
        Quaternion, float or int.
        """
        
        # For a definition of quaternion addition, see __add__

        if Quaternion.isQuaternion(q) :
            self.o += q.o
            self.i += q.i
            self.j += q.j
            self.k += q.k
        elif InstanceCheck.isFloat(q) :
            self.o += q
        else:
            raise QuaternionException("Input must be a quaternion or a float")
        return self
예제 #4
0
    def __sub__(self, q) :
        """
        Implementation of the subtraction operator '-' of two quaternions.
        
        Input:
        q - quaternion or a float value to be subtracted from this one
        
        Return:
        a new instance of Quaternion
        
        A QuaternionException is raised if 'q' is not an instance of 
        Quaternion, float or int.
        """
        
        # Subtraction of quaternions is trivial:
        #
        #   (a1 + b1*i + c1*j + d1*k) - (a2 + b2*i + c2*j + d2*k) =
        # = ( (a1-a2) + (b1-b2)*i + (c1-c2)*j + (d1-d2)*k )

        if Quaternion.isQuaternion(q) :
            return Quaternion(
                self.o - q.o,
                self.i - q.i,
                self.j - q.j,
                self.k - q.k ) 
        elif InstanceCheck.isFloat(q) :
            return Quaternion(
                self.o - q,
                self.i,
                self.j,
                self.k ) 
        else:
            raise QuaternionException("Input must be a quaternion or a float")
예제 #5
0
 def setZ(self, z=0.0):
     """
     Sets point's z-component. Other components are not changed.
     A PointException is raised if x is not a float or integer value.
     """
     if InstanceCheck.isFloat(z):
         self.z = z
     else:
         raise PointException("Invalid input argument")
예제 #6
0
    def setQ(self, o=0.0, i=0.0, j=0.0, k=0.0) :
        """
        Assigns values of all quaternion's components.

        Input:
        o - scalar component of the quaternion (default: 0)
        i - component 'i' of the quaternion (default: 0)
        j - component 'j' of the quaternion (default: 0)
        k - component 'k' of the quaternion (default: 0)

        Alternatively 'o' may be a quaternion. In this case, its components
        are copied into self's ones and all other input arguments are ignored.
        
        A QuaternionExceptionxception is raised if any argument is not an instance
        of supported types (int, float, Quaternion).
        """

        if Quaternion.isQuaternion(o) :
            # If o is a quaternion, simply copy its components...
            self.o = o.o
            self.i = o.i
            self.j = o.j
            self.k = o.k
        else:
            # otherwise check if all inputs are floats or integers...
            if not (
                InstanceCheck.isFloat(o) and 
                InstanceCheck.isFloat(i) and 
                InstanceCheck.isFloat(j) and
                InstanceCheck.isFloat(k) ) :
                    raise QuaternionException("Invalid input arguments")
            
            # if they are, just assign their values to quaternion's components
            self.o = o;
            self.i = i;
            self.j = j;
            self.k = k;

            return self
예제 #7
0
 def __init__(self, x=0.0, y=0.0, z=0.0):
     """
     A "constructor" that initializes a point
     
     Input:
     x - x component of a point/vector
     y - y component of a point/vector
     z - z component of a point/vector
     
     'x' may also be an instance of Point3D. In this case, the other
     arguments are ignored and the method acts as a copy constructor.
     
     A PointException is raised if input arguments are of invalid types.
     """
     if InstanceCheck.isFloat(x) and InstanceCheck.isFloat(y) and InstanceCheck.isFloat(z):
         self.x = x
         self.y = y
         self.z = z
     elif Point3D.isPoint3D(x):
         self.setPoint(x)
     else:
         raise PointException("Invalid input arguments")
예제 #8
0
    def setK(self, k=0.0) :
        """
        Assigns the component 'k' of the quaternion.

        Input:
        k - value of the component 'k' (default: 0)

        Raises a QuaternionException if 'k' is not an instance 
        of a supported type (float or int).
        """

        if not InstanceCheck.isFloat(k) :
            raise QuaternionException("Invalid input argument")
        self.k = k
        return self
예제 #9
0
    def setI(self, i=0.0) :
        """
        Assigns the component 'i' of the quaternion.
        
        Input:
        i - value of the component 'i' (default: 0)
        
        Raises a QuaternionException if 'i' is not an instance 
        of a supported type (float or int).
        """

        if not InstanceCheck.isFloat(i) :
            raise QuaternionException("Invalid input argument")
        self.i = i;
        return self
예제 #10
0
    def setScalar(self, o=0.0) :
        """
        Assigns the scalar component of the quaternion.
        
        Input:
        o - value of the scalar component (default: 0)
        
        Raises a QuaternionException if 'o' is not an instance
        of a supported type (float or int).
        """

        if not InstanceCheck.isFloat(o) :
            raise QuaternionException("Invalid input argument")
        self.o = o
        return self
예제 #11
0
    def setAngle(self, angle=0.0):
        """
        Sets a new angle of rotation. 
        Rotation vector's components remain unmodified.
        
        Input:
        - angle - angle of rotation in radians (default: 0)
        
        A RotationException is raised if 'angle' is not a float or integer value.
        """
        if not InstanceCheck.isFloat(angle):
            raise RotationException("Angle must be float value")

        self.__theta = angle
        self.__update()
예제 #12
0
    def __mul__(self, q) :
        """
        Implementation of the multiplication operator '*' of two quaternions.
        Note that multiplication of quaternions is not commutative: (p*q != q*p)
        
        Input:
        q - quaternion or a float value to be multiplied by this one
        
        Return:
        a new instance of Quaternion
        
        A QuaternionException is raised if 'q' is not an instance of 
        Quaternion, float or int.
        """
        
        # From the following definitions:
        # i*i = j*j = k*k = -1,
        # i*j = k, j*i = -k, j*k = i, k*j = -i, k*i = j and i*k = -j,
        # the following formula can be quickly derived:
        #
        # (a1 + b1*i + c1*j + d1*k) * (a2 + b2*i + c2*j + d2*k) =
        # = (a1*a2 - b1*b2 - c1*c2 - d1*d2) +
        # + (a1*b2 + b1*a2 + c1*d2 - d1*c2) * i +
        # + (a1*c2 - b1*d2 + c1*a2 + d1*b2) * j +
        # + (a1*d2 + b1*c2 - c1*b2 + d1*a2) * k
        #
        # Note: The following script for GNU Octave or Matlab can be used
        # for a quick unit test of the function:
        # http://mind.cog.jhu.edu/courses/680/octave/Installers/Octave/Octave.OSX10.6/Applications/MATLAB_R2009b.app/toolbox/aero/aero/quatmultiply.m

        if Quaternion.isQuaternion(q) :
            return Quaternion(
                self.o * q.o - self.i * q.i - self.j * q.j - self.k * q.k,
                self.o * q.i + self.i * q.o + self.j * q.k - self.k * q.j,
                self.o * q.j - self.i * q.k + self.j * q.o + self.k * q.i,
                self.o * q.k + self.i * q.j - self.j * q.i + self.k * q.o )
        elif InstanceCheck.isFloat(q) :
            return Quaternion(
                self.o * q,
                self.i * q,
                self.j * q,
                self.k * q )
        else:
            raise QuaternionException("Input must be a quaternion or a float")
예제 #13
0
    def __imul__(self, q) :
        """
        Multiplication operator (*=) that multiplies this by a quaternion and assigns the product to itself.
        
        Input:
        q - quaternion or a float value to be multiplied to this one
        
        Return:
        a reference to itself
        
        A QuaternionException is raised if 'q' is not an instance of 
        Quaternion, float or int.
        """
        
        # For a definition of quaternion multiplication, see __mul__

        if Quaternion.isQuaternion(q) :
            # From maintanance poit of view, this would
            # a more elegant solution:
            #qaux = self * q;
            #self.o = qaux.o;
            #self.i = qaux.i
            #self.j = qaux.j
            #self.k = qaux.k
            # However, this one slightly reduces overhead with
            # instantiation and destruction of another instance of Quaternion:
            self.o, self.i, self.j, self. k = \
                self.o * q.o - self.i * q.i - self.j * q.j - self.k * q.k, \
                self.o * q.i + self.i * q.o + self.j * q.k - self.k * q.j, \
                self.o * q.j - self.i * q.k + self.j * q.o + self.k * q.i, \
                self.o * q.k + self.i * q.j - self.j * q.i + self.k * q.o 
        elif  InstanceCheck.isFloat(q) :
            self.o *= q
            self.i *= q
            self.j *= q
            self.k *= q
        else:
            raise QuaternionException("Input must be a quaternion or a float")
        return self
예제 #14
0
    def __init__(self, rx=0.0, ry=0.0, rz=0.0, angle=0.0):
        """
        A "constructor" that initializes an object.__class__
        
        Input:
        - rx - x - component of the vector (default: 0)
        - ry - y - component of the vector (default: 0)
        - rz - z - component of the vector (default: 0)
        - angle - angle of rotation in radians (default: 0)
        
        'rx' may also be an instance of a Point3D. In this case, ry and rz
        are ignored and rx's components are copied into this object.
        
        Note that the vector will automatically be converted into a unit vector.
        
        A RotationException is raised if input arguments are of invalid types.
        """
        if not InstanceCheck.isFloat(angle):
            raise RotationException("Angle must be a float value")

        self.__theta = angle
        self.setAxis(rx, ry, rz)