001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math.geometry;
019    
020    import org.apache.commons.math.geometry.Vector3D;
021    
022    import junit.framework.*;
023    
024    public class Vector3DTest
025      extends TestCase {
026    
027      public Vector3DTest(String name) {
028        super(name);
029      }
030    
031      public void testConstructors() {
032          double r = Math.sqrt(2) /2;
033          checkVector(new Vector3D(2, new Vector3D(Math.PI / 3, -Math.PI / 4)),
034                      r, r * Math.sqrt(3), -2 * r);
035          checkVector(new Vector3D(2, Vector3D.PLUS_I,
036                                  -3, Vector3D.MINUS_K),
037                      2, 0, 3);
038          checkVector(new Vector3D(2, Vector3D.PLUS_I,
039                                   5, Vector3D.PLUS_J,
040                                  -3, Vector3D.MINUS_K),
041                      2, 5, 3);
042          checkVector(new Vector3D(2, Vector3D.PLUS_I,
043                                   5, Vector3D.PLUS_J,
044                                   5, Vector3D.MINUS_J,
045                                   -3, Vector3D.MINUS_K),
046                      2, 0, 3);
047      }
048    
049      public void testCoordinates() {
050        Vector3D v = new Vector3D(1, 2, 3);
051        assertTrue(Math.abs(v.getX() - 1) < 1.0e-12);
052        assertTrue(Math.abs(v.getY() - 2) < 1.0e-12);
053        assertTrue(Math.abs(v.getZ() - 3) < 1.0e-12);
054      }
055      
056      public void testNorm1() {
057        assertEquals(0.0, Vector3D.ZERO.getNorm1());
058        assertEquals(6.0, new Vector3D(1, -2, 3).getNorm1(), 0);
059      }
060    
061      public void testNorm() {
062          assertEquals(0.0, Vector3D.ZERO.getNorm());
063          assertEquals(Math.sqrt(14), new Vector3D(1, 2, 3).getNorm(), 1.0e-12);
064        }
065    
066      public void testNormInf() {
067          assertEquals(0.0, Vector3D.ZERO.getNormInf());
068          assertEquals(3.0, new Vector3D(1, -2, 3).getNormInf(), 0);
069        }
070    
071      public void testDistance1() {
072          Vector3D v1 = new Vector3D(1, -2, 3);
073          Vector3D v2 = new Vector3D(-4, 2, 0);
074          assertEquals(0.0, Vector3D.distance1(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
075          assertEquals(12.0, Vector3D.distance1(v1, v2), 1.0e-12);
076          assertEquals(v1.subtract(v2).getNorm1(), Vector3D.distance1(v1, v2), 1.0e-12);
077      }
078    
079      public void testDistance() {
080          Vector3D v1 = new Vector3D(1, -2, 3);
081          Vector3D v2 = new Vector3D(-4, 2, 0);
082          assertEquals(0.0, Vector3D.distance(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
083          assertEquals(Math.sqrt(50), Vector3D.distance(v1, v2), 1.0e-12);
084          assertEquals(v1.subtract(v2).getNorm(), Vector3D.distance(v1, v2), 1.0e-12);
085      }
086    
087      public void testDistanceSq() {
088          Vector3D v1 = new Vector3D(1, -2, 3);
089          Vector3D v2 = new Vector3D(-4, 2, 0);
090          assertEquals(0.0, Vector3D.distanceSq(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
091          assertEquals(50.0, Vector3D.distanceSq(v1, v2), 1.0e-12);
092          assertEquals(Vector3D.distance(v1, v2) * Vector3D.distance(v1, v2),
093                       Vector3D.distanceSq(v1, v2), 1.0e-12);
094      }
095    
096      public void testDistanceInf() {
097          Vector3D v1 = new Vector3D(1, -2, 3);
098          Vector3D v2 = new Vector3D(-4, 2, 0);
099          assertEquals(0.0, Vector3D.distanceInf(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
100          assertEquals(5.0, Vector3D.distanceInf(v1, v2), 1.0e-12);
101          assertEquals(v1.subtract(v2).getNormInf(), Vector3D.distanceInf(v1, v2), 1.0e-12);
102      }
103    
104      public void testSubtract() {
105    
106        Vector3D v1 = new Vector3D(1, 2, 3);
107        Vector3D v2 = new Vector3D(-3, -2, -1);
108        v1 = v1.subtract(v2);
109        checkVector(v1, 4, 4, 4);
110    
111        checkVector(v2.subtract(v1), -7, -6, -5);
112        checkVector(v2.subtract(3, v1), -15, -14, -13);
113    
114      }
115    
116      public void testAdd() {
117        Vector3D v1 = new Vector3D(1, 2, 3);
118        Vector3D v2 = new Vector3D(-3, -2, -1);
119        v1 = v1.add(v2);
120        checkVector(v1, -2, 0, 2);
121    
122        checkVector(v2.add(v1), -5, -2, 1);
123        checkVector(v2.add(3, v1), -9, -2, 5);
124    
125      }
126    
127      public void testScalarProduct() {
128        Vector3D v = new Vector3D(1, 2, 3);
129        v = v.scalarMultiply(3);
130        checkVector(v, 3, 6, 9);
131    
132        checkVector(v.scalarMultiply(0.5), 1.5, 3, 4.5);
133    
134      }
135    
136      public void testVectorialProducts() {
137        Vector3D v1 = new Vector3D(2, 1, -4);
138        Vector3D v2 = new Vector3D(3, 1, -1);
139    
140        assertTrue(Math.abs(Vector3D.dotProduct(v1, v2) - 11) < 1.0e-12);
141    
142        Vector3D v3 = Vector3D.crossProduct(v1, v2);
143        checkVector(v3, 3, -10, -1);
144    
145        assertTrue(Math.abs(Vector3D.dotProduct(v1, v3)) < 1.0e-12);
146        assertTrue(Math.abs(Vector3D.dotProduct(v2, v3)) < 1.0e-12);
147    
148      }
149    
150      public void testAngular() {
151    
152        assertEquals(0,           Vector3D.PLUS_I.getAlpha(), 1.0e-10);
153        assertEquals(0,           Vector3D.PLUS_I.getDelta(), 1.0e-10);
154        assertEquals(Math.PI / 2, Vector3D.PLUS_J.getAlpha(), 1.0e-10);
155        assertEquals(0,           Vector3D.PLUS_J.getDelta(), 1.0e-10);
156        assertEquals(0,           Vector3D.PLUS_K.getAlpha(), 1.0e-10);
157        assertEquals(Math.PI / 2, Vector3D.PLUS_K.getDelta(), 1.0e-10);
158    
159        Vector3D u = new Vector3D(-1, 1, -1);
160        assertEquals(3 * Math.PI /4, u.getAlpha(), 1.0e-10);
161        assertEquals(-1.0 / Math.sqrt(3), Math.sin(u.getDelta()), 1.0e-10);
162    
163      }
164    
165      public void testAngularSeparation() {
166        Vector3D v1 = new Vector3D(2, -1, 4);
167    
168        Vector3D  k = v1.normalize();
169        Vector3D  i = k.orthogonal();
170        Vector3D v2 = k.scalarMultiply(Math.cos(1.2)).add(i.scalarMultiply(Math.sin(1.2)));
171    
172        assertTrue(Math.abs(Vector3D.angle(v1, v2) - 1.2) < 1.0e-12);
173    
174      }
175    
176      public void testNormalize() {
177        assertEquals(1.0, new Vector3D(5, -4, 2).normalize().getNorm(), 1.0e-12);
178        try {
179            Vector3D.ZERO.normalize();
180            fail("an exception should have been thrown");
181        } catch (ArithmeticException ae) {
182            // expected behavior
183        } catch (Exception e) {
184            fail("wrong exception caught: " + e.getMessage());
185        }
186      }
187    
188      public void testOrthogonal() {
189          Vector3D v1 = new Vector3D(0.1, 2.5, 1.3);
190          assertEquals(0.0, Vector3D.dotProduct(v1, v1.orthogonal()), 1.0e-12);
191          Vector3D v2 = new Vector3D(2.3, -0.003, 7.6);
192          assertEquals(0.0, Vector3D.dotProduct(v2, v2.orthogonal()), 1.0e-12);
193          Vector3D v3 = new Vector3D(-1.7, 1.4, 0.2);
194          assertEquals(0.0, Vector3D.dotProduct(v3, v3.orthogonal()), 1.0e-12);
195          try {
196              new Vector3D(0, 0, 0).orthogonal();
197              fail("an exception should have been thrown");
198          } catch (ArithmeticException ae) {
199              // expected behavior
200          } catch (Exception e) {
201              fail("wrong exception caught: " + e.getMessage());
202          }
203      }
204    
205      public void testAngle() {
206         assertEquals(0.22572612855273393616, 
207                      Vector3D.angle(new Vector3D(1, 2, 3), new Vector3D(4, 5, 6)),
208                      1.0e-12);
209         assertEquals(7.98595620686106654517199e-8, 
210                      Vector3D.angle(new Vector3D(1, 2, 3), new Vector3D(2, 4, 6.000001)),
211                      1.0e-12);
212         assertEquals(3.14159257373023116985197793156, 
213                      Vector3D.angle(new Vector3D(1, 2, 3), new Vector3D(-2, -4, -6.000001)),
214                      1.0e-12);
215         try {
216             Vector3D.angle(Vector3D.ZERO, Vector3D.PLUS_I);
217             fail("an exception should have been thrown");
218         } catch (ArithmeticException ae) {
219             // expected behavior
220         } catch (Exception e) {
221             fail("wrong exception caught: " + e.getMessage());
222         }
223      }
224    
225      private void checkVector(Vector3D v, double x, double y, double z) {
226          assertEquals(x, v.getX(), 1.0e-12);
227          assertEquals(y, v.getY(), 1.0e-12);
228          assertEquals(z, v.getZ(), 1.0e-12);
229      }
230      
231      public static Test suite() {
232        return new TestSuite(Vector3DTest.class);
233      }
234    
235    }