Math_Quaternion
[ class tree: Math_Quaternion ] [ index: Math_Quaternion ] [ all elements ]

Source for file QuaternionOp.php

Documentation is available at QuaternionOp.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Jesus M. Castagnetto <jmcastagnetto@php.net>                |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: QuaternionOp.php 303949 2010-10-02 16:11:40Z clockwerx $
  20. //
  21.  
  22. include_once 'PEAR.php';
  23. include_once 'Math/Quaternion.php';
  24.  
  25. /**
  26.  * Math_QuaternionOp: class that implements operations on quaternions
  27.  *
  28.  * Originally this class was part of NumPHP (Numeric PHP package)
  29.  *
  30.  * Example:
  31.  * <pre>
  32.  * require_once 'Math/QuaternionOp.php';
  33.  * 
  34.  * $a = new Math_Quaternion(2,4,2,-0.5);
  35.  * $b = new Math_Quaternion(1,2,3,0.5);
  36.  * 
  37.  * if (!Math_QuaternionOp::areEqual($a, Math_QuaternionOp::negate($a))) {
  38.  *     echo "a and neg(a) are different\n";
  39.  * }
  40.  * $t=Math_QuaternionOp::negate($a);
  41.  * echo "Neg(a) is ".$t->toString()."\n";
  42.  * $t=Math_QuaternionOp::conjugate($a);
  43.  * echo "Conj(a) is ".$t->toString()."\n";
  44.  * $t=Math_QuaternionOp::inverse($a);
  45.  * echo "Inv(a) is ".$t->toString()."\n";
  46.  * $t=Math_QuaternionOp::multReal($a, 1.23);
  47.  * echo "MultReal(a, 1.23) is ".$t->toString()."\n";
  48.  * 
  49.  * echo "====\n";
  50.  * $t=Math_QuaternionOp::mult($a,$b);
  51.  * echo "a*b: ".$t->toString()."\n";
  52.  * $t=Math_QuaternionOp::mult($b,$a);
  53.  * echo "b*a: ".$t->toString()."\n";
  54.  * $t=Math_QuaternionOp::mult($a,Math_QuaternionOp::conjugate($a));
  55.  * echo "a*a': ".$t->toString()."\n";
  56.  * echo "length(a*a'): ".$t->length()."\n";
  57.  * $t=Math_QuaternionOp::add($a,$b);
  58.  * echo "a+b: ".$t->toString()."\n";
  59.  * $t=Math_QuaternionOp::sub($a,$b);
  60.  * echo "a-b: ".$t->toString()."\n";
  61.  * $t=Math_QuaternionOp::sub($b,$a);
  62.  * echo "b-a: ".$t->toString()."\n";
  63.  * $t=Math_QuaternionOp::sub($b,Math_QuaternionOp::conjugate($a));
  64.  * echo "b-a': ".$t->toString()."\n";
  65.  * $t=Math_QuaternionOp::sub(Math_QuaternionOp::conjugate($b), $a);
  66.  * echo "b'-a: ".$t->toString()."\n";
  67.  * $t=Math_QuaternionOp::sub(Math_QuaternionOp::conjugate($b), Math_QuaternionOp::conjugate($a));
  68.  * echo "b'-a': ".$t->toString()."\n";
  69.  * $t = Math_QuaternionOp::div($a, $b);
  70.  * echo "a/b: ".$t->toString()."\n";
  71.  * $t = Math_QuaternionOp::div($b, $a);
  72.  * echo "b/a: ".$t->toString()."\n";
  73.  * </pre>
  74.  *
  75.  * Output from example:
  76.  * <pre>
  77.  * a and neg(a) are different
  78.  * Neg(a) is -2 + -4i + -2j + 0.5k
  79.  * Conj(a) is 2 + -4i + -2j + 0.5k
  80.  * Inv(a) is 0.40613846605345 + -0.8122769321069i + -0.40613846605345j + 0.10153461651336k
  81.  * MultReal(a, 1.23) is 2.46 + 4.92i + 2.46j + -0.615k
  82.  * ====
  83.  * a*b: -11.25 + 6i + 9j + 1.5k
  84.  * b*a: -18.25 + 12i + 6j + -1.5k
  85.  * a*a': -16.25 + -16i + -8j + 2k
  86.  * length(a*a'): 24.25
  87.  * a+b: 3 + 6i + 5j + 0k
  88.  * a-b: 1 + 2i + -1j + -1k
  89.  * b-a: -1 + -2i + 1j + 1k
  90.  * b-a': -1 + 6i + 5j + 0k
  91.  * b'-a: -1 + -6i + -5j + 0k
  92.  * b'-a': -1 + 2i + -1j + -1k
  93.  * a/b: -19.720187057174 + 9.059625885652i + 4.529812942826j + -1.1324532357065k
  94.  * b/a: -12.843861533947 + 2.8122769321069i + 4.2184153981603j + 0.70306923302672k
  95.  * </pre>
  96.  *
  97.  * @author  Jesus M. Castagnetto <jmcastagnetto@php.net>
  98.  * @version 0.7
  99.  * @access  public
  100.  * @package Math_Quaternion
  101.  */
  102. class Math_QuaternionOp {/*{{{*/
  103.  
  104.     /**
  105.      * Whether the object is a Math_Quaternion instance
  106.      *
  107.      * @param object Math_Quaternion $q1 
  108.      * @return boolean TRUE if object is a Math_Quaternion, FALSE otherwise
  109.      * @access public
  110.      */
  111.     function isQuaternion (&$q1{/*{{{*/
  112.         if (function_exists('is_a')) {
  113.             return is_a($q1'math_quaternion');
  114.         else {
  115.             return (strtolower(get_class($q1)) == 'math_quaternion' 
  116.                     || is_subclass_of($q1'math_quaternion'));
  117.         }
  118.     }/*}}}*/
  119.  
  120.     /**
  121.      * Calculate the conjugate of a quaternion
  122.      *
  123.      * @param object Math_Quaternion $q1 
  124.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  125.      * @access public
  126.      */
  127.     function &conjugate (&$q1{/*{{{*/
  128.         if (!Math_QuaternionOp::isQuaternion($q1)) {
  129.             return PEAR::raiseError("Parameter needs to be a Math_Quaternion object");
  130.         }
  131.         $q2 $q1->makeClone();
  132.         $q2->conjugate();
  133.         return $q2;
  134.     }/*}}}*/
  135.         
  136.     /**
  137.      * Negates the given quaternion
  138.      *
  139.      * @param object Math_Quaternion $q1 
  140.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  141.      * @access public
  142.      */
  143.     function &negate (&$q1{/*{{{*/
  144.         if (!Math_QuaternionOp::isQuaternion($q1)) {
  145.             return PEAR::raiseError("Parameter needs to be a Math_Quaternion object");
  146.         }
  147.         $q2 $q1->makeClone();
  148.         $q2->negate();
  149.         return $q2;
  150.     }/*}}}*/
  151.  
  152.     /**
  153.      * Inverts the given quaternion
  154.      *
  155.      * @param object Math_Quaternion $q1 
  156.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  157.      * @access public
  158.      * @see Math_QuaternionOp::multReal
  159.      */
  160.     function &inverse (&$q1{/*{{{*/
  161.         if (!Math_QuaternionOp::isQuaternion($q1)) {
  162.             return PEAR::raiseError("Parameter needs to be a Math_Quaternion object");
  163.         }
  164.         $c Math_QuaternionOp::conjugate($q1);
  165.         $norm $q1->norm();
  166.         if ($norm == 0{
  167.             return PEAR::raiseError('Quaternion norm is zero, cannot calculate inverse');
  168.         }
  169.         $invmult = 1/$norm;
  170.         return Math_QuaternionOp::multReal($c$invmult);
  171.     }/*}}}*/
  172.  
  173.     /**
  174.      * Checks if two quaternions represent the same number
  175.      *
  176.      * @param object Math_Quaternion $q1 
  177.      * @param object Math_Quaternion $q2 
  178.      * @return mixed PEAR_Error on error, TRUE if q1 == q2, FALSE otherwise
  179.      * @access public
  180.      */
  181.     function areEqual (&$q1&$q2{/*{{{*/
  182.         if (!Math_QuaternionOp::isQuaternion($q1|| !Math_QuaternionOp::isQuaternion($q2)) {
  183.             return PEAR::raiseError("Parameters need to be Math_Quaternion objects");
  184.         }
  185.         return $q1->getReal(== $q2->getReal(&& $q1->getI(== $q2->getI(&&
  186.                  $q1->getJ(== $q2->getJ(&& $q1->getK(== $q2->getK() );
  187.     }/*}}}*/
  188.  
  189.     /**
  190.      * Adds two quaternions: q1 + q2
  191.      *
  192.      * @param object Math_Quaternion $q1 
  193.      * @param object Math_Quaternion $q2 
  194.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  195.      * @access public
  196.      */
  197.     function &add (&$q1&$q2{/*{{{*/
  198.         if (!Math_QuaternionOp::isQuaternion($q1|| !Math_QuaternionOp::isQuaternion($q2)) {
  199.             return PEAR::raiseError("Parameters need to be Math_Quaternion objects");
  200.         }
  201.         $obj = new Math_Quaternion$q1->getReal($q2->getReal()$q1->getI($q2->getI()
  202.                                 $q1->getJ($q2->getJ()$q1->getK($q2->getK() );
  203.  
  204.         return $obj;
  205.     }/*}}}*/
  206.  
  207.     /**
  208.      * Substracts two quaternions: q1 - q2
  209.      *
  210.      * @param object Math_Quaternion $q1 
  211.      * @param object Math_Quaternion $q2 
  212.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  213.      * @access public
  214.      */
  215.     function &sub (&$q1&$q2{/*{{{*/
  216.         if (!Math_QuaternionOp::isQuaternion($q1|| !Math_QuaternionOp::isQuaternion($q2)) {
  217.             return PEAR::raiseError("Parameters need to be Math_Quaternion objects");
  218.         }
  219.         return Math_QuaternionOp::add($q1Math_QuaternionOp::negate($q2));
  220.     }/*}}}*/
  221.  
  222.     /**
  223.      * Multiplies two quaternions: q1 * q2
  224.      * It uses a fast multiplication algorithm.
  225.      *
  226.      * @param object Math_Quaternion $q1 
  227.      * @param object Math_Quaternion $q2 
  228.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  229.      * @access public
  230.      */
  231.     function &mult (&$q1&$q2{/*{{{*/
  232.         if (!Math_QuaternionOp::isQuaternion($q1|| !Math_QuaternionOp::isQuaternion($q2)) {
  233.             return PEAR::raiseError("Parameters need to be Math_Quaternion objects");
  234.         }
  235.         // uses the fast multiplication algorithm
  236.         $a $q1->getReal()$q1im $q1->getAllIm();
  237.         $b $q1im["i"]$c $q1im["j"]$d $q1im["k"];
  238.  
  239.         $x $q2->getReal()$q2im $q2->getAllIm();
  240.         $y $q2im["i"]$z $q2im["j"]$w $q2im["k"];
  241.  
  242.         $t0 ($d $c($z $w)
  243.         $t1 ($a $b($x $y);
  244.         $t2 ($a $b($z $w);
  245.         $t3 ($c $d($x $y);
  246.         $t4 ($d $b($y $z);
  247.         $t5 ($d $b($y $z);
  248.         $t6 ($a $c($x $w);
  249.         $t7 ($a $c($x $w);
  250.         $t8 $t5 $t6 $t7;
  251.         $t9 = 0.5 * ($t4 $t8);
  252.         
  253.         $r $t0 $t9 $t5;
  254.         $i $t1 $t9 $t8;
  255.         $j $t2 $t9 $t7;
  256.         $k $t3 $t9 $t6;
  257.  
  258.         $obj = new Math_Quaternion($r$i $j$k);
  259.         return $obj;
  260.     }/*}}}*/
  261.  
  262.     /**
  263.      * Divides two quaternions: q1 / q2
  264.      *
  265.      * @param object Math_Quaternion $q1 
  266.      * @param object Math_Quaternion $q2 
  267.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  268.      * @access public
  269.      */
  270.     function &div(&$q1&$q2{/*{{{*/
  271.         if (!Math_QuaternionOp::isQuaternion($q1|| !Math_QuaternionOp::isQuaternion($q2)) {
  272.             return PEAR::raiseError("Parameters need to be Math_Quaternion objects");
  273.         }
  274.         $i2 Math_QuaternionOp::inverse($q2);
  275.         if (PEAR::isError($i2)) {
  276.             return $i2;
  277.         }
  278.         return Math_QuaternionOp::mult($i2$q1);
  279.     }/*}}}*/
  280.  
  281.     /**
  282.      * Multiplies a quaternion by a real number: q1 * realnum
  283.      *
  284.      * @param object Math_Quaternion $q1 
  285.      * @param float $realnum 
  286.      * @return object Math_Quaternion on success, PEAR_Error otherwise
  287.      * @access public
  288.      */
  289.     function &multReal (&$q1$realnum{/*{{{*/
  290.         if (!Math_QuaternionOp::isQuaternion($q1|| !is_numeric($realnum)) {
  291.             return PEAR::raiseError("A Math_Quaternion object and a real number are needed");
  292.         }
  293.         $obj = new Math_Quaternion $realnum $q1->getReal()$realnum $q1->getI(),
  294.                                 $realnum $q1->getJ()$realnum $q1->getK() );
  295.         return $obj;
  296.     }/*}}}*/
  297.  
  298. }/*}}} end of Math_QuaternionOp */
  299. ?>

Documentation generated on Mon, 11 Mar 2019 15:39:16 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.