1 package org.djutils.base;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertTrue;
6
7 import org.junit.Test;
8
9
10
11
12
13
14
15
16
17
18
19 public class AngleUtilTest
20 {
21
22
23
24 @Test
25 public void testAngleNormalization()
26 {
27 final double pi = Math.PI;
28 final double pi05 = 0.5 * pi;
29 final double pi15 = 1.5 * pi;
30 final double pi20 = 2.0 * pi;
31 final double pi100 = 10.0 * pi;
32
33
34 assertEquals(pi, AngleUtil.normalizeAroundPi(pi), 1E-6);
35 assertEquals(0.0, AngleUtil.normalizeAroundZero(0.0), 1E-6);
36
37 assertEquals(pi, AngleUtil.normalizeAroundPi(pi + pi20), 1E-6);
38 assertEquals(0.0, AngleUtil.normalizeAroundZero(0.0 + pi20), 1E-6);
39 assertEquals(pi, AngleUtil.normalizeAroundPi(pi - pi20), 1E-6);
40 assertEquals(0.0, AngleUtil.normalizeAroundZero(0.0 - pi20), 1E-6);
41
42 assertEquals(pi, AngleUtil.normalizeAroundPi(pi + pi100), 1E-6);
43 assertEquals(0.0, AngleUtil.normalizeAroundZero(0.0 + pi100), 1E-6);
44 assertEquals(pi, AngleUtil.normalizeAroundPi(pi - pi100), 1E-6);
45 assertEquals(0.0, AngleUtil.normalizeAroundZero(0.0 - pi100), 1E-6);
46
47
48 assertEquals(pi05, AngleUtil.normalizeAroundPi(pi05), 1E-6);
49 assertEquals(pi15, AngleUtil.normalizeAroundPi(pi15), 1E-6);
50 assertEquals(pi05, AngleUtil.normalizeAroundZero(pi05), 1E-6);
51 assertEquals(-pi05, AngleUtil.normalizeAroundZero(-pi05), 1E-6);
52 assertEquals(pi05, AngleUtil.normalizeAroundZero(-pi15), 1E-6);
53 assertEquals(-pi05, AngleUtil.normalizeAroundZero(pi15), 1E-6);
54
55 assertEquals(pi05, AngleUtil.normalizeAroundPi(pi05 + pi20), 1E-6);
56 assertEquals(pi05, AngleUtil.normalizeAroundPi(pi05 - pi20), 1E-6);
57 assertEquals(pi15, AngleUtil.normalizeAroundPi(pi15 + pi20), 1E-6);
58 assertEquals(pi15, AngleUtil.normalizeAroundPi(pi15 - pi20), 1E-6);
59 assertEquals(pi05, AngleUtil.normalizeAroundZero(pi05 + pi20), 1E-6);
60 assertEquals(pi05, AngleUtil.normalizeAroundZero(pi05 - pi20), 1E-6);
61 assertEquals(-pi05, AngleUtil.normalizeAroundZero(pi20 - pi05), 1E-6);
62 assertEquals(-pi05, AngleUtil.normalizeAroundZero(-pi20 - pi05), 1E-6);
63
64 assertEquals(pi05, AngleUtil.normalizeAroundPi(pi05 + pi100), 1E-6);
65 assertEquals(pi05, AngleUtil.normalizeAroundPi(pi05 - pi100), 1E-6);
66 assertEquals(pi15, AngleUtil.normalizeAroundPi(pi15 + pi100), 1E-6);
67 assertEquals(pi15, AngleUtil.normalizeAroundPi(pi15 - pi100), 1E-6);
68 assertEquals(pi05, AngleUtil.normalizeAroundZero(pi05 + pi100), 1E-6);
69 assertEquals(pi05, AngleUtil.normalizeAroundZero(pi05 - pi100), 1E-6);
70 assertEquals(-pi05, AngleUtil.normalizeAroundZero(pi100 - pi05), 1E-6);
71 assertEquals(-pi05, AngleUtil.normalizeAroundZero(-pi100 - pi05), 1E-6);
72
73
74 final double eps = 1E-8;
75 assertEquals(pi, AngleUtil.normalizeAroundZero(pi - eps), 1E-6);
76 assertEquals(-pi, AngleUtil.normalizeAroundZero(pi + eps), 1E-6);
77 assertEquals(-pi, AngleUtil.normalizeAroundZero(-pi + eps), 1E-6);
78 assertEquals(pi, AngleUtil.normalizeAroundZero(-pi - eps), 1E-6);
79
80 assertEquals(0.0, AngleUtil.normalizeAroundPi(eps), 1E-6);
81 assertEquals(pi20, AngleUtil.normalizeAroundPi(-eps), 1E-6);
82 assertEquals(pi20, AngleUtil.normalizeAroundPi(pi20 - eps), 1E-6);
83 assertEquals(0.0, AngleUtil.normalizeAroundPi(pi20 + eps), 1E-6);
84
85
86 assertTrue(Double.isNaN(AngleUtil.normalizeAroundPi(Double.NaN)));
87 assertTrue(Double.isNaN(AngleUtil.normalizeAroundZero(Double.NaN)));
88 assertTrue(Double.isNaN(AngleUtil.normalizeAroundPi(Double.POSITIVE_INFINITY)));
89 assertTrue(Double.isNaN(AngleUtil.normalizeAroundZero(Double.POSITIVE_INFINITY)));
90 assertTrue(Double.isNaN(AngleUtil.normalizeAroundPi(Double.NEGATIVE_INFINITY)));
91 assertTrue(Double.isNaN(AngleUtil.normalizeAroundZero(Double.NEGATIVE_INFINITY)));
92 }
93
94
95
96
97 @Test
98 public void testAngleEpsilonEquals()
99 {
100 final double pi = Math.PI;
101 final double pi05 = 0.5 * pi;
102 final double pi15 = 1.5 * pi;
103 final double pi20 = 2.0 * pi;
104
105 assertTrue(AngleUtil.epsilonEquals(pi, 3, 0.2));
106 assertTrue(AngleUtil.epsilonEquals(pi, 3.14, 0.01));
107 assertFalse(AngleUtil.epsilonEquals(pi, 3.14, 0.001));
108 assertTrue(AngleUtil.epsilonEquals(3, pi, 0.2));
109 assertTrue(AngleUtil.epsilonEquals(3.14, pi, 0.01));
110 assertFalse(AngleUtil.epsilonEquals(3.14, pi, 0.001));
111
112 assertTrue(AngleUtil.epsilonEquals(pi, -pi, 1E-6));
113 assertTrue(AngleUtil.epsilonEquals(0.0, pi20, 1E-6));
114 assertTrue(AngleUtil.epsilonEquals(-pi20, 5.0 * pi20, 1E-6));
115 assertFalse(AngleUtil.epsilonEquals(pi05, pi15, 1E-6));
116 assertTrue(AngleUtil.epsilonEquals(pi - 1E-7, pi + 1E-7, 1E-6));
117 assertTrue(AngleUtil.epsilonEquals(pi20 - 1E-7, pi20 + 1E-7, 1E-6));
118 for (double s1 : new double[] {-1E-7, 0.0, 1E-7})
119 {
120 for (double s2 : new double[] {-1E-7, 0.0, 1E-7})
121 {
122 assertTrue(AngleUtil.epsilonEquals(s1, pi20 + s2, 1E-6));
123 assertTrue(AngleUtil.epsilonEquals(s1, -pi20 + s2, 1E-6));
124 assertTrue(AngleUtil.epsilonEquals(-pi + s1, pi + s2, 1E-6));
125 for (double a : new double[] {0.0, pi05, pi15, pi20})
126 {
127 assertTrue(AngleUtil.epsilonEquals(a + s1, a + s2, 1E-6));
128 }
129 }
130 }
131 }
132
133
134
135
136 @Test
137 public void testAngleInterpolate()
138 {
139 assertEquals(0.1, AngleUtil.interpolateClockwise(0.1, 0.2, 0.0), 1E-6);
140 assertEquals(0.2, AngleUtil.interpolateClockwise(0.1, 0.2, 1.0), 1E-6);
141 assertEquals(0.15, AngleUtil.interpolateClockwise(0.1, 0.2, 0.5), 1E-6);
142 assertEquals(0.3, AngleUtil.interpolateClockwise(0.1, 0.2, 2.0), 1E-6);
143 assertEquals(0.05, AngleUtil.interpolateClockwise(0.1, 0.2, -0.5), 1E-6);
144
145 assertEquals(0.1, AngleUtil.interpolateClockwise(0.1, 0.1, 0.0), 1E-6);
146 assertEquals(0.1, AngleUtil.interpolateClockwise(0.1, 0.1, 1.0), 1E-6);
147 assertEquals(0.1, AngleUtil.interpolateClockwise(0.1, 0.1, -1.0), 1E-6);
148 assertEquals(0.1, AngleUtil.interpolateClockwise(0.1, 0.1, 10.0), 1E-6);
149
150 final double pi = Math.PI;
151 final double pi05 = 0.5 * pi;
152 final double pi15 = 1.5 * pi;
153 final double pi20 = 2.0 * pi;
154
155 assertEquals(0.0, AngleUtil.interpolateClockwise(0, pi20, 0.0), 1E-6);
156 assertEquals(0.0, AngleUtil.interpolateClockwise(0, pi20, 1.0), 1E-6);
157 assertEquals(0.0, AngleUtil.interpolateClockwise(0, pi20, 0.5), 1E-6);
158 assertEquals(0.0, AngleUtil.interpolateClockwise(pi20, 0, 0.5), 1E-6);
159 assertEquals(pi, Math.abs(AngleUtil.interpolateClockwise(-pi, pi, 0.5)), 1E-6);
160 assertEquals(pi, Math.abs(AngleUtil.interpolateClockwise(pi, -pi, 0.5)), 1E-6);
161
162 assertEquals(pi, Math.abs(AngleUtil.interpolateClockwise(pi05, pi15, 0.5)), 1E-6);
163 assertEquals(0.0, AngleUtil.interpolateClockwise(pi15, pi05, 0.5), 1E-6);
164
165 assertEquals(pi / 4, AngleUtil.interpolateClockwise(0.0, pi05, 0.5), 1E-6);
166 assertEquals(-0.75 * pi, AngleUtil.interpolateClockwise(pi05, 0.0, 0.5), 1E-6);
167 }
168
169
170
171
172 @Test
173 public void testInterpolateShortest()
174 {
175 for (double angle1 = -15 * Math.PI / 6; angle1 < 50; angle1 += Math.PI / 300)
176 {
177 for (double angle2 = -15 * Math.PI / 6; angle2 < 50; angle2 += Math.PI / 300)
178 {
179 for (double fraction : new double[] {0, 1, 0.5, 0.1, 0.9})
180 {
181 double angleFraction = AngleUtil.interpolateShortest(angle1, angle2, fraction);
182 double check1 = Math.abs(AngleUtil.normalizeAroundZero(angle1 - angleFraction));
183 double check2 = Math.abs(AngleUtil.normalizeAroundZero(angleFraction - angle2));
184
185
186
187
188
189 if (check1 > Math.PI * fraction)
190 {
191 AngleUtil.interpolateShortest(angle1, angle2, fraction);
192 }
193 assertTrue("diff of normalized is less than Pi * fraction", check1 <= Math.PI * fraction + 0.000001);
194 assertTrue("diff of normalized complement is less than 2*Pi/3",
195 check2 <= Math.PI * (1 - fraction) + 0.000001);
196 if (angle1 != angle2)
197 {
198 if (Math.abs(check1) > 0.00001 && Math.abs(check2) > 0.00001)
199 {
200 assertEquals("angle should be divided in parts with ratio fraction", fraction / (1 - fraction),
201 check1 / check2, 0.0001);
202 }
203 }
204 else
205 {
206 assertEquals("if angles are identical; both parts are zero ", 0, check1, 1e-10);
207 assertEquals("if angles are identical; both parts are zero ", 0, check2, 1e-10);
208 }
209 }
210 }
211 }
212
213 assertEquals("extrapolate at 2 of 0.2, 0.3", 0.4, AngleUtil.interpolateShortest(0.2, 0.3, 2), 0.00001);
214 assertEquals("extrapolate at 01 of 0.2, 0.3", 0.1, AngleUtil.interpolateShortest(0.2, 0.3, -1), 0.00001);
215 }
216
217
218
219
220
221
222 public static String printAngle(final double angle)
223 {
224 return String.format("%9.6f (%4.0f\u00b0)", angle, Math.toDegrees(angle));
225 }
226
227 }