blob: 4c7ba7d669ca6af66641fb911548ea1679d14126 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.lucene.document;
import org.apache.lucene.geo.Component2D;
import org.apache.lucene.geo.GeoUtils;
import org.apache.lucene.util.LuceneTestCase;
/** base shape encoding class for testing encoding of tessellated {@link org.apache.lucene.document.XYShape} and
* {@link LatLonShape}
*/
public abstract class BaseShapeEncodingTestCase extends LuceneTestCase {
protected abstract int encodeX(double x);
protected abstract double decodeX(int x);
protected abstract int encodeY(double y);
protected abstract double decodeY(int y);
protected abstract double nextX();
protected abstract double nextY();
protected abstract Object nextPolygon();
protected abstract Component2D createPolygon2D(Object polygon);
//One shared point with MBR -> MinY, MinX
public void testPolygonEncodingMinLatMinLon() {
double ay = 0.0;
double ax = 0.0;
double by = 1.0;
double blon = 2.0;
double cy = 2.0;
double cx = 1.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(blon);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//One shared point with MBR -> MinLat, MaxLon
public void testPolygonEncodingMinLatMaxLon() {
double ay = 1.0;
double ax = 0.0;
double by = 0.0;
double blon = 2.0;
double cy = 2.0;
double cx = 1.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(blon);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//One shared point with MBR -> MaxLat, MaxLon
public void testPolygonEncodingMaxLatMaxLon() {
double ay = 1.0;
double ax = 0.0;
double by = 2.0;
double blon = 2.0;
double cy = 0.0;
double cx = 1.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(cy);
int bxEnc = encodeX(cx);
int cyEnc = encodeY(by);
int cxEnc = encodeX(blon);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//One shared point with MBR -> MaxLat, MinLon
public void testPolygonEncodingMaxLatMinLon() {
double ay = 2.0;
double ax = 0.0;
double by = 1.0;
double blon = 2.0;
double cy = 0.0;
double cx = 1.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(cy);
int bxEnc = encodeX(cx);
int cyEnc = encodeY(by);
int cxEnc = encodeX(blon);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//Two shared point with MBR -> [MinLat, MinLon], [MaxLat, MaxLon], third point below
public void testPolygonEncodingMinLatMinLonMaxLatMaxLonBelow() {
double ay = 0.0;
double ax = 0.0;
double by = 0.25;
double blon = 0.75;
double cy = 2.0;
double cx = 2.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(blon);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//Two shared point with MBR -> [MinLat, MinLon], [MaxLat, MaxLon], third point above
public void testPolygonEncodingMinLatMinLonMaxLatMaxLonAbove() {
double ay = 0.0;
double ax = 0.0;
double by = 2.0;
double bx = 2.0;
double cy = 1.75;
double cx = 1.25;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(bx);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//Two shared point with MBR -> [MinLat, MaxLon], [MaxLat, MinLon], third point below
public void testPolygonEncodingMinLatMaxLonMaxLatMinLonBelow() {
double ay = 8.0;
double ax = 6.0;
double by = 6.25;
double bx = 6.75;
double cy = 6.0;
double cx = 8.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(bx);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//Two shared point with MBR -> [MinLat, MaxLon], [MaxLat, MinLon], third point above
public void testPolygonEncodingMinLatMaxLonMaxLatMinLonAbove() {
double ay = 2.0;
double ax = 0.0;
double by = 0.0;
double bx = 2.0;
double cy = 1.75;
double cx = 1.25;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(bx);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//all points shared with MBR
public void testPolygonEncodingAllSharedAbove() {
double ay = 0.0;
double ax = 0.0;
double by = 0.0;
double bx = 2.0;
double cy = 2.0;
double cx = 2.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(bx);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
verifyEncodingPermutations(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//all points shared with MBR
public void testPolygonEncodingAllSharedBelow() {
double ay = 2.0;
double ax = 0.0;
double by = 0.0;
double bx = 0.0;
double cy = 2.0;
double cx = 2.0;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(bx);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, cyEnc);
assertEquals(encoded.cX, cxEnc);
}
//[a,b,c] == [c,a,b] == [b,c,a] == [c,b,a] == [b,a,c] == [a,c,b]
public void verifyEncodingPermutations(int ayEnc, int axEnc, int byEnc, int bxEnc, int cyEnc, int cxEnc) {
//this is only valid when points are not co-planar
assertTrue(GeoUtils.orient(ayEnc, axEnc, byEnc, bxEnc, cyEnc, cxEnc) != 0);
byte[] b = new byte[7 * ShapeField.BYTES];
//[a,b,c]
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, false);
ShapeField.DecodedTriangle encodedABC = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encodedABC);
//[c,a,b]
ShapeField.encodeTriangle(b, cyEnc, cxEnc, false, ayEnc, axEnc, true, byEnc, bxEnc, true);
ShapeField.DecodedTriangle encodedCAB = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encodedCAB);
assertEquals(encodedABC, encodedCAB);
//[b,c,a]
ShapeField.encodeTriangle(b, byEnc, bxEnc, true, cyEnc, cxEnc, false, ayEnc, axEnc, true);
ShapeField.DecodedTriangle encodedBCA = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encodedBCA);
assertEquals(encodedABC, encodedBCA);
//[c,b,a]
ShapeField.encodeTriangle(b, cyEnc, cxEnc, true, byEnc, bxEnc, true, ayEnc, axEnc, false);
ShapeField.DecodedTriangle encodedCBA= new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encodedCBA);
assertEquals(encodedABC, encodedCBA);
//[b,a,c]
ShapeField.encodeTriangle(b, byEnc, bxEnc, true, ayEnc, axEnc, false, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encodedBAC= new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encodedBAC);
assertEquals(encodedABC, encodedBAC);
//[a,c,b]
ShapeField.encodeTriangle(b, ayEnc, axEnc, false, cyEnc, cxEnc, true, byEnc, bxEnc, true);
ShapeField.DecodedTriangle encodedACB= new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encodedACB);
assertEquals(encodedABC, encodedACB);
}
public void testPointEncoding() {
double lat = 45.0;
double lon = 45.0;
int latEnc = encodeY(lat);
int lonEnc = encodeX(lon);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, latEnc, lonEnc, true, latEnc, lonEnc, true, latEnc, lonEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, latEnc);
assertEquals(encoded.aX, lonEnc);
assertEquals(encoded.bY, latEnc);
assertEquals(encoded.bX, lonEnc);
assertEquals(encoded.cY, latEnc);
assertEquals(encoded.cX, lonEnc);
}
public void testLineEncodingSameLat() {
double lat = 2.0;
double ax = 0.0;
double bx = 2.0;
int latEnc = encodeY(lat);
int axEnc = encodeX(ax);
int bxEnc = encodeX(bx);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, latEnc, axEnc, true, latEnc, bxEnc, true, latEnc, axEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, latEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, latEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, latEnc);
assertEquals(encoded.cX, axEnc);
ShapeField.encodeTriangle(b, latEnc, axEnc, true, latEnc, axEnc, true, latEnc, bxEnc, true);
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, latEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, latEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, latEnc);
assertEquals(encoded.cX, axEnc);
ShapeField.encodeTriangle(b, latEnc, bxEnc, true, latEnc, axEnc, true, latEnc, axEnc, true);
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, latEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, latEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, latEnc);
assertEquals(encoded.cX, axEnc);
}
public void testLineEncodingSameLon() {
double ay = 0.0;
double by = 2.0;
double lon = 2.0;
int ayEnc = encodeY(ay);
int byEnc = encodeY(by);
int lonEnc = encodeX(lon);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, lonEnc, true, byEnc, lonEnc, true, ayEnc, lonEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, lonEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, lonEnc);
assertEquals(encoded.cY, ayEnc);
assertEquals(encoded.cX, lonEnc);
ShapeField.encodeTriangle(b, ayEnc, lonEnc, true, ayEnc, lonEnc, true, byEnc, lonEnc, true);
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, lonEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, lonEnc);
assertEquals(encoded.cY, ayEnc);
assertEquals(encoded.cX, lonEnc);
ShapeField.encodeTriangle(b, byEnc, lonEnc, true, ayEnc, lonEnc, true, ayEnc, lonEnc, true);
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, lonEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, lonEnc);
assertEquals(encoded.cY, ayEnc);
assertEquals(encoded.cX, lonEnc);
}
public void testLineEncoding() {
double ay = 0.0;
double by = 2.0;
double ax = 0.0;
double bx = 2.0;
int ayEnc = encodeY(ay);
int byEnc = encodeY(by);
int axEnc = encodeX(ax);
int bxEnc = encodeX(bx);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, ayEnc, axEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, ayEnc);
assertEquals(encoded.cX, axEnc);
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, ayEnc, axEnc, true, byEnc, bxEnc, true);
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, ayEnc);
assertEquals(encoded.cX, axEnc);
ShapeField.encodeTriangle(b, byEnc, bxEnc, true, ayEnc, axEnc, true, ayEnc, axEnc, true);
ShapeField.decodeTriangle(b, encoded);
assertEquals(encoded.aY, ayEnc);
assertEquals(encoded.aX, axEnc);
assertEquals(encoded.bY, byEnc);
assertEquals(encoded.bX, bxEnc);
assertEquals(encoded.cY, ayEnc);
assertEquals(encoded.cX, axEnc);
}
public void testRandomPointEncoding() {
double ay = nextY();
double ax = nextX();
verifyEncoding(ay, ax, ay, ax, ay, ax);
}
public void testRandomLineEncoding() {
double ay = nextY();
double ax = nextX();
double by = nextY();
double bx = nextX();
verifyEncoding(ay, ax, by, bx, ay, ax);
}
public void testRandomPolygonEncoding() {
double ay = nextY();
double ax = nextX();
double by = nextY();
double bx = nextX();
double cy = nextY();
double cx = nextX();
verifyEncoding(ay, ax, by, bx, cy, cx);
}
protected void verifyEncoding(double ay, double ax, double by, double bx, double cy, double cx) {
// encode triangle
int[] original = new int[]{encodeX(ax), encodeY(ay), encodeX(bx), encodeY(by), encodeX(cx), encodeY(cy)};
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, original[1], original[0], true, original[3], original[2], true, original[5], original[4], true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
// quantize decoded triangle
double[] encodedQuantize = new double[] {decodeX(encoded.aX), decodeY(encoded.aY), decodeX(encoded.bX), decodeY(encoded.bY), decodeX(encoded.cX), decodeY(encoded.cY)};
// quantize original and order it to reflect encoding
double[] originalQuantize = orderTriangle(original[0], original[1], original[2], original[3], original[4], original[5]);
// check spatial property
for (int i =0; i < 100; i ++) {
Component2D polygon2D = createPolygon2D(nextPolygon());
boolean originalIntersects = false;
boolean encodedIntersects = false;
boolean originalContains = false;
boolean encodedContains = false;
switch (encoded.type) {
case POINT:
originalIntersects = polygon2D.contains(originalQuantize[0], originalQuantize[1]);
encodedIntersects = polygon2D.contains(encodedQuantize[0], encodedQuantize[1]);
originalContains = polygon2D.contains(originalQuantize[0], originalQuantize[1]);
encodedContains = polygon2D.contains(encodedQuantize[0], encodedQuantize[1]);
break;
case LINE:
originalIntersects = polygon2D.intersectsLine(originalQuantize[0], originalQuantize[1], originalQuantize[2], originalQuantize[3]);
encodedIntersects = polygon2D.intersectsLine(encodedQuantize[0], encodedQuantize[1], encodedQuantize[2], encodedQuantize[3]);
originalContains = polygon2D.containsLine(originalQuantize[0], originalQuantize[1], originalQuantize[2], originalQuantize[3]);
encodedContains = polygon2D.containsLine(encodedQuantize[0], encodedQuantize[1], encodedQuantize[2], encodedQuantize[3]);
break;
case TRIANGLE:
originalIntersects = polygon2D.intersectsTriangle(originalQuantize[0], originalQuantize[1], originalQuantize[2], originalQuantize[3], originalQuantize[4], originalQuantize[5]);
encodedIntersects = polygon2D.intersectsTriangle(originalQuantize[0], originalQuantize[1], originalQuantize[2], originalQuantize[3], originalQuantize[4], originalQuantize[5]);
originalContains = polygon2D.containsTriangle(originalQuantize[0], originalQuantize[1], originalQuantize[2], originalQuantize[3], originalQuantize[4], originalQuantize[5]);
encodedContains = polygon2D.containsTriangle(originalQuantize[0], originalQuantize[1], originalQuantize[2], originalQuantize[3], originalQuantize[4], originalQuantize[5]);
break;
}
assertTrue(originalIntersects == encodedIntersects);
assertTrue(originalContains == encodedContains);
}
}
private double[] orderTriangle(int aX, int aY, int bX, int bY, int cX, int cY) {
// quantize original and order it to reflect encoding
int orientation = GeoUtils.orient(aX, aY, bX, bY, cX, cY);
if (orientation == -1) {
// we need to change the orientation if CW for triangles
return new double[]{decodeX(cX), decodeY(cY), decodeX(bX), decodeY(bY), decodeX(aX), decodeY(aY)};
} else if (aX == bX && aY == bY) {
if (aX != cX || aY != cY) { // not a point
if (aX < cX) {
return new double[]{decodeX(aX), decodeY(aY), decodeX(cX), decodeY(cY), decodeX(aX), decodeY(aY)};
} else {
return new double[]{decodeX(cX), decodeY(cY), decodeX(aX), decodeY(aY), decodeX(cX), decodeY(cY)};
}
}
} else if ((aX == cX && aY == cY) || (bX == cX && bY == cY)) {
if (aX < bX) {
return new double[]{decodeX(aX), decodeY(aY), decodeX(bX), decodeY(bY), decodeX(aX), decodeY(aY)};
} else {
return new double[]{decodeX(bX), decodeY(bY), decodeX(aX), decodeY(aY), decodeX(bX), decodeY(bY)};
}
}
return new double[]{decodeX(aX), decodeY(aY), decodeX(bX), decodeY(bY), decodeX(cX), decodeY(cY)};
}
public void testDegeneratedTriangle() {
double ay = 1e-26d;
double ax = 0.0d;
double by = -1.0d;
double bx = 0.0d;
double cy = 1.0d;
double cx = 0.0d;
int ayEnc = encodeY(ay);
int axEnc = encodeX(ax);
int byEnc = encodeY(by);
int bxEnc = encodeX(bx);
int cyEnc = encodeY(cy);
int cxEnc = encodeX(cx);
byte[] b = new byte[7 * ShapeField.BYTES];
ShapeField.encodeTriangle(b, ayEnc, axEnc, true, byEnc, bxEnc, true, cyEnc, cxEnc, true);
ShapeField.DecodedTriangle encoded = new ShapeField.DecodedTriangle();
ShapeField.decodeTriangle(b, encoded);
assertTrue(encoded.aY == byEnc);
assertTrue(encoded.aX == bxEnc);
assertTrue(encoded.bY == cyEnc);
assertTrue(encoded.bX == cxEnc);
assertTrue(encoded.cY == ayEnc);
assertTrue(encoded.cX == axEnc);
}
}