24.09., 9:00 - 11:00: Due to updates GitLab will be unavailable for some minutes between 09:00 and 11:00.

Commit dac80587 by Benedikt Zoennchen

Merge branch 'fixGetOrthocenterBug' into 'master'

```getOrthocenter without slope determination

See merge request !49```
parents c6997cb8 f1d5730d
Pipeline #113405 passed with stages
in 168 minutes and 54 seconds
 ... ... @@ -5,6 +5,10 @@ import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; import org.vadere.util.geometry.GeometryUtils; import org.vadere.util.geometry.Vector3D; import static java.lang.Double.isInfinite; import static java.lang.Double.isNaN; /** * A triangle. Points must be given in counter clockwise manner to get correct ... ... @@ -112,25 +116,58 @@ public class VTriangle extends VPolygon { } public VPoint getOrthocenter() { if(orthocenter == null) { double slope = -1 / ((p2.getY() - p1.getY()) / (p2.getX() - p1.getX())); // y = slope * (x - p3.x) + p3.y double slope2 = -1 / ((p1.getY() - p3.getY()) / (p1.getX() - p3.getX()));// y = slope2 * (x - p2.x) + p2.y VPoint p12, p13, p23, L1, L2; // create edge vectors p12 = p2.subtract(p1); // Vector2D better?? p13 = p3.subtract(p1); p23 = p3.subtract(p2); // create system of equations double cross = p13.crossProduct(p12); // slope2 * (x - p2.x) + p2.y = slope * (x - p3.x) + p3.y // slope2 * (x - p2.x) - slope * (x - p3.x) = + p3.y - p2.y // slope2 * x - slope2 * p2.x - slope * x + slope * p3.x = + p3.y - p2.y // slope2 * x - slope * x = + p3.y - p2.y + slope2 * p2.x - slope * p3.x // x * (slope2 - slope) = + p3.y - p2.y + slope2 * p2.x - slope * p3.x double x = (p3.getY() - p2.getY() + slope2 * p2.getX() - slope * p3.getX()) / (slope2 - slope); double y = slope * (x - p3.getX()) + p3.getY(); orthocenter = new VPoint(x, y); L1 = new VPoint(-cross* p23.getY() , cross * p23.getX() ); L2 = new VPoint(-cross* p13.getY() , cross * p13.getX() ); // solve system of equation (determine first element of resulting vector lamda with cramers rule; second element not necessary) double lamda1 = ( p12.getX() * L2.getY() - p12.getY() * L2.getX() ) / ( L1.getX()*L2.getY() - L2.getX()*L1.getY() ) ; orthocenter = new VPoint ( p1.add( L1.scalarMultiply(lamda1) ) ); } //VPoint orthocenter2 = getOrthocenterSlowImplementation() ; //assert Math.abs( orthocenter.distance(orthocenter2)) < GeometryUtils.DOUBLE_EPS ; return orthocenter; } public VPoint getOrthocenterSlowImplementation() { // create edge vectors VPoint p12 = p2.subtract(p1); // Vector2D better?? VPoint p13 = p3.subtract(p1); VPoint p23 = p3.subtract(p2); // edge vectors reverse VPoint p21 = new VPoint(p12.scalarMultiply(-1.0)); VPoint p31 = new VPoint(p13.scalarMultiply(-1.0)); VPoint p32 = new VPoint(p23.scalarMultiply(-1.0)); // calculate angles a1, a2, a3 double a1 = Math.atan2(Math.abs( p13.crossProduct(p12)), p13.scalarProduct(p12)) ; double a2 = Math.atan2(Math.abs( p23.crossProduct(p21)), p23.scalarProduct(p21)) ; double a3 = Math.atan2(Math.abs( p31.crossProduct(p32)), p31.scalarProduct(p32)) ; double div = Math.tan(a1)+ Math.tan(a2)+ Math.tan(a3) ; double x = ( Math.tan(a1)*p1.getX() + Math.tan(a2)*p2.getX() + Math.tan(a3)*p3.getX() ) / div; double y = ( Math.tan(a1)*p1.getY() + Math.tan(a2)*p2.getY() + Math.tan(a3)*p3.getY() ) / div; return new VPoint(x,y); } public VPoint closestPoint(final IPoint point) { VPoint currentClosest = null; ... ...
 ... ... @@ -2,14 +2,9 @@ package org.vadere.util.geometry.shapes; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.vadere.util.geometry.GeometryUtils; import org.vadere.util.logging.Logger; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import static org.junit.Assert.*; public class TestVTriangle { ... ... @@ -23,11 +18,10 @@ public class TestVTriangle { private double coorTop = Math.sqrt( Math.pow(radiusShould,2) + Math.pow(coor,2) ); private VTriangle vTriangle_symY_60degree = new VTriangle(new VPoint(-coor,-radiusShould), new VPoint(coor,-radiusShould), new VPoint(0.,coorTop) ); // create y-symmetric 45°-45°-90°-triangle (90°-angle is split by y-axis) private VPoint vPoint1 = new VPoint(-1.,0.); private VPoint vPoint2 = new VPoint(1.,0.); private VPoint vPoint3 = new VPoint(0.,1.); private VPoint vPoint3 = new VPoint(0.,1); private VTriangle vTriangle_sym = new VTriangle(vPoint1, vPoint2, vPoint3); private VPoint vPoint4 = new VPoint(vPoint2.getX() + 0.1,vPoint2.getY()); // getter not necessary because attributes are public ... ... @@ -40,23 +34,13 @@ public class TestVTriangle { @Before public void setUp() throws Exception { // ? } @Test public void testClosestPoint0(){ // also write time stemp because it is not included into ASCI output file VadereUtils/log.out logger.info("Start Test testClosestPoint" + ZonedDateTime.now().toLocalTime().truncatedTo(ChronoUnit.SECONDS)); System.out.println( "Point 1 == Point 2"); System.out.println( vTriangle_sym.closestPoint(vPoint1).equals(vPoint2,0.1) ); System.out.println( "Point 2 == Point 2"); System.out.println( vTriangle_sym.closestPoint(vPoint2).equals(vPoint2,0.1) ); System.out.println( "Point 2 == Point 4; accurate"); System.out.println( vTriangle_sym.closestPoint(vPoint2).equals(vPoint4,0.1) ); System.out.println( "Point 2 == Point 4; not accurate"); System.out.println( vTriangle_sym.closestPoint(vPoint2).equals(vPoint4,0.2) ); //double d1 = GeometryUtils.ccw(vPoint1, vPoint2, vPoint3); assertFalse( vTriangle_sym.closestPoint(vPoint1).equals(vPoint2,0.1) ); assertTrue( vTriangle_sym.closestPoint(vPoint2).equals(vPoint2,0.1) ); assertFalse( vTriangle_sym.closestPoint(vPoint2).equals(vPoint4,0.1) ); assertTrue( vTriangle_sym.closestPoint(vPoint2).equals(vPoint4,0.2) ); } /** ... ... @@ -65,13 +49,6 @@ public class TestVTriangle { */ @Test public void testContains() { /* System.out.println( "Point 1 - 3 belong to the triangle; should be true" ); System.out.println( vTriangle_sym.contains(vPoint1) && vTriangle_sym.contains(vPoint2) && vTriangle_sym.contains(vPoint3) ); System.out.println( "Point 2 - 4 belong to the triangle; should be false" ); System.out.println( vTriangle_sym.contains(vPoint2) && vTriangle_sym.contains(vPoint3) && vTriangle_sym.contains(vPoint4) ); */ // vTriangle_sym.contains returns true if point is a vertex or point is inside triangle assertTrue("Point 1 is vertex of Triangle 1.", vTriangle_sym.contains(vPoint1)); assertTrue("Point 2 is vertex of Triangle 1.", vTriangle_sym.contains(vPoint2)); ... ... @@ -88,15 +65,6 @@ public class TestVTriangle { */ @Test public void testIsPartOf() { /* System.out.println( "Point 1 is in triangle; should be true" ); System.out.println( vTriangle_sym.isPartOf(vPoint1,0.0)); System.out.println( "Point 4 is in triangle; should be true" ); System.out.println( vTriangle_sym.isPartOf(vPoint4,0.2)); System.out.println( "Point 4 is in triangle; should be false" ); System.out.println( vTriangle_sym.isPartOf(vPoint4,0.1)); System.out.println( vTriangle_sym.isPartOf(vPoint5,0.01));*/ // vTriangle_sym.isPartOf returns true if point is a vertex or point is inside triangle + tolerance double tolerance = 0.0; assertTrue("Point 1 is vertex of Triangle 1.", vTriangle_sym.isPartOf(vPoint1,tolerance)); ... ... @@ -106,7 +74,6 @@ public class TestVTriangle { // vTriangle_sym.isPartOf returns false if point is outside triangle + tolerance assertFalse("Point 4 lays outside Triangle 1.", vTriangle_sym.isPartOf(vPoint4,tolerance)); } @Test ... ... @@ -115,19 +82,9 @@ public class TestVTriangle { double x = vPoint.getX(); double y = vPoint.getY(); double eps = Math.max (Math.abs(x - 0.0), Math.abs(y - 1./3)); System.out.print( vPoint.toString() ); if (eps > GeometryUtils.DOUBLE_EPS) System.out.print( " is not Midpoint. Error \n"); else System.out.print( " is Midpoint. \n" ); assertTrue(eps < GeometryUtils.DOUBLE_EPS); } @Test public void testMidPointA() { VPoint vPoint = vTriangle_sym.midPoint(); VPoint checkPoint = new VPoint(0.0, 1./3); assertEquals(checkPoint,vPoint); } @Test public void testIsLine() { ... ... @@ -143,8 +100,7 @@ public class TestVTriangle { @Test public void testGetCentroid() { VPoint vPoint = vTriangle_sym.getCentroid(); // special structure of triangle: midpoint = centroid VPoint checkPoint = new VPoint(0.0, 1./3); VPoint checkPoint = new VPoint(0.0, 1./3); // special structure of triangle: midpoint = centroid assertEquals(checkPoint,vPoint); } ... ... @@ -158,33 +114,66 @@ public class TestVTriangle { //assertEquals(vPoint, new VPoint(0.0,0.0), GeometryUtils.DOUBLE_EPS); double eps = Math.max (Math.abs(x - 0.0), Math.abs(y - 0.0)); // Point (0,0) is incenter assertTrue(eps < GeometryUtils.DOUBLE_EPS); // assertEquals(0.0, vPoint.distance(new VPoint(x, y)), GeometryUtils.DOUBLE_EPS); } /** * test fails because slope is infinite * */ @Ignore @Test public void testGetOrthocenter() { // use 60°-triangle (2 vertices on y-axis) for test VPoint vPoint = vTriangle_60degree.getOrthocenter(); // time measure long startTime, runTimeInNs, runTimeInNsSlow; VPoint vPointY, vPoint; /** Triangle 1: use 60°-triangle (2 vertices on y-axis) for test */ // fast implementation startTime = System.nanoTime(); vPoint = vTriangle_60degree.getOrthocenter(); runTimeInNs = System.nanoTime() - startTime ; double x = vPoint.getX(); double y = vPoint.getY(); double eps = Math.max (Math.abs(x - 0.5), Math.abs(y - 0.0)); // Point (0.5,0) is orthocenter assertTrue(eps < GeometryUtils.DOUBLE_EPS); // triangle with y-symmetry (45°-90°-45°); does not work because of infinite slope // exception handling ? VPoint vPointY = this.vTriangle_sym.getOrthocenter(); // slow implementation startTime = System.nanoTime(); vPoint = vTriangle_60degree.getOrthocenterSlowImplementation(); runTimeInNsSlow = System.nanoTime() - startTime ; x = vPoint.getX(); y = vPoint.getY(); eps = Math.max (Math.abs(x - 0.5), Math.abs(y - 0.0)); // Point (0.5,0) is orthocenter assertTrue(eps < GeometryUtils.DOUBLE_EPS); // compare fast and slow implementation logger.info("Triangle 1: Fast implementation required " + runTimeInNs + "[nano sec]"); logger.info("Triangle 1: Slow implementation required " + runTimeInNsSlow + "[nano sec]"); logger.info("Triangle 1: time factor -> slow to fast: " + 1.0*runTimeInNsSlow/runTimeInNs ); /** Triangle 2: triangle with y-symmetry (45°-90°-45°); does not work because of infinite slope */ // fast implementation startTime = System.nanoTime(); vPointY= this.vTriangle_sym.getOrthocenter(); runTimeInNs = System.nanoTime() - startTime ; x = vPointY.getX(); y = vPointY.getY(); eps = Math.max (Math.abs(x - 0.0), Math.abs(y - 1.0)); // Point (0.5,0) is orthocenter assertTrue(eps < GeometryUtils.DOUBLE_EPS); // slow implementation startTime = System.nanoTime(); vPointY = this.vTriangle_sym.getOrthocenterSlowImplementation(); runTimeInNsSlow = System.nanoTime() - startTime ; x = vPointY.getX(); y = vPointY.getY(); eps = Math.max (Math.abs(x - 0.0), Math.abs(y - 1.0)); // Point (0.5,0) is orthocenter assertTrue(eps < GeometryUtils.DOUBLE_EPS); // compare fast and slow implementation logger.info("Triangle 2: Fast implementation required " + runTimeInNs + "[nano sec]"); logger.info("Triangle 2: Slow implementation required " + runTimeInNsSlow + "[nano sec]"); logger.info("Triangle 2: time factor -> slow to fast: " + 1.0*runTimeInNsSlow/runTimeInNs ); } @Test public void testClosestPoint() { // y-symmetric triangle contains vPoint1 assertEquals(vTriangle_sym.closestPoint(vPoint1), vPoint1 ); ... ... @@ -205,20 +194,17 @@ public class TestVTriangle { y = newPoint3.getY(); eps = Math.max (Math.abs(x - 0.0), Math.abs(y - 0.3)); assertTrue(eps < GeometryUtils.DOUBLE_EPS); } @Test public void testGetCircumcenter(){ // y-symmetric 60°-triangle: Circumcenter = Incenter = (0.0,0.0) // y-symmetric 60°-triangle: Circumcenter = (0.0,0.0) VPoint vPoint = vTriangle_symY_60degree.getIncenter(); double x = vPoint.getX(); double y = vPoint.getY(); double eps = Math.max (Math.abs(x - 0.0), Math.abs(y - 0.0)); assertTrue(eps < GeometryUtils.DOUBLE_EPS); } @Test ... ... @@ -229,17 +215,6 @@ public class TestVTriangle { assertTrue(eps < GeometryUtils.DOUBLE_EPS); } /* @Test public void testIsInCircumscribedCycle() { } @Test public void testMaxCoordinate() { } @Test public void testGetLines() { } */ @After public void tearDown() throws Exception { } ... ...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!