package warbot.chevri_t;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class GeoUtil
{
public static double angleBetween2Lines(Point2D line1S, Point2D line1E,
Point2D line2S, Point2D line2E) {
if (line1S == null || line1E == null || line2S == null || line2E == null)
return 90;
double angle1 = Math.atan2(line1S.getY() - line1E.getY(), line1S.getX()
- line1E.getX());
double angle2 = Math.atan2(line2S.getY() - line2E.getY(), line2S.getX()
- line2E.getX());
return Math.abs(Math.toDegrees(angle1 - angle2));
}
public static boolean areCircleLineIntersected(Point2D pointA,
Point2D pointB, Point2D center, double radius) {
double baX = pointB.getX() - pointA.getX();
double baY = pointB.getY() - pointA.getY();
double caX = center.getX() - pointA.getX();
double caY = center.getY() - pointA.getY();
double a = baX * baX + baY * baY;
double bBy2 = baX * caX + baY * caY;
double c = caX * caX + caY * caY - radius * radius;
double pBy2 = bBy2 / a;
double q = c / a;
double disc = pBy2 * pBy2 - q;
return disc >= 0;
}
public static boolean areCircleSegmentIntersected(Point2D pointA,
Point2D pointB, Point2D center, double radius) {
List<Point2D> list = getCircleLineIntersectionPoint(pointA, pointB, center,
radius);
for (Point2D point : list)
if (point.getX() <= pointA.getX() && point.getX() >= pointB.getX()
|| point.getX() >= pointA.getX() && point.getX() <= pointB.getX())
if (point.getY() <= pointA.getY() && point.getY() >= pointB.getY()
|| point.getY() >= pointA.getY() && point.getY() <= pointB.getY())
return true;
return false;
}
/**
*
* @param oneS
* User position
* @param oneE
* User target
* @param twoS
* Foe position
* @param twoE
* Foe target
* @return
*/
public static boolean areLineLineIntersected(Point2D oneS, Point2D oneE,
Point2D twoS, Point2D twoE, int MaxDistIntersec) {
if (oneS == null || oneE == null || twoS == null || twoE == null)
return false;
double det1And2 = det(oneS.getX(), oneS.getY(), oneE.getX(), oneE.getY());
double det3And4 = det(twoS.getX(), twoS.getY(), twoE.getX(), twoE.getY());
double x1LessX2 = oneS.getX() - oneE.getX();
double y1LessY2 = oneS.getY() - oneE.getY();
double x3LessX4 = twoS.getX() - twoE.getX();
double y3LessY4 = twoS.getY() - twoE.getY();
double det1Less2And3Less4 = det(x1LessX2, y1LessY2, x3LessX4, y3LessY4);
if (det1Less2And3Less4 == 0)
return false;
double x = det(det1And2, x1LessX2, det3And4, x3LessX4) / det1Less2And3Less4;
double y = det(det1And2, y1LessY2, det3And4, y3LessY4) / det1Less2And3Less4;
Point2D inter = new Point2D.Double(x, y);
return inter.distance(oneS) < MaxDistIntersec;
}
public static boolean areSegmentSegmentIntersected(Point2D As, Point2D Ae,
Point2D Bs, Point2D Be) {
double x1 = As.getX(), x2 = Ae.getX(), x3 = Bs.getX(), x4 = Be.getX(), y1 = As
.getY(), y2 = Ae.getY(), y3 = Bs.getY(), y4 = Be.getY();
double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
if (d == 0)
return false;
double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2)
* (x3 * y4 - y3 * x4))
/ d;
if (xi < Math.min(x1, x2) || xi > Math.max(x1, x2))
return false;
if (xi < Math.min(x3, x4) || xi > Math.max(x3, x4))
return false;
return true;
}
public static List<Point2D> getCircleLineIntersectionPoint(Point2D pointA,
Point2D pointB, Point2D center, double radius) {
double baX = pointB.getX() - pointA.getX();
double baY = pointB.getY() - pointA.getY();
double caX = center.getX() - pointA.getX();
double caY = center.getY() - pointA.getY();
double a = baX * baX + baY * baY;
double bBy2 = baX * caX + baY * caY;
double c = caX * caX + caY * caY - radius * radius;
double pBy2 = bBy2 / a;
double q = c / a;
double disc = pBy2 * pBy2 - q;
if (disc < 0)
return Collections.emptyList();
// if disc == 0 ... dealt with later
double tmpSqrt = Math.sqrt(disc);
double abScalingFactor1 = -pBy2 + tmpSqrt;
double abScalingFactor2 = -pBy2 - tmpSqrt;
Point2D p1 = new Point2D.Double(pointA.getX() - baX * abScalingFactor1,
pointA.getY() - baY * abScalingFactor1);
if (disc == 0)
return Collections.singletonList(p1);
Point2D p2 = new Point2D.Double(pointA.getX() - baX * abScalingFactor2,
pointA.getY() - baY * abScalingFactor2);
return Arrays.asList(p1, p2);
}
public static Point2D getLineLineIntersection(Point2D oneS, Point2D oneE,
Point2D twoS, Point2D twoE) {
double det1And2 = det(oneS.getX(), oneS.getY(), oneE.getX(), oneE.getY());
double det3And4 = det(twoS.getX(), twoS.getY(), twoE.getX(), twoE.getY());
double x1LessX2 = oneS.getX() - oneE.getX();
double y1LessY2 = oneS.getY() - oneE.getY();
double x3LessX4 = twoS.getX() - twoE.getX();
double y3LessY4 = twoS.getY() - twoE.getY();
double det1Less2And3Less4 = det(x1LessX2, y1LessY2, x3LessX4, y3LessY4);
if (det1Less2And3Less4 == 0)
// the denominator is zero so the lines are parallel and there's either no
// solution (or multiple solutions if the lines overlap) so return null.
return null;
double x = det(det1And2, x1LessX2, det3And4, x3LessX4) / det1Less2And3Less4;
double y = det(det1And2, y1LessY2, det3And4, y3LessY4) / det1Less2And3Less4;
return new Point2D.Double(x, y);
}
public static ArrayList<MobileFoe> getLocalFoes(MobileFoes foes,
double minDistance, Point2D target) {
ArrayList<MobileFoe> result = new ArrayList<MobileFoe>();
if (foes == null || target == null)
return result;
for (MobileFoe f : foes)
if (!f.getType().equals(MobileFoe.Type.Explorer)
&& f.getPosition().distance(target) < minDistance)
result.add(f);
return result;
}
public static Obstacles getLocalObstacles(Obstacles obs, double minDistance,
Point2D target) {
Obstacles result = new Obstacles();
if (obs == null || target == null)
return result;
for (Obstacle o : obs)
if (o.getPos().distance(target) < minDistance)
result.add(o);
return result;
}
private static double det(double a, double b, double c, double d) {
return a * d - b * c;
}
}