001        package com.croftsoft.core.math.axis;
002    
003        import com.croftsoft.core.math.matrix.Matrix3x3Imp;
004        import com.croftsoft.core.math.matrix.Matrix3x3Mut;
005        import com.croftsoft.core.math.quat.QuatImp;
006        import com.croftsoft.core.math.quat.QuatMut;
007    
008        /***********************************************************************
009        * A library of static methods to manipulate AxisAngle objects.
010        * 
011        * @version
012        *   $Id: AxisAngleLib.java,v 1.1 2008/05/09 18:35:55 croft Exp $
013        * @since
014        *   2008-05-09
015        * @author
016        *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
017        ***********************************************************************/
018    
019        public final class  AxisAngleLib
020        ////////////////////////////////////////////////////////////////////////
021        ////////////////////////////////////////////////////////////////////////
022        {
023          
024        public static double  magnitude ( final AxisAngle  axisAngle )
025        ////////////////////////////////////////////////////////////////////////
026        {
027          final double  x = axisAngle.getX ( );
028          
029          final double  y = axisAngle.getY ( );
030          
031          final double  z = axisAngle.getZ ( );
032          
033          return Math.sqrt ( x * x + y * y + z * z );
034        }
035        
036        public static boolean  matches (
037          final AxisAngle  axisAngle0,
038          final AxisAngle  axisAngle1 )
039        ////////////////////////////////////////////////////////////////////////
040        {
041          return axisAngle0.getDegrees ( ) == axisAngle1.getDegrees ( )
042              && axisAngle0.getX ( ) == axisAngle1.getX ( )
043              && axisAngle0.getY ( ) == axisAngle1.getY ( )
044              && axisAngle0.getZ ( ) == axisAngle1.getZ ( );
045        }
046          
047        public static boolean  matches (
048          final AxisAngle    axisAngle0,
049          final AxisAngle    axisAngle1,
050          final double  tolerance )
051        ////////////////////////////////////////////////////////////////////////
052        {
053          if ( tolerance < 0 )
054          {
055            throw new IllegalArgumentException ( "tolerance < 0" );
056          }
057          
058          return Math.abs (
059                axisAngle0.getDegrees ( ) - axisAngle1.getDegrees ( ) )
060                <= tolerance
061              && Math.abs ( axisAngle0.getX ( ) - axisAngle1.getX ( ) )
062                <= tolerance
063              && Math.abs ( axisAngle0.getY ( ) - axisAngle1.getY ( ) )
064                <= tolerance
065              && Math.abs ( axisAngle0.getZ ( ) - axisAngle1.getZ ( ) )
066                <= tolerance;
067        }
068        
069        public static void  normalize ( final AxisAngleMut  axisAngleMut )
070        ////////////////////////////////////////////////////////////////////////
071        {
072          final double  magnitude = axisAngleMut.magnitude ( );
073          
074          axisAngleMut.setX ( axisAngleMut.getX ( ) / magnitude );
075          
076          axisAngleMut.setY ( axisAngleMut.getY ( ) / magnitude );
077          
078          axisAngleMut.setZ ( axisAngleMut.getZ ( ) / magnitude );
079        }
080          
081        public static QuatMut  toQuat ( final AxisAngle  axisAngle )
082        ////////////////////////////////////////////////////////////////////////
083        {
084          final double  halfRadians
085            = Math.toRadians ( axisAngle.getDegrees ( ) / 2 );
086          
087          final double  sinHalfRadians = Math.sin ( halfRadians );
088          
089          return new QuatImp (
090            Math.cos ( halfRadians ),
091            sinHalfRadians * axisAngle.getX ( ),
092            sinHalfRadians * axisAngle.getY ( ),
093            sinHalfRadians * axisAngle.getZ ( ) );
094        }
095        
096        public static Matrix3x3Mut  toRotationMatrix (
097          final AxisAngle  axisAngle )
098        ////////////////////////////////////////////////////////////////////////
099        {
100          // return toQuat ( axisAngle ).toRotationMatrix ( );
101          
102          final double  degrees = axisAngle.getDegrees ( );
103          
104          final double  x = axisAngle.getX ( );
105          
106          final double  y = axisAngle.getY ( );
107          
108          final double  z = axisAngle.getZ ( );
109          
110          final double  c = Math.cos ( Math.toRadians ( degrees ) );
111          
112          final double  s = Math.sin ( Math.toRadians ( degrees ) );
113          
114          // Lengyel, "Mathematics for 3D Game Programming & Computer Graphics",
115          // Second Edition, p80, equation 3.22.
116          
117          return new Matrix3x3Imp (
118            c + ( 1 - c ) * x * x,
119            ( 1 - c ) * x * y - s * z,
120            ( 1 - c ) * x * z + s * y,
121            
122            ( 1 - c ) * x * y + s * z,
123            c + ( 1 - c ) * y * y,
124            ( 1 - c ) * y * z - s * x,
125            
126            ( 1 - c ) * x * z - s * y,
127            ( 1 - c ) * y * z + s * x,
128            c + ( 1 - c ) * z * z );
129        }
130          
131        public static String  toString ( final AxisAngle  axisAngle )
132        ////////////////////////////////////////////////////////////////////////
133        {
134          return String.format (
135            "%1$1.3f; %2$1.3f, %3$1.3f, %4$1.3f",
136            new Double ( axisAngle.getDegrees ( ) ),
137            new Double ( axisAngle.getX ( ) ),
138            new Double ( axisAngle.getY ( ) ),
139            new Double ( axisAngle.getZ ( ) ) );
140        }
141        
142        ////////////////////////////////////////////////////////////////////////
143        // private methods
144        ////////////////////////////////////////////////////////////////////////
145        
146        private  AxisAngleLib ( )
147        ////////////////////////////////////////////////////////////////////////
148        {
149          // empty
150        }
151        
152        ////////////////////////////////////////////////////////////////////////
153        ////////////////////////////////////////////////////////////////////////
154        }