1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server;
18 
19 import android.test.AndroidTestCase;
20 
21 import java.lang.Exception;
22 import java.lang.Math;
23 
24 /**
25  * Tests for {@link com.android.server.AnyMotionDetector.Vector3}
26  */
27 public class Vector3Test extends AndroidTestCase {
28     private static final float tolerance = 1.0f / (1 << 12);
29     private static final float STATIONARY_ANGLE_THRESHOLD = 0.05f;
30 
31     private AnyMotionDetector.Vector3 unitXAxis;
32     private AnyMotionDetector.Vector3 unitYAxis;
33     private AnyMotionDetector.Vector3 unitZAxis;
34     private AnyMotionDetector.Vector3 x3;
35     private AnyMotionDetector.Vector3 case1A;
36     private AnyMotionDetector.Vector3 case1B;
37     private AnyMotionDetector.Vector3 case2A;
38     private AnyMotionDetector.Vector3 case2B;
39     private AnyMotionDetector.Vector3 x1y1;
40     private AnyMotionDetector.Vector3 xn1y1;
41     private AnyMotionDetector.Vector3 x1z1;
42     private AnyMotionDetector.Vector3 y1z1;
43     private AnyMotionDetector.Vector3 piOverSixUnitCircle;
44 
45 
nearlyEqual(float a, float b)46     private boolean nearlyEqual(float a, float b) {
47         return Math.abs(a - b) <= tolerance;
48     }
49 
setUp()50     public void setUp() throws Exception {
51         super.setUp();
52         unitXAxis = new AnyMotionDetector.Vector3(0, 1, 0, 0);
53         unitYAxis = new AnyMotionDetector.Vector3(0, 0, 1, 0);
54         unitZAxis = new AnyMotionDetector.Vector3(0, 0, 0, 1);
55         x3 = new AnyMotionDetector.Vector3(0, 3, 0, 0);
56         x1y1 = new AnyMotionDetector.Vector3(0, 1, 1, 0);
57         xn1y1 = new AnyMotionDetector.Vector3(0, -1, 1, 0);
58         x1z1 = new AnyMotionDetector.Vector3(0, 1, 0, 1);
59         y1z1 = new AnyMotionDetector.Vector3(0, 0, 1, 1);
60         piOverSixUnitCircle = new AnyMotionDetector.Vector3(
61                 0, (float)Math.sqrt(3)/2, (float)0.5, 0);
62 
63         case1A = new AnyMotionDetector.Vector3(0, -9.81f, -0.02f, 0.3f);
64         case1B = new AnyMotionDetector.Vector3(0, -9.80f, -0.02f, 0.3f);
65         case2A = new AnyMotionDetector.Vector3(0, 1f, 2f, 3f);
66         case2B = new AnyMotionDetector.Vector3(0, 4f, 5f, 6f);
67     }
68 
testVector3Norm()69     public void testVector3Norm() {
70         assertTrue(nearlyEqual(unitXAxis.norm(), 1.0f));
71         assertTrue(nearlyEqual(unitYAxis.norm(), 1.0f));
72         assertTrue(nearlyEqual(unitZAxis.norm(), 1.0f));
73         assertTrue(nearlyEqual(x1y1.norm(), (float)Math.sqrt(2)));
74     }
75 
testVector3AngleBetween()76     public void testVector3AngleBetween() {
77         // Zero angle.
78         assertTrue(nearlyEqual(unitXAxis.angleBetween(unitXAxis), 0.0f));
79         assertTrue(nearlyEqual(unitYAxis.angleBetween(unitYAxis), 0.0f));
80         assertTrue(nearlyEqual(unitZAxis.angleBetween(unitZAxis), 0.0f));
81 
82         // Unit axes should be perpendicular.
83         assertTrue(nearlyEqual(unitXAxis.angleBetween(unitYAxis), 90.0f));
84         assertTrue(nearlyEqual(unitXAxis.angleBetween(unitZAxis), 90.0f));
85         assertTrue(nearlyEqual(unitYAxis.angleBetween(unitZAxis), 90.0f));
86 
87         // 45 degree angles.
88         assertTrue(nearlyEqual(unitXAxis.angleBetween(x1y1), 45.0f));
89         assertTrue(nearlyEqual(unitYAxis.angleBetween(x1y1), 45.0f));
90 
91         // 135 degree angles.
92         assertTrue(nearlyEqual(xn1y1.angleBetween(unitXAxis), 135.0f));
93 
94         // 30 degree angles.
95         assertTrue(nearlyEqual(piOverSixUnitCircle.angleBetween(unitXAxis), 30.0f));
96 
97         // These vectors are expected to be still.
98         assertTrue(case1A.angleBetween(case1A) < STATIONARY_ANGLE_THRESHOLD);
99         assertTrue(case1A.angleBetween(case1B) < STATIONARY_ANGLE_THRESHOLD);
100         assertTrue(unitXAxis.angleBetween(unitXAxis) < STATIONARY_ANGLE_THRESHOLD);
101         assertTrue(unitYAxis.angleBetween(unitYAxis) < STATIONARY_ANGLE_THRESHOLD);
102         assertTrue(unitZAxis.angleBetween(unitZAxis) < STATIONARY_ANGLE_THRESHOLD);
103     }
104 
105     public void testVector3Normalized() {
106         AnyMotionDetector.Vector3 unitXAxisNormalized = unitXAxis.normalized();
107         assertTrue(nearlyEqual(unitXAxisNormalized.x, unitXAxis.x));
108         assertTrue(nearlyEqual(unitXAxisNormalized.y, unitXAxis.y));
109         assertTrue(nearlyEqual(unitXAxisNormalized.z, unitXAxis.z));
110 
111         // Normalizing the vector created by multiplying the unit vector by 3 gets the unit vector.
112         AnyMotionDetector.Vector3 x3Normalized = x3.normalized();
113         assertTrue(nearlyEqual(x3Normalized.x, unitXAxis.x));
114         assertTrue(nearlyEqual(x3Normalized.y, unitXAxis.y));
115         assertTrue(nearlyEqual(x3Normalized.z, unitXAxis.z));
116     }
117 
118     public void testVector3Cross() {
119         AnyMotionDetector.Vector3 xCrossX = unitXAxis.cross(unitXAxis);
120         assertTrue(nearlyEqual(xCrossX.x, 0f));
121         assertTrue(nearlyEqual(xCrossX.y, 0f));
122         assertTrue(nearlyEqual(xCrossX.z, 0f));
123 
124         AnyMotionDetector.Vector3 xCrossNx = unitXAxis.cross(unitXAxis.times(-1));
125         assertTrue(nearlyEqual(xCrossNx.x, 0f));
126         assertTrue(nearlyEqual(xCrossNx.y, 0f));
127         assertTrue(nearlyEqual(xCrossNx.z, 0f));
128 
129         AnyMotionDetector.Vector3 cross2 = case2A.cross(case2B);
130         assertTrue(nearlyEqual(cross2.x, -3));
131         assertTrue(nearlyEqual(cross2.y, 6));
132         assertTrue(nearlyEqual(cross2.z, -3));
133     }
134 
135      public void testVector3Times() {
136          AnyMotionDetector.Vector3 yTimes2 = unitYAxis.times(2);
137          assertTrue(nearlyEqual(yTimes2.x, 0f));
138          assertTrue(nearlyEqual(yTimes2.y, 2f));
139          assertTrue(nearlyEqual(yTimes2.z, 0f));
140      }
141 
142      public void testVector3Plus() {
143          AnyMotionDetector.Vector3 xPlusY = unitXAxis.plus(unitYAxis);
144          assertTrue(nearlyEqual(xPlusY.x, 1f));
145          assertTrue(nearlyEqual(xPlusY.y, 1f));
146          assertTrue(nearlyEqual(xPlusY.z, 0f));
147      }
148 
149      public void testVector3Minus() {
150          AnyMotionDetector.Vector3 xMinusY = unitXAxis.minus(unitYAxis);
151          assertTrue(nearlyEqual(xMinusY.x, 1f));
152          assertTrue(nearlyEqual(xMinusY.y, -1f));
153          assertTrue(nearlyEqual(xMinusY.z, 0f));
154      }
155 
156      public void testVector3DotProduct() {
157          float xDotX = unitXAxis.dotProduct(unitXAxis);
158          float xDotY = unitXAxis.dotProduct(unitYAxis);
159          float xDotZ = unitXAxis.dotProduct(unitZAxis);
160          assertTrue(nearlyEqual(xDotX, 1f));
161          assertTrue(nearlyEqual(xDotY, 0f));
162          assertTrue(nearlyEqual(xDotZ, 0f));
163      }
164 }
165