package com.tilusnet.josm.plugins.alignways.geometry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import org.openstreetmap.josm.data.coor.EastNorth;
public class AlignWaysGeomPoint {
double x;
double y;
public AlignWaysGeomPoint(double x, double y) {
setX(x);
setY(y);
}
public AlignWaysGeomPoint(EastNorth eastNorth) {
this.x = eastNorth.getX();
this.y = eastNorth.getY();
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public static boolean isSetCollinear(ArrayList<AlignWaysGeomPoint> awPts) {
if (awPts.size() <= 1)
return false;
if (awPts.size() == 2)
return true;
else {
// at least 3 points
// First create a line of the first two points in the set
AlignWaysGeomLine line = new AlignWaysGeomLine(awPts.get(0), awPts.get(1));
// ...then check the subsequent points whether they are on the line
for (int i = 2; i < awPts.size(); i++) {
if (!line.isPointOnLine(awPts.get(i))) {
return false;
}
}
return true;
}
}
/**
* Determines which (EastNorth) point falls between the other two.
* Ideally to be used with collinear points.
*
* @return 1, 2 or 3 for pt1, pt2 and pt3, respectively.
* 0 if middle value cannot be determined (i.e. some values are equal).
*/
public static int getMiddleOf3(
AlignWaysGeomPoint pt1,
AlignWaysGeomPoint pt2,
AlignWaysGeomPoint pt3) {
int midPtXIdx = getMiddleOf3(pt1.x, pt2.x, pt3.x);
int midPtYIdx = getMiddleOf3(pt1.y, pt2.y, pt3.y);
if ((midPtXIdx == 0) && (midPtYIdx == 0))
// All 3 points overlap:
// Design decision: return the middle point (could be any other or none)
return 2;
if (midPtXIdx == 0) return midPtYIdx;
if (midPtYIdx == 0) return midPtXIdx;
// Both x and y middle points could be determined;
// their indexes must coincide
if (midPtXIdx == midPtYIdx)
// Success
return midPtXIdx; // (or midPtYIdx)
else
// Fail
return 0;
}
/**
* Determine which value, d1, d2 or d3 falls in the middle of the other two.
* @return 1, 2 or 3 for d1, d2 and d3, respectively.
* 0 if middle value cannot be determined (i.e. some values are equal).
*/
private static int getMiddleOf3(double d1, double d2, double d3) {
Double[] dValues = {d1, d2, d3};
ArrayList<Double> alValues = new ArrayList<>(Arrays.asList(dValues));
Collections.sort(alValues);
if ((Math.abs(alValues.get(1) - alValues.get(0)) < 0.01) ||
(Math.abs(alValues.get(1) - alValues.get(2)) < 0.01))
// Cannot determine absolute middle value
return 0;
else {
if (Math.abs(alValues.get(1) - d1) < 0.01) return 1;
if (Math.abs(alValues.get(1) - d2) < 0.01) return 2;
if (Math.abs(alValues.get(1) - d3) < 0.01) return 3;
}
// Should never happen
return 0;
}
}