// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.android.stardroid.test.util;
import com.google.android.stardroid.test.units.Matrix33Test;
import com.google.android.stardroid.units.GeocentricCoordinates;
import com.google.android.stardroid.units.Matrix33;
import com.google.android.stardroid.units.RaDec;
import com.google.android.stardroid.units.Vector3;
import com.google.android.stardroid.util.Geometry;
import junit.framework.TestCase;
public class GeometryTest extends TestCase {
private final double TOL = 0.00001;
public void assertVectorsEqual(Vector3 v, Vector3 w) {
assertEquals(v.x, w.x, TOL);
assertEquals(v.y, w.y, TOL);
assertEquals(v.z, w.z, TOL);
}
private void assertMatrixSame(Matrix33 m1, Matrix33 m2, double tol) {
assertEquals(m1.xx, m2.xx, tol);
assertEquals(m1.xy, m2.xy, tol);
assertEquals(m1.xz, m2.xz, tol);
assertEquals(m1.yx, m2.yx, tol);
assertEquals(m1.yy, m2.yy, tol);
assertEquals(m1.yz, m2.yz, tol);
assertEquals(m1.zx, m2.zx, tol);
assertEquals(m1.zy, m2.zy, tol);
assertEquals(m1.zz, m2.zz, tol);
}
private float[][] allTestValues = { {0, 0, 1, 0, 0},
{90, 0, 0, 1, 0},
{0, 90, 0, 0, 1},
{180, 0, -1, 0, 0},
{0, -90, 0, 0, -1},
{270, 0, 0, -1, 0} };
public void testSphericalToCartesians() {
for (float[] testValues : allTestValues) {
float ra = testValues[0];
float dec = testValues[1];
float x = testValues[2];
float y = testValues[3];
float z = testValues[4];
GeocentricCoordinates result = Geometry.getXYZ(new RaDec(ra, dec));
assertEquals(x, result.x, TOL);
assertEquals(y, result.y, TOL);
assertEquals(z, result.z, TOL);
}
}
public void testCartesiansToSphericals() {
for (float[] testValues : allTestValues) {
float ra = testValues[0];
float dec = testValues[1];
float x = testValues[2];
float y = testValues[3];
float z = testValues[4];
RaDec result =
RaDec.getInstance(new GeocentricCoordinates(x, y, z));
assertEquals(ra, result.ra, TOL);
assertEquals(dec, result.dec, TOL);
}
}
public void testVectorProduct() {
// Check that z is x X y
Vector3 x = new Vector3(1, 0, 0);
Vector3 y = new Vector3(0, 1, 0);
Vector3 z = Geometry.vectorProduct(x, y);
assertVectorsEqual(z, new Vector3(0, 0, 1));
// Check that a X b is perpendicular to a and b
Vector3 a = new Vector3(1, -2, 3);
Vector3 b = new Vector3(2, 0, -4);
Vector3 c = Geometry.vectorProduct(a, b);
double aDotc = Geometry.scalarProduct(a, c);
double bDotc = Geometry.scalarProduct(b, c);
assertEquals(0, aDotc, TOL);
assertEquals(0, bDotc, TOL);
// Check that |a X b| is correct
Vector3 v= new Vector3(1, 2, 0);
Vector3 ww = Geometry.vectorProduct(x, v);
float wwDotww = Geometry.scalarProduct(ww, ww);
assertEquals(Math.pow(1f * Math.sqrt(5) * Math.sin(Math.atan(2)),2),
wwDotww, TOL);
}
public void testMatrixInversion() {
Matrix33 m = new Matrix33 (1, 2, 0, 0, 1, 5, 0, 0, 1);
System.out.println(GeometryTest.formatMatrix(m));
Matrix33 inv = m.getInverse();
System.out.println(GeometryTest.formatMatrix(inv));
Matrix33 product = Geometry.matrixMultiply(m, inv);
System.out.println(GeometryTest.formatMatrix(product));
}
public void testCalculateRotationMatrix() {
Matrix33 noRotation = Geometry.calculateRotationMatrix(0, new Vector3(1, 2, 3));
Matrix33 identity = new Matrix33(1, 0, 0, 0, 1, 0, 0, 0, 1);
assertMatrixSame(identity, noRotation, TOL);
Matrix33 rotAboutZ = Geometry.calculateRotationMatrix(90, new Vector3(0, 0, 1));
assertMatrixSame(new Matrix33(0, 1, 0, -1, 0, 0, 0, 0, 1), rotAboutZ, TOL);
Vector3 axis = new Vector3(2, -4, 1);
axis.normalize();
Matrix33 rotA = Geometry.calculateRotationMatrix(30, axis);
Matrix33 rotB = Geometry.calculateRotationMatrix(-30, axis);
Matrix33 shouldBeIdentity = Geometry.matrixMultiply(rotA, rotB);
assertMatrixSame(identity, shouldBeIdentity, TOL);
Vector3 axisPerpendicular = new Vector3(4, 2, 0);
Vector3 rotatedAxisPerpendicular = Geometry.matrixVectorMultiply(rotA, axisPerpendicular);
// Should still be perpendicular
assertEquals(0, Geometry.scalarProduct(axis, rotatedAxisPerpendicular), TOL);
// And the angle between them should be 30 degrees
axisPerpendicular.normalize();
rotatedAxisPerpendicular.normalize();
assertEquals(Math.cos(30.0 * Geometry.DEGREES_TO_RADIANS),
Geometry.scalarProduct(axisPerpendicular, rotatedAxisPerpendicular),
TOL);
}
public void testMatrixMultiply() {
Matrix33 m1 = new Matrix33(1, 2, 4, -1, -3, 5, 3, 2, 6);
Matrix33 m2 = new Matrix33(3, -1, 4, 0, 2, 1, 2, -1, 2);
Vector3 v1 = new Vector3(0, -1, 2);
Vector3 v2 = new Vector3(2, -2, 3);
Matrix33Test.assertMatricesEqual(
new Matrix33(11, -1, 14, 7, -10, 3, 21, -5, 26),
Geometry.matrixMultiply(m1, m2), (float) TOL);
assertVectorsEqual(new Vector3(6, 13, 10),
Geometry.matrixVectorMultiply(m1, v1));
assertVectorsEqual(new Vector3(10, 19, 20),
Geometry.matrixVectorMultiply(m1, v2));
}
public static String formatMatrix(Matrix33 m) {
return m.xx + " " + m.xy + " " + m.xz + " "
+ m.yx + " " + m.yy + " " + m.yz + " "
+ m.zx + " " + m.zy + " " + m.zz;
}
}