View Javadoc
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  package org.apache.commons.geometry.spherical.twod;
18  
19  import org.apache.commons.geometry.core.GeometryTestUtils;
20  import org.apache.commons.geometry.euclidean.threed.Vector3D;
21  import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
22  import org.apache.commons.geometry.spherical.SphericalTestUtils;
23  import org.apache.commons.numbers.angle.PlaneAngleRadians;
24  import org.junit.Assert;
25  import org.junit.Test;
26  
27  public class Transform2STest {
28  
29      private static final double TEST_EPS = 1e-10;
30  
31      @Test
32      public void testIdentity() {
33          // act
34          final Transform2S t = Transform2S.identity();
35  
36          // assert
37          Assert.assertTrue(t.preservesOrientation());
38          Assert.assertArrayEquals(new double[] {
39              1, 0, 0, 0,
40              0, 1, 0, 0,
41              0, 0, 1, 0
42          }, t.getEuclideanTransform().toArray(), 0);
43  
44          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_I, t.apply(Point2S.PLUS_I), TEST_EPS);
45          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, t.apply(Point2S.PLUS_J), TEST_EPS);
46          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_K, t.apply(Point2S.PLUS_K), TEST_EPS);
47  
48          checkInverse(t);
49      }
50  
51      @Test
52      public void testRotation() {
53          // arrange
54          final Transform2S aroundPole = Transform2S.createRotation(Point2S.PLUS_K, PlaneAngleRadians.PI_OVER_TWO);
55          final Transform2S aroundX = Transform2S.createRotation(Vector3D.Unit.PLUS_X, -PlaneAngleRadians.PI_OVER_TWO);
56          final Transform2S aroundY = Transform2S.createRotation(
57                  QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
58  
59          // act/assert
60          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, aroundPole.apply(Point2S.PLUS_I), TEST_EPS);
61          SphericalTestUtils.assertPointsEqual(Point2S.MINUS_I, aroundPole.apply(Point2S.PLUS_J), TEST_EPS);
62          SphericalTestUtils.assertPointsEq(Point2S.PLUS_K, aroundPole.apply(Point2S.PLUS_K), TEST_EPS);
63          checkInverse(aroundPole);
64  
65          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_I, aroundX.apply(Point2S.PLUS_I), TEST_EPS);
66          SphericalTestUtils.assertPointsEq(Point2S.MINUS_K, aroundX.apply(Point2S.PLUS_J), TEST_EPS);
67          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, aroundX.apply(Point2S.PLUS_K), TEST_EPS);
68          checkInverse(aroundX);
69  
70          SphericalTestUtils.assertPointsEq(Point2S.MINUS_K, aroundY.apply(Point2S.PLUS_I), TEST_EPS);
71          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, aroundY.apply(Point2S.PLUS_J), TEST_EPS);
72          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_I, aroundY.apply(Point2S.PLUS_K), TEST_EPS);
73          checkInverse(aroundY);
74      }
75  
76      @Test
77      public void testMultipleRotations() {
78          // act
79          final Transform2S t = Transform2S.identity()
80                  .rotate(Point2S.PLUS_K, PlaneAngleRadians.PI_OVER_TWO)
81                  .rotate(Vector3D.Unit.PLUS_X, -PlaneAngleRadians.PI_OVER_TWO)
82                  .rotate(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
83  
84          // assert
85          SphericalTestUtils.assertPointsEqual(Point2S.MINUS_I, t.apply(Point2S.PLUS_I), TEST_EPS);
86          SphericalTestUtils.assertPointsEq(Point2S.PLUS_K, t.apply(Point2S.PLUS_J), TEST_EPS);
87          SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, t.apply(Point2S.PLUS_K), TEST_EPS);
88  
89          checkInverse(t);
90      }
91  
92      @Test
93      public void testMultiply() {
94          // act
95          final Transform2S t = Transform2S.identity()
96                  .multiply(Transform2S.createRotation(Point2S.PLUS_K, PlaneAngleRadians.PI_OVER_TWO))
97                  .multiply(Transform2S.createRotation(Point2S.PLUS_J, PlaneAngleRadians.PI_OVER_TWO));
98  
99          // assert
100         SphericalTestUtils.assertPointsEq(Point2S.MINUS_K, t.apply(Point2S.PLUS_I), TEST_EPS);
101         SphericalTestUtils.assertPointsEqual(Point2S.MINUS_I, t.apply(Point2S.PLUS_J), TEST_EPS);
102         SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, t.apply(Point2S.PLUS_K), TEST_EPS);
103 
104         checkInverse(t);
105     }
106 
107     @Test
108     public void testPremultiply() {
109         // act
110         final Transform2S t = Transform2S.identity()
111                 .premultiply(Transform2S.createRotation(Point2S.PLUS_K, PlaneAngleRadians.PI_OVER_TWO))
112                 .premultiply(Transform2S.createRotation(Point2S.PLUS_J, PlaneAngleRadians.PI_OVER_TWO));
113 
114         // assert
115         SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, t.apply(Point2S.PLUS_I), TEST_EPS);
116         SphericalTestUtils.assertPointsEq(Point2S.PLUS_K, t.apply(Point2S.PLUS_J), TEST_EPS);
117         SphericalTestUtils.assertPointsEqual(Point2S.PLUS_I, t.apply(Point2S.PLUS_K), TEST_EPS);
118 
119         checkInverse(t);
120     }
121 
122     @Test
123     public void testReflection_point() {
124         // arrange
125         final Point2S a = Point2S.of(1, 1);
126         final Point2S b = Point2S.of(-1, 1);
127 
128         final Point2S c = Point2S.of(1, PlaneAngleRadians.PI - 1);
129         final Point2S d = Point2S.of(-1, PlaneAngleRadians.PI - 1);
130 
131         // act
132         final Transform2S t = Transform2S.createReflection(Point2S.PLUS_I);
133 
134         // assert
135         Assert.assertFalse(t.preservesOrientation());
136 
137         SphericalTestUtils.assertPointsEqual(Point2S.MINUS_I, t.apply(Point2S.PLUS_I), TEST_EPS);
138         SphericalTestUtils.assertPointsEqual(Point2S.PLUS_J, t.apply(Point2S.PLUS_J), TEST_EPS);
139         SphericalTestUtils.assertPointsEq(Point2S.PLUS_K, t.apply(Point2S.PLUS_K), TEST_EPS);
140 
141         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI - 1, 1), t.apply(a), TEST_EPS);
142         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI + 1, 1), t.apply(b), TEST_EPS);
143 
144         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI - 1, PlaneAngleRadians.PI - 1), t.apply(c), TEST_EPS);
145         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI + 1, PlaneAngleRadians.PI - 1), t.apply(d), TEST_EPS);
146 
147         checkInverse(t);
148     }
149 
150     @Test
151     public void testReflection_vector() {
152         // arrange
153         final Point2S a = Point2S.of(1, 1);
154         final Point2S b = Point2S.of(-1, 1);
155 
156         final Point2S c = Point2S.of(1, PlaneAngleRadians.PI - 1);
157         final Point2S d = Point2S.of(-1, PlaneAngleRadians.PI - 1);
158 
159         // act
160         final Transform2S t = Transform2S.createReflection(Vector3D.Unit.PLUS_Y);
161 
162         // assert
163         Assert.assertFalse(t.preservesOrientation());
164 
165         SphericalTestUtils.assertPointsEqual(Point2S.PLUS_I, t.apply(Point2S.PLUS_I), TEST_EPS);
166         SphericalTestUtils.assertPointsEqual(Point2S.MINUS_J, t.apply(Point2S.PLUS_J), TEST_EPS);
167         SphericalTestUtils.assertPointsEq(Point2S.PLUS_K, t.apply(Point2S.PLUS_K), TEST_EPS);
168 
169         SphericalTestUtils.assertPointsEqual(b, t.apply(a), TEST_EPS);
170         SphericalTestUtils.assertPointsEqual(a, t.apply(b), TEST_EPS);
171 
172         SphericalTestUtils.assertPointsEqual(d, t.apply(c), TEST_EPS);
173         SphericalTestUtils.assertPointsEqual(c, t.apply(d), TEST_EPS);
174 
175         checkInverse(t);
176     }
177 
178     @Test
179     public void testDoubleReflection() {
180         // arrange
181         final Point2S a = Point2S.of(1, 1);
182         final Point2S b = Point2S.of(-1, 1);
183 
184         final Point2S c = Point2S.of(1, PlaneAngleRadians.PI - 1);
185         final Point2S d = Point2S.of(-1, PlaneAngleRadians.PI - 1);
186 
187         // act
188         final Transform2S t = Transform2S.identity()
189                 .reflect(Point2S.PLUS_I)
190                 .reflect(Vector3D.Unit.PLUS_Y);
191 
192         // assert
193         Assert.assertTrue(t.preservesOrientation());
194 
195         SphericalTestUtils.assertPointsEqual(Point2S.MINUS_I, t.apply(Point2S.PLUS_I), TEST_EPS);
196         SphericalTestUtils.assertPointsEqual(Point2S.MINUS_J, t.apply(Point2S.PLUS_J), TEST_EPS);
197         SphericalTestUtils.assertPointsEq(Point2S.PLUS_K, t.apply(Point2S.PLUS_K), TEST_EPS);
198 
199         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI + 1, 1), t.apply(a), TEST_EPS);
200         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI - 1, 1), t.apply(b), TEST_EPS);
201 
202         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI + 1, PlaneAngleRadians.PI - 1), t.apply(c), TEST_EPS);
203         SphericalTestUtils.assertPointsEqual(Point2S.of(PlaneAngleRadians.PI - 1,  PlaneAngleRadians.PI - 1), t.apply(d), TEST_EPS);
204 
205         checkInverse(t);
206     }
207 
208     @Test
209     public void testHashcode() {
210         // arrange
211         final Transform2S a = Transform2S.createRotation(Point2S.PLUS_I, PlaneAngleRadians.PI_OVER_TWO);
212         final Transform2S b = Transform2S.createRotation(Point2S.PLUS_J, PlaneAngleRadians.PI_OVER_TWO);
213         final Transform2S c = Transform2S.createRotation(Point2S.PLUS_I, PlaneAngleRadians.PI);
214         final Transform2S d = Transform2S.createRotation(Point2S.PLUS_I, PlaneAngleRadians.PI_OVER_TWO);
215 
216         // act
217         final int hash = a.hashCode();
218 
219         // assert
220         Assert.assertEquals(hash, a.hashCode());
221 
222         Assert.assertNotEquals(hash, b.hashCode());
223         Assert.assertNotEquals(hash, c.hashCode());
224 
225         Assert.assertEquals(hash, d.hashCode());
226     }
227 
228     @Test
229     public void testEquals() {
230         // arrange
231         final Transform2S a = Transform2S.createRotation(Point2S.PLUS_I, PlaneAngleRadians.PI_OVER_TWO);
232         final Transform2S b = Transform2S.createRotation(Point2S.PLUS_J, PlaneAngleRadians.PI_OVER_TWO);
233         final Transform2S c = Transform2S.createRotation(Point2S.PLUS_I, PlaneAngleRadians.PI);
234         final Transform2S d = Transform2S.createRotation(Point2S.PLUS_I, PlaneAngleRadians.PI_OVER_TWO);
235 
236         // act/assert
237         Assert.assertEquals(a, a);
238 
239         Assert.assertFalse(a.equals(null));
240         Assert.assertFalse(a.equals(new Object()));
241 
242         Assert.assertNotEquals(a, b);
243         Assert.assertNotEquals(a, c);
244 
245         Assert.assertEquals(a, d);
246         Assert.assertEquals(d, a);
247     }
248 
249     @Test
250     public void testToString() {
251         // arrange
252         final Transform2S t = Transform2S.identity();
253 
254         // act
255         final String str = t.toString();
256 
257         // assert
258         GeometryTestUtils.assertContains("Transform2S", str);
259         GeometryTestUtils.assertContains("euclideanTransform= [", str);
260     }
261 
262     private static void checkInverse(final Transform2S t) {
263         final Transform2S inv = t.inverse();
264 
265         // test non-pole points
266         for (double az = -PlaneAngleRadians.TWO_PI; az <= 2 * PlaneAngleRadians.TWO_PI; az += 0.2) {
267             for (double p = 0.1; p < PlaneAngleRadians.PI; p += 0.2) {
268 
269                 final Point2S pt = Point2S.of(az, p);
270 
271                 SphericalTestUtils.assertPointsEqual(pt, inv.apply(t.apply(pt)), TEST_EPS);
272                 SphericalTestUtils.assertPointsEqual(pt, t.apply(inv.apply(pt)), TEST_EPS);
273             }
274         }
275 
276         // test poles
277         SphericalTestUtils.assertVectorsEqual(Vector3D.Unit.PLUS_Z,
278                 inv.apply(t.apply(Point2S.of(1, 0))).getVector(), TEST_EPS);
279         SphericalTestUtils.assertVectorsEqual(Vector3D.Unit.PLUS_Z,
280                 t.apply(inv.apply(Point2S.of(-1, 0))).getVector(), TEST_EPS);
281 
282         SphericalTestUtils.assertVectorsEqual(Vector3D.Unit.MINUS_Z,
283                 inv.apply(t.apply(Point2S.of(1, PlaneAngleRadians.PI))).getVector(), TEST_EPS);
284         SphericalTestUtils.assertVectorsEqual(Vector3D.Unit.MINUS_Z,
285                 t.apply(inv.apply(Point2S.of(-1, PlaneAngleRadians.PI))).getVector(), TEST_EPS);
286     }
287 }