From 94b7d28559e0bc23b0bbd13c3ee84a34fb36a899 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Fri, 5 Oct 2018 12:07:21 +0200
Subject: [PATCH] method that allows to remove collinear points from line

---
 .../geometry/helper/PolylineDataFactory.java  | 28 ++++++
 .../helper/PolylineDataFactoryTest.java       | 88 +++++++++++++------
 2 files changed, 91 insertions(+), 25 deletions(-)

diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactory.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactory.java
index b44d10bf2c..de81309349 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactory.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactory.java
@@ -4,6 +4,8 @@ import java.awt.geom.Point2D;
 import java.util.ArrayList;
 import java.util.List;
 
+import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.common.geometry.LineTransformation;
 import lcsb.mapviewer.converter.model.celldesigner.structure.fields.EditPoints;
 import lcsb.mapviewer.model.graphics.PolylineData;
 
@@ -58,4 +60,30 @@ public final class PolylineDataFactory {
       return createPolylineDataFromEditPoints(baseA, baseB, new ArrayList<Point2D>());
     }
   }
+
+  /**
+   * Creates {@link PolylineData} object from the parameter that doesn't contain
+   * collinear points.
+   * 
+   * @param ld
+   *          original line
+   * @return line without collinear points
+   */
+  public static PolylineData removeCollinearPoints(PolylineData ld) {
+    LineTransformation lt = new LineTransformation();
+    PolylineData result = new PolylineData(ld);
+    int pointNumber = 1;
+    while (pointNumber < result.getPoints().size() - 1) {
+      Point2D previousPoint = result.getPoints().get(pointNumber - 1);
+      Point2D nextPoint = result.getPoints().get(pointNumber + 1);
+      Point2D currentPoint = result.getPoints().get(pointNumber);
+      Point2D closestPointOnLine = lt.closestPointOnSegmentLineToPoint(previousPoint, nextPoint, currentPoint);
+      if (closestPointOnLine.distance(currentPoint) <= Configuration.EPSILON) {
+        result.getPoints().remove(pointNumber);
+      } else {
+        pointNumber++;
+      }
+    }
+    return result;
+  }
 }
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactoryTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactoryTest.java
index 4661d079e8..19822c1205 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactoryTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/geometry/helper/PolylineDataFactoryTest.java
@@ -1,37 +1,75 @@
 package lcsb.mapviewer.converter.model.celldesigner.geometry.helper;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
+import java.awt.geom.Point2D;
 import java.lang.reflect.Constructor;
 
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
 import org.junit.Test;
 
+import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.model.graphics.PolylineData;
+
 public class PolylineDataFactoryTest {
 
-	@AfterClass
-	public static void tearDownAfterClass() throws Exception {
-	}
-
-	@Before
-	public void setUp() throws Exception {
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	@Test
-	public void testPrivateCotnstructor() throws Exception {
-		try {
-			Constructor<?> constr = PolylineDataFactory.class.getDeclaredConstructor(new Class<?>[] {});
-			constr.setAccessible(true);
-			assertNotNull(constr.newInstance(new Object[] {}));
-		} catch (Exception e) {
-			throw e;
-		}
-	}
+  @Test
+  public void testPrivateCotnstructor() throws Exception {
+    try {
+      Constructor<?> constr = PolylineDataFactory.class.getDeclaredConstructor(new Class<?>[] {});
+      constr.setAccessible(true);
+      assertNotNull(constr.newInstance(new Object[] {}));
+    } catch (Exception e) {
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRemoveCollinearPoints2() throws Exception {
+    try {
+      PolylineData line = new PolylineData();
+      line.addPoint(new Point2D.Double(10, 20));
+      line.addPoint(new Point2D.Double(11, 30));
+      line.addPoint(new Point2D.Double(12, 40));
+      PolylineData modifiedLine = PolylineDataFactory.removeCollinearPoints(line);
+      assertEquals(2, modifiedLine.getPoints().size());
+      assertEquals(0, modifiedLine.getBeginPoint().distance(new Point2D.Double(10, 20)), Configuration.EPSILON);
+      assertEquals(0, modifiedLine.getEndPoint().distance(new Point2D.Double(12, 40)), Configuration.EPSILON);
+    } catch (Exception e) {
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRemoveCollinearPoints() throws Exception {
+    try {
+      PolylineData line = new PolylineData();
+      line.addPoint(new Point2D.Double(10, 20));
+      line.addPoint(new Point2D.Double(10, 30));
+      line.addPoint(new Point2D.Double(10, 40));
+      line.addPoint(new Point2D.Double(10, 40));
+      PolylineData modifiedLine = PolylineDataFactory.removeCollinearPoints(line);
+      assertEquals(2, modifiedLine.getPoints().size());
+      assertEquals(0, modifiedLine.getBeginPoint().distance(new Point2D.Double(10, 20)), Configuration.EPSILON);
+      assertEquals(0, modifiedLine.getEndPoint().distance(new Point2D.Double(10, 40)), Configuration.EPSILON);
+    } catch (Exception e) {
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRemoveCollinearPointsWithoutCollinearPoints() throws Exception {
+    try {
+      PolylineData line = new PolylineData();
+      line.addPoint(new Point2D.Double(10, 20));
+      line.addPoint(new Point2D.Double(10, 30));
+      line.addPoint(new Point2D.Double(20, 40));
+      line.addPoint(new Point2D.Double(10, 40));
+      PolylineData modifiedLine = PolylineDataFactory.removeCollinearPoints(line);
+      assertEquals(4, modifiedLine.getPoints().size());
+    } catch (Exception e) {
+      throw e;
+    }
+  }
 
 }
-- 
GitLab