1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.math.geometry;
19  
20  import org.apache.commons.math.geometry.Vector3D;
21  
22  import junit.framework.*;
23  
24  public class Vector3DTest
25    extends TestCase {
26  
27    public Vector3DTest(String name) {
28      super(name);
29    }
30  
31    public void testConstructors() {
32        double r = Math.sqrt(2) /2;
33        checkVector(new Vector3D(2, new Vector3D(Math.PI / 3, -Math.PI / 4)),
34                    r, r * Math.sqrt(3), -2 * r);
35        checkVector(new Vector3D(2, Vector3D.PLUS_I,
36                                -3, Vector3D.MINUS_K),
37                    2, 0, 3);
38        checkVector(new Vector3D(2, Vector3D.PLUS_I,
39                                 5, Vector3D.PLUS_J,
40                                -3, Vector3D.MINUS_K),
41                    2, 5, 3);
42        checkVector(new Vector3D(2, Vector3D.PLUS_I,
43                                 5, Vector3D.PLUS_J,
44                                 5, Vector3D.MINUS_J,
45                                 -3, Vector3D.MINUS_K),
46                    2, 0, 3);
47    }
48  
49    public void testCoordinates() {
50      Vector3D v = new Vector3D(1, 2, 3);
51      assertTrue(Math.abs(v.getX() - 1) < 1.0e-12);
52      assertTrue(Math.abs(v.getY() - 2) < 1.0e-12);
53      assertTrue(Math.abs(v.getZ() - 3) < 1.0e-12);
54    }
55    
56    public void testNorm1() {
57      assertEquals(0.0, Vector3D.ZERO.getNorm1());
58      assertEquals(6.0, new Vector3D(1, -2, 3).getNorm1(), 0);
59    }
60  
61    public void testNorm() {
62        assertEquals(0.0, Vector3D.ZERO.getNorm());
63        assertEquals(Math.sqrt(14), new Vector3D(1, 2, 3).getNorm(), 1.0e-12);
64      }
65  
66    public void testNormInf() {
67        assertEquals(0.0, Vector3D.ZERO.getNormInf());
68        assertEquals(3.0, new Vector3D(1, -2, 3).getNormInf(), 0);
69      }
70  
71    public void testDistance1() {
72        Vector3D v1 = new Vector3D(1, -2, 3);
73        Vector3D v2 = new Vector3D(-4, 2, 0);
74        assertEquals(0.0, Vector3D.distance1(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
75        assertEquals(12.0, Vector3D.distance1(v1, v2), 1.0e-12);
76        assertEquals(v1.subtract(v2).getNorm1(), Vector3D.distance1(v1, v2), 1.0e-12);
77    }
78  
79    public void testDistance() {
80        Vector3D v1 = new Vector3D(1, -2, 3);
81        Vector3D v2 = new Vector3D(-4, 2, 0);
82        assertEquals(0.0, Vector3D.distance(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
83        assertEquals(Math.sqrt(50), Vector3D.distance(v1, v2), 1.0e-12);
84        assertEquals(v1.subtract(v2).getNorm(), Vector3D.distance(v1, v2), 1.0e-12);
85    }
86  
87    public void testDistanceSq() {
88        Vector3D v1 = new Vector3D(1, -2, 3);
89        Vector3D v2 = new Vector3D(-4, 2, 0);
90        assertEquals(0.0, Vector3D.distanceSq(Vector3D.MINUS_I, Vector3D.MINUS_I), 0);
91        assertEquals(50.0, Vector3D.distanceSq(v1, v2), 1.0e-12);
92        assertEquals(Vector3D.distance(v1, v2) * Vector3D.distance(v1, v2),
93                     Vector3D.distanceSq(v1, v2), 1.0e-12);
94    }
95  
96    public void testDistanceInf() {
97        Vector3D v1 = new Vector3D(1, -2, 3);
98        Vector3D v2 = new Vector3D(-4, 2, 0);
99        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 }