You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
7.3 KiB
204 lines
7.3 KiB
/*
|
|
* Copyright 2006 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.common.geometry;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import junit.framework.Assert;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Tests for {@link S2Polyline}.
|
|
*
|
|
*/
|
|
public strictfp class S2PolylineTest extends GeometryTestCase {
|
|
|
|
@Override
|
|
public void setUp() {
|
|
super.setUp();
|
|
}
|
|
|
|
public void testBasic() {
|
|
List<S2Point> vertices = Lists.newArrayList();
|
|
S2Polyline empty = new S2Polyline(vertices);
|
|
assertEquals(empty.getRectBound(), S2LatLngRect.empty());
|
|
}
|
|
|
|
public void testGetLengthCentroid() {
|
|
// Construct random great circles and divide them randomly into segments.
|
|
// Then make sure that the length and centroid are correct. Note that
|
|
// because of the way the centroid is computed, it does not matter how
|
|
// we split the great circle into segments.
|
|
|
|
for (int i = 0; i < 100; ++i) {
|
|
// Choose a coordinate frame for the great circle.
|
|
S2Point x = randomPoint();
|
|
S2Point y = S2Point.normalize(S2Point.crossProd(x, randomPoint()));
|
|
S2Point z = S2Point.normalize(S2Point.crossProd(x, y));
|
|
|
|
List<S2Point> vertices = Lists.newArrayList();
|
|
for (double theta = 0; theta < 2 * S2.M_PI; theta += Math.pow(rand.nextDouble(), 10)) {
|
|
S2Point p = S2Point.add(S2Point.mul(x, Math.cos(theta)), S2Point.mul(y, Math.sin(theta)));
|
|
if (vertices.isEmpty() || !p.equals(vertices.get(vertices.size() - 1))) {
|
|
vertices.add(p);
|
|
}
|
|
}
|
|
// Close the circle.
|
|
vertices.add(vertices.get(0));
|
|
S2Polyline line = new S2Polyline(vertices);
|
|
S1Angle length = line.getArclengthAngle();
|
|
assertTrue(Math.abs(length.radians() - 2 * S2.M_PI) < 2e-14);
|
|
}
|
|
}
|
|
|
|
public void testMayIntersect() {
|
|
List<S2Point> vertices = Lists.newArrayList();
|
|
vertices.add(S2Point.normalize(new S2Point(1, -1.1, 0.8)));
|
|
vertices.add(S2Point.normalize(new S2Point(1, -0.8, 1.1)));
|
|
S2Polyline line = new S2Polyline(vertices);
|
|
for (int face = 0; face < 6; ++face) {
|
|
S2Cell cell = S2Cell.fromFacePosLevel(face, (byte) 0, 0);
|
|
assertEquals(line.mayIntersect(cell), (face & 1) == 0);
|
|
}
|
|
}
|
|
|
|
public void testInterpolate() {
|
|
List<S2Point> vertices = Lists.newArrayList();
|
|
vertices.add(new S2Point(1, 0, 0));
|
|
vertices.add(new S2Point(0, 1, 0));
|
|
vertices.add(S2Point.normalize(new S2Point(0, 1, 1)));
|
|
vertices.add(new S2Point(0, 0, 1));
|
|
S2Polyline line = new S2Polyline(vertices);
|
|
|
|
assertEquals(line.interpolate(-0.1), vertices.get(0));
|
|
assertTrue(S2.approxEquals(
|
|
line.interpolate(0.1), S2Point.normalize(new S2Point(1, Math.tan(0.2 * S2.M_PI / 2), 0))));
|
|
assertTrue(S2.approxEquals(line.interpolate(0.25), S2Point.normalize(new S2Point(1, 1, 0))));
|
|
|
|
assertEquals(line.interpolate(0.5), vertices.get(1));
|
|
assertEquals(line.interpolate(0.75), vertices.get(2));
|
|
assertEquals(line.interpolate(1.1), vertices.get(3));
|
|
}
|
|
|
|
public void testEqualsAndHashCode() {
|
|
List<S2Point> vertices = Lists.newArrayList();
|
|
vertices.add(new S2Point(1, 0, 0));
|
|
vertices.add(new S2Point(0, 1, 0));
|
|
vertices.add(S2Point.normalize(new S2Point(0, 1, 1)));
|
|
vertices.add(new S2Point(0, 0, 1));
|
|
|
|
|
|
S2Polyline line1 = new S2Polyline(vertices);
|
|
S2Polyline line2 = new S2Polyline(vertices);
|
|
|
|
checkEqualsAndHashCodeMethods(line1, line2, true);
|
|
|
|
List<S2Point> moreVertices = Lists.newLinkedList(vertices);
|
|
moreVertices.remove(0);
|
|
|
|
S2Polyline line3 = new S2Polyline(moreVertices);
|
|
|
|
checkEqualsAndHashCodeMethods(line1, line3, false);
|
|
checkEqualsAndHashCodeMethods(line1, null, false);
|
|
checkEqualsAndHashCodeMethods(line1, "", false);
|
|
}
|
|
|
|
public void testProject() {
|
|
List<S2Point> latLngs = Lists.newArrayList();
|
|
latLngs.add(S2LatLng.fromDegrees(0, 0).toPoint());
|
|
latLngs.add(S2LatLng.fromDegrees(0, 1).toPoint());
|
|
latLngs.add(S2LatLng.fromDegrees(0, 2).toPoint());
|
|
latLngs.add(S2LatLng.fromDegrees(1, 2).toPoint());
|
|
S2Polyline line = new S2Polyline(latLngs);
|
|
|
|
int edgeIndex = -1;
|
|
S2Point testPoint = null;
|
|
|
|
testPoint = S2LatLng.fromDegrees(0.5, -0.5).toPoint();
|
|
edgeIndex = line.getNearestEdgeIndex(testPoint);
|
|
assertTrue(S2.approxEquals(
|
|
line.projectToEdge(testPoint, edgeIndex), S2LatLng.fromDegrees(0, 0).toPoint()));
|
|
assertEquals(0, edgeIndex);
|
|
|
|
testPoint = S2LatLng.fromDegrees(0.5, 0.5).toPoint();
|
|
edgeIndex = line.getNearestEdgeIndex(testPoint);
|
|
assertTrue(S2.approxEquals(
|
|
line.projectToEdge(testPoint, edgeIndex), S2LatLng.fromDegrees(0, 0.5).toPoint()));
|
|
assertEquals(0, edgeIndex);
|
|
|
|
testPoint = S2LatLng.fromDegrees(0.5, 1).toPoint();
|
|
edgeIndex = line.getNearestEdgeIndex(testPoint);
|
|
assertTrue(S2.approxEquals(
|
|
line.projectToEdge(testPoint, edgeIndex), S2LatLng.fromDegrees(0, 1).toPoint()));
|
|
assertEquals(0, edgeIndex);
|
|
|
|
testPoint = S2LatLng.fromDegrees(-0.5, 2.5).toPoint();
|
|
edgeIndex = line.getNearestEdgeIndex(testPoint);
|
|
assertTrue(S2.approxEquals(
|
|
line.projectToEdge(testPoint, edgeIndex), S2LatLng.fromDegrees(0, 2).toPoint()));
|
|
assertEquals(1, edgeIndex);
|
|
|
|
testPoint = S2LatLng.fromDegrees(2, 2).toPoint();
|
|
edgeIndex = line.getNearestEdgeIndex(testPoint);
|
|
assertTrue(S2.approxEquals(
|
|
line.projectToEdge(testPoint, edgeIndex), S2LatLng.fromDegrees(1, 2).toPoint()));
|
|
assertEquals(2, edgeIndex);
|
|
}
|
|
|
|
/**
|
|
* Utility for testing equals() and hashCode() results at once.
|
|
* Tests that lhs.equals(rhs) matches expectedResult, as well as
|
|
* rhs.equals(lhs). Also tests that hashCode() return values are
|
|
* equal if expectedResult is true. (hashCode() is not tested if
|
|
* expectedResult is false, as unequal objects can have equal hashCodes.)
|
|
*
|
|
* @param lhs An Object for which equals() and hashCode() are to be tested.
|
|
* @param rhs As lhs.
|
|
* @param expectedResult True if the objects should compare equal,
|
|
* false if not.
|
|
*/
|
|
private static void checkEqualsAndHashCodeMethods(Object lhs, Object rhs,
|
|
boolean expectedResult) {
|
|
if ((lhs == null) && (rhs == null)) {
|
|
Assert.assertTrue(
|
|
"Your check is dubious...why would you expect null != null?",
|
|
expectedResult);
|
|
return;
|
|
}
|
|
|
|
if ((lhs == null) || (rhs == null)) {
|
|
Assert.assertFalse(
|
|
"Your check is dubious...why would you expect an object "
|
|
+ "to be equal to null?", expectedResult);
|
|
}
|
|
|
|
if (lhs != null) {
|
|
assertEquals(expectedResult, lhs.equals(rhs));
|
|
}
|
|
if (rhs != null) {
|
|
assertEquals(expectedResult, rhs.equals(lhs));
|
|
}
|
|
|
|
if (expectedResult) {
|
|
String hashMessage =
|
|
"hashCode() values for equal objects should be the same";
|
|
Assert.assertTrue(hashMessage, lhs.hashCode() == rhs.hashCode());
|
|
}
|
|
}
|
|
}
|