GeometryUtils improvements (#709)

This commit is contained in:
Gustl22
2019-04-05 11:47:27 +02:00
committed by Emux
parent 036d63c9dd
commit ba65786b5a
2 changed files with 59 additions and 24 deletions

View File

@@ -7,17 +7,36 @@ import org.oscim.utils.geom.GeometryUtils;
public class GeometryTest { public class GeometryTest {
@Test @Test
public void testIsTrisClockwise() { public void testClosestPointOnLine2D() {
// Coordinate system is LHS float[] pP = {4, 1};
float[] pA = new float[]{0, 0}; float[] pL = {1, 2};
float[] pB = new float[]{1, 0}; float[] vL = {1, -1};
float[] pC = new float[]{1, 1};
float area = GeometryUtils.isTrisClockwise(pA, pB, pC); float[] point = GeometryUtils.closestPointOnLine2D(pP, pL, vL);
Assert.assertTrue(area > 0); Assert.assertEquals(point[0], 3, 0.00001);
Assert.assertEquals(point[1], 0, 0.00001);
}
area = GeometryUtils.isTrisClockwise(pA, pC, pB); @Test
Assert.assertTrue(area < 0); public void testDistancePointLine2D() {
float[] pP = {1, 0};
float[] pL = {0, 0};
float[] vL = {2, 2};
float distance = GeometryUtils.distancePointLine2D(pP, pL, vL);
Assert.assertEquals(distance, Math.sqrt(2) / 2, 0.00001);
}
@Test
public void testDotProduct() {
float[] p = {-1, 0, 0, 0, 0, 0};
for (int i = 0; i < 9; i++) {
p[4] = (float) Math.cos(Math.toRadians(i * 45));
p[5] = (float) Math.sin(Math.toRadians(i * 45));
System.out.println("\n> " + (i * 45) + " " + p[3] + ":" + p[4] + "\n="
+ GeometryUtils.dotProduct(p, 0, 2, 4));
}
} }
@Test @Test
@@ -34,14 +53,16 @@ public class GeometryTest {
} }
@Test @Test
public void testDotProduct() { public void testIsTrisClockwise() {
float[] p = {-1, 0, 0, 0, 0, 0}; // Coordinate system is LHS
float[] pA = new float[]{0, 0};
float[] pB = new float[]{1, 0};
float[] pC = new float[]{1, 1};
for (int i = 0; i < 9; i++) { float area = GeometryUtils.isTrisClockwise(pA, pB, pC);
p[4] = (float) Math.cos(Math.toRadians(i * 45)); Assert.assertTrue(area > 0);
p[5] = (float) Math.sin(Math.toRadians(i * 45));
System.out.println("\n> " + (i * 45) + " " + p[3] + ":" + p[4] + "\n=" area = GeometryUtils.isTrisClockwise(pA, pC, pB);
+ GeometryUtils.dotProduct(p, 0, 2, 4)); Assert.assertTrue(area < 0);
}
} }
} }

View File

@@ -131,13 +131,9 @@ public final class GeometryUtils {
if (out == null) if (out == null)
out = new float[2]; out = new float[2];
// Calculate center
for (int i = 0; i < n; i += 2, pointPos += 2) { for (int i = 0; i < n; i += 2, pointPos += 2) {
float x = points[pointPos]; out[0] += points[pointPos];
float y = points[pointPos + 1]; out[1] += points[pointPos + 1];
out[0] += x;
out[1] += y;
} }
out[0] = out[0] * 2 / n; out[0] = out[0] * 2 / n;
out[1] = out[1] * 2 / n; out[1] = out[1] * 2 / n;
@@ -145,6 +141,21 @@ public final class GeometryUtils {
return out; return out;
} }
/**
* Calculate the closest point on a line.
* See: https://en.wikipedia.org/wiki/Vector_projection#Vector_projection_2
*
* @param pP point
* @param pL point of line
* @param vL vector of line
* @return the closest point on line
*/
public static float[] closestPointOnLine2D(float[] pP, float[] pL, float[] vL) {
float[] vPL = diffVec(pL, pP);
float[] vPS = diffVec(vPL, scale(vL, dotProduct(vPL, vL) / dotProduct(vL, vL)));
return sumVec(pP, vPS);
}
/** /**
* @param a first vector * @param a first vector
* @param b second vector * @param b second vector
@@ -222,6 +233,9 @@ public final class GeometryUtils {
} }
/** /**
* Calculate the distance from a point to a line.
* See: https://en.wikipedia.org/wiki/Vector_projection#Vector_projection_2
*
* @param pP point * @param pP point
* @param pL point of line * @param pL point of line
* @param vL vector of line * @param vL vector of line
@@ -229,7 +243,7 @@ public final class GeometryUtils {
*/ */
public static float distancePointLine2D(float[] pP, float[] pL, float[] vL) { public static float distancePointLine2D(float[] pP, float[] pL, float[] vL) {
float[] vPL = diffVec(pL, pP); float[] vPL = diffVec(pL, pP);
float[] vPS = diffVec(vPL, scale(vL, dotProduct(vPL, vL))); float[] vPS = diffVec(vPL, scale(vL, dotProduct(vPL, vL) / dotProduct(vL, vL)));
return (float) Math.sqrt(dotProduct(vPS, vPS)); return (float) Math.sqrt(dotProduct(vPS, vPS));
} }