3

I'm creating a tool where I have a map in JavaFX. I have to draw a existing polygon on that map in order to create zones on it for a location service. Then I want to click somewhere on the map to add a new corner to this polycon. Now, adding a corner to a polygon is not that hard. When I click somewhere on the map with the right mouse button I want to create a new corner there. But I want to add that corner in the "right" position, meaning before or after that existing corner that is nearest to the new one, not at the end of the polygon. Furthermore the new polygone should not cut thru the esiting polygone (see pict at the end of this post).

I used the theorem of Pythagoras to find the nearest point, but my problem now is, that I don't want if to add that corner BEFORE or AFTER this nearest corner.

Polygon poly = new Polygon(...);  //javaFX

private void insertPoint(double x, double y)
{
  int positionInPolygon = 0;
  double minDistance = Double.MAX_VALUE;

  //find that point in the existing polygon that is nearest to the new one
  for ( int i = 0; i <= poly.getPoints().size()-1; i += 2 ) 
  {
    double cornerA_x = poly.getPoints().get(i);
    double cornerA_y = poly.getPoints().get(i+1);
    double tmpDistance = distance(x, y, cornerA_x, cornerA_y);
    if(minDistance > tmpDistance)
    {
      minDistance = tmpDistance;
      positionInPolygon = i;
    }
  }
  //Now I have the nearest point in the polygon    
  //But I don't know if I have to insert that new point BEFORE or AFTER the existing one.
  ...
}


private double distance(double x1, double y1, double x2, double y2)
{
  double result = 0;
  result = Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
  return result;
}

This should be the result, to be honest I dindn't find how the polygone that I want as a result is called correctly.

1

Community
  • 1
  • 1
user3354754
  • 79
  • 1
  • 7
  • Just an idea... if you have n points, there are just n spots in between points where to insert the new points. Try each of them, and take the one with the lowest total circumference of the resulting figure. Not sure if this always gives the best result, but it's a start. – tobias_k Feb 26 '14 at 08:46
  • I'm pretty sure that you are looking for the Convex Hull ( http://en.wikipedia.org/wiki/Convex_hull ) of the click positions. There are various algorithms for that (e.g. the "Graham Scan"). You can probably find a Java implementation with these keywords. – Marco13 Feb 26 '14 at 12:00
  • Hello tokias_k, your solution works! Thank you for that hint! – user3354754 Feb 26 '14 at 17:17

1 Answers1

0

Solution taken from the answer:

SOLUTION ADDED IN THE CODE: thanks to tokias_k (calculate circumference to know where to insert the new point)

Polygon poly = new Polygon(...);  //javaFX

private void insertPoint(double x, double y)
{
  int positionInPolygon = 0;
  double minDistance = Double.MAX_VALUE;

  //find that point in the existing polygon that is nearest to the new one
  for ( int i = 0; i <= poly.getPoints().size()-1; i += 2 ) 
  {
    double cornerA_x = poly.getPoints().get(i);
    double cornerA_y = poly.getPoints().get(i+1);
    double tmpDistance = distance(x, y, cornerA_x, cornerA_y);
    if(minDistance > tmpDistance)
    {
      minDistance = tmpDistance;
      positionInPolygon = i;
    }
  }
  //Now I have the nearest point in the polygon    

  //find out if the new point has to be inserted before or after that corner
  int[] pos = new int[2]; 
  pos[0] =positionInPolygon-2;
  pos[1] = positionInPolygon;
  //special points: first one
  if(pos[0] < 0)
    pos[0] = poly.getPoints().size()-2;

  double[] circumference = new double[2];
  for(int i = 0; i < 2; i++)
  {
    ObservableList<Double> tmp = FXCollections.observableArrayList(poly.getPoints());
    tmp.add(pos[i]+2, x);
    tmp.add(pos[i]+3, y);
    circumference[i] = getPolyconCircumference(tmp);
  }
  if(circumference[0] < circumference[1])
  {
    poly.getPoints().add(pos[0]+2, x);
    poly.getPoints().add(pos[0]+3, y);
    drawCircle(x, y, pos[0]);
  }
  else
  {
    poly.getPoints().add((pos[1]+2), x);
    poly.getPoints().add((pos[1]+3), y);
    drawCircle(x, y, pos[1]);
  }
}


private double getPolyconCircumference(List<Double> p)
{
  double result = 0;
  int size = p.size();

  //init with edge between first and last point of the polygon
  result = distance(p.get(size-2), p.get(size-1), 0, 1);

  for ( int i = 0; i <= poly.getPoints().size()-4; i += 2 ) 
  {
    result += distance(p.get(i), p.get(i+1), p.get(i+2), p.get(i+3));
  }
  return result;
}

private double distance(double x1, double y1, double x2, double y2)
{
  double result = 0;
  result = Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
  return result;
}
Community
  • 1
  • 1
bummi
  • 27,123
  • 14
  • 62
  • 101