Note that there are some explanatory texts on larger screens.

plurals
  1. POmerging convex hulls in java
    primarykey
    data
    text
    <p>I've written a java program which which uses the divide and conquer algorithm to find the convex hull of a polygon in a cartesian coordination. I have a class Coord which has two "double" fields X and y and "this" which I'm using the method on, is a collection of coordinates (set). my method should return the hull (Collection) of the polygon</p> <p>My code is like this:</p> <pre><code> public Collection&lt;Coord&gt; territoire() { Collection&lt;Coord&gt; sommets = new ArrayList&lt;Coord&gt;(); ArrayList&lt;Coord&gt; thisToArrList = new ArrayList&lt;Coord&gt;(); for(Coord c : this) thisToArrList.add(c); ArrayList&lt;Coord&gt; sortedPointsByX = new ArrayList&lt;Coord&gt;(); int n = this.size(); if (n &lt;= 2) return this; //sorting the points by their X coordinates sortedPointsByX = sortedArrayByX(thisToArrList); //&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; works good till here &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; // now sortedPointsByX array contains the points with increasing X // splitting the sortedPointsByX into two arrays ArrayList&lt;Coord&gt; firstPart = new ArrayList&lt;Coord&gt;(); ArrayList&lt;Coord&gt; secondPart = new ArrayList&lt;Coord&gt;(); // if the number of the points is prime, the leftmost and the rightmost half // both have same number of points if(sortedPointsByX.size() % 2 == 0) { for(int i = 0; i &lt; sortedPointsByX.size()/2; i++) { firstPart.add(sortedPointsByX.get(i)); } for(int i = sortedPointsByX.size()/2; i &lt; sortedPointsByX.size(); i++) { secondPart.add(sortedPointsByX.get(i)); } } //&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;works good till here&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; // if the number of points is odd, the leftmost half have the extra points else { for(int i = 0; i &lt; sortedPointsByX.size()/2+1; i++) { firstPart.add(sortedPointsByX.get(i)); } for(int i = sortedPointsByX.size()/2+1; i &lt; sortedPointsByX.size(); i++) { secondPart.add(sortedPointsByX.get(i)); } } //&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;works good till here&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; CoordSet firstSet = new CoordSet(firstPart); CoordSet secondSet = new CoordSet(secondPart); // converting the arrays to list of coordinates in order to use recursion over them //recursion for sub coordsets Collection&lt;Coord&gt; firstSetSommet = firstSet.territoire(); Collection&lt;Coord&gt; secondSetSommet = secondSet.territoire(); ArrayList&lt;Coord&gt; firstHull = new ArrayList&lt;Coord&gt;(firstSetSommet); ArrayList&lt;Coord&gt; secondHull = new ArrayList&lt;Coord&gt;(secondSetSommet); sommets = mergeHulls(firstHull, secondHull); return sommets; } public Collection&lt;Coord&gt; mergeHulls(ArrayList&lt;Coord&gt; firstHull, ArrayList&lt;Coord&gt; secondHull) { Collection&lt;Coord&gt; pointsInside = new ArrayList&lt;Coord&gt;(); Collection&lt;Coord&gt; sommets = new ArrayList&lt;Coord&gt;(); //********************upper tangent*************** //find the highest point of the leftmost part Coord firstPartHighestPoint = getMaxY(firstHull); //find the highest point of the rightmost part Coord secondPartHighestPoint = getMaxY(secondHull); for(int i = 0; i&lt; firstHull.size(); i++) { // check if the points lie on the line between highest point in leftmost and in rightmost // if true, the current point is above the line if(isCollinear(firstPartHighestPoint, secondPartHighestPoint, firstHull.get(i))&gt;0) { // the current point is above the line firstPartHighestPoint = firstHull.get(i); } pointsInside.add(firstPartHighestPoint); } for(int i = 0; i &lt; secondHull.size(); i++) { if(isCollinear(firstPartHighestPoint, secondPartHighestPoint, secondHull.get(i))&gt;0) { // the current point is above the line secondPartHighestPoint = secondHull.get(i); } pointsInside.add(secondPartHighestPoint); } //******************lower tangent*************** //find the lowest point of the leftmost part Coord firstPartLowestPoint = getMinY(firstHull); // find the lowest point of the rightmost part Coord secondPartLowestPoint = getMinY(secondHull); for(int i = 0; i&lt; firstHull.size(); i++) { // check if the points lie on the line between highest point in leftmost and in rightmost // if true, the current point is above the line if(isCollinear(firstPartLowestPoint, secondPartLowestPoint, firstHull.get(i)) &lt; 0) { // the current point is above the line firstPartLowestPoint = firstHull.get(i); } pointsInside.add(firstPartLowestPoint); } for(int i = 0; i &lt; secondHull.size(); i++) { if(isCollinear(firstPartLowestPoint, secondPartLowestPoint, secondHull.get(i)) &lt; 0) { // the current point is above the line secondPartLowestPoint = secondHull.get(i); } pointsInside.add(firstPartLowestPoint); } sommets.addAll(firstHull); sommets.addAll(secondHull); sommets.removeAll(pointsInside); return sommets; } //**********************************Auxiliary méthods**************************************************** // if the equation is equal to 0, the points are collinear // the method returns the determinant of the point matrix // This determinant tells how far point 'c' is from vector ab and on which side // it is // &lt; 0 if the point 'c' is below the line (assumption : horizontal line) // &gt; 0 if the point 'c' is above the line public double isCollinear(Coord a, Coord b, Coord c) { return ((b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x)); } //************************************** line equation ************************************************ // find the slope of the line between two points public static double findSlope(Coord point1, Coord point2) { return (point2.y - point1.y)/(point2.x-point1.x); } // finding the constant 'b' of the line equation y = xm + b public static double constantB(Double slope, Coord point) { return point.y - slope* point.x; } //*************************************** Minimum and Maximum "Y" ***************************************** // the point with maximum Y public static Coord getMaxY(ArrayList&lt;Coord&gt; points) { double maxY = points.get(0).y; // start with the first value Coord maxPoint = points.get(0); for (int i=1; i&lt;points.size(); i++) { if (points.get(i).y &gt; maxY) { maxY = points.get(i).y; // new maximum maxPoint = points.get(i); } } return maxPoint; } // a method to find the Point with the minimum y public static Coord getMinY(ArrayList&lt;Coord&gt; points) { double minValue = points.get(0).y; Coord minPoint = points.get(0); for(int i=1;i&lt;points.size();i++){ if(points.get(i).y &lt; minValue) { minPoint = points.get(i); minValue = points.get(i).y; } } return minPoint; } //************************************** sorting the points ******************************************** //sorting the points by their x in ascending order public static ArrayList&lt;Coord&gt; sortedArrayByX(ArrayList&lt;Coord&gt; arrayOfPoints) { //double minval = arrayOfPoints[0].x; Coord temp = null; for(int i = 0; i&lt; arrayOfPoints.size(); i++) { for(int j = 0; j&lt; arrayOfPoints.size()-1; j++) { if(arrayOfPoints.get(j+1).x &lt; arrayOfPoints.get(j).x) { temp = arrayOfPoints.get(j+1); arrayOfPoints.set(j+1, arrayOfPoints.get(j)); arrayOfPoints.set(j, temp); } } } return arrayOfPoints; } </code></pre> <p>I can't get why when I run the program, the following message shows up:</p> <pre><code>Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:604) at java.util.ArrayList.get(ArrayList.java:382) at miniprojet2.CoordSet.getMaxY(CoordSet.java:270) at miniprojet2.CoordSet.mergeHulls(CoordSet.java:154) at miniprojet2.CoordSet.territoire(CoordSet.java:139) at miniprojet2.CalculeTerritoire.main(CalculeTerritoire.java:36) </code></pre> <p>I'll be so glad if you tell me where I've made a mistake</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload