我在网上找到了一个解决方案,我已经对其进行了调整,并进行了手动测试。
自带的,只需要import java.awt.geom.Point2D
/**
* Test if the first point lies in the bounding box denote by the other two
* points.
*/
public static boolean isBetween(Point2D pToTest, Point2D p1, Point2D p2) {
return isBetween(pToTest.getX(), pToTest.getY(), p1.getX(), p1.getY(), p2.getX(), p2.getY());
}
/**
* Called {@link #isBetween(Point2D, Point2D, Point2D)} passing those points
* coordinates.
*/
public static boolean isBetween(double pxToTest, double pyToTest, double px1, double py1, double px2, double py2) {
double w, h;
// taking inspiration from Rectangle's class
w = px1 - px2;
if (w < 0)
w = -w;
h = py1 - py2;
if (h < 0)
h = -h;
// use p1 as the left-top corner of the rectangle
// (the left-top corner is considered as the origin (0;0))
if (px1 > px2)
px1 = px2;//
if (py1 > py2)
py1 = py2;//
if (pxToTest < px1 || pyToTest < py1) {
return false;
}
w += px1;
h += py1;
// overflow || intersect
return ((w < px1 || w > pxToTest) && (h < py1 || h > pyToTest));
}
public static double slope(double xa, double ya, double xb, double yb) {
if (xb == xa)
return Double.POSITIVE_INFINITY;
return (yb == ya) ? 0.0 : ((yb - ya) / (xb - xa));
}
/**
* Called by {@link #areLinesIntersecting(Point2D, Point2D, Point2D, Point2D)}
* by providing each of those point's coordinates.
*/
public static Point2D areLinesIntersecting(double pxStart1, double pyStart1, double pxEnd1, double pyEnd1,
double pxStart2, double pyStart2, double pxEnd2, double pyEnd2) {
double slope_ab, slope_cd, numerator, denominator, q_ab, q_cd, x, y;
Point2D p;
slope_ab = slope(pxStart1, pyStart1, pxEnd1, pyEnd1);
slope_cd = slope(pxStart2, pyStart2, pxEnd2, pyEnd2);
q_ab = (pyStart1 - slope_ab * pxStart1);
q_cd = (pyStart2 - slope_cd * pxStart2);
if ((slope_ab == slope_cd) // parallel?
&& (
// overlapping?
((slope_ab == Double.POSITIVE_INFINITY || slope_ab == Double.NaN) && pxStart1 == pxStart2) //
|| //
// overlapping?
(slope_ab == 0.0 && pyStart1 == pyStart2) //
|| //
// if different costant parts of lines, then parallel BUT not overlapping
(q_ab == q_cd)//
)) {
if (isBetween(pxStart2, pyStart2, pxStart1, pyStart1, pxEnd1, pyEnd1))
return new Point2D.Double(pxStart2, pyStart2);
if (isBetween(pxEnd2, pyEnd2, pxStart1, pyStart1, pxEnd1, pyEnd1))
return new Point2D.Double(pxEnd2, pyEnd2);
if (isBetween(pxStart1, pyStart1, pxStart2, pyStart2, pxEnd2, pyEnd2))
return new Point2D.Double(pxStart1, pyStart1);
if (isBetween(pxEnd1, pyEnd1, pxStart2, pyStart2, pxEnd2, pyEnd2))
return new Point2D.Double(pxEnd1, pyEnd1);
}
if (slope_ab == Double.POSITIVE_INFINITY) {
// ab vertical line: all a&b's x-es are equals
x = pxStart1;
y = (q_cd + (slope_cd * x));
// it's a cross
if ((pyStart1 <= pyEnd1) ? (y < pyStart1 || y > pyEnd1)
// point are reversed
: (y > pyStart1 || y < pyEnd1))
return null;
if ((pxStart2 < pxEnd2) ? (pxStart2 <= x && x <= pxEnd2)//
: (pxEnd2 <= x && x <= pxStart2))
return new Point2D.Double(x, y);
else
return null;
}
if (slope_cd == Double.POSITIVE_INFINITY) {
// cd vertical line: all c&d's x-es are equals
x = pxStart2;
y = (q_ab + (slope_ab * x));
// it's a cross
if ((pyStart2 <= pyEnd2) ? (y < pyStart2 || y > pyEnd2)
// point are reversed
: (y > pyStart2 || y < pyEnd2))
return null;
// if the y lies inside the line a-b, then intersection
if ((pxStart1 < pxEnd1) ? (pxStart1 <= x && x <= pxEnd1)//
: (pxEnd1 <= x && x <= pxStart1))
return new Point2D.Double(x, y);
else
return null;
}
// slopes cannot be infinity
if (slope_ab == 0.0) {
y = pyStart1;
// slope_cd cannot be Infinity (second group of checks) and zero (first ones)
x = (y - q_cd) / slope_cd;
if ((pxStart1 <= pxEnd1) ? (x < pxStart1 || x > pxEnd1)
// point are reversed
: (x > pxStart1 || x < pxEnd1))
return null;
if ((pxStart2 <= pxEnd2) ? (x < pxStart2 || x > pxEnd2)
// point are reversed
: (x > pxStart2 || x < pxEnd2))
return null;
if ((pyStart2 < pyEnd2) ? (pyStart2 <= y && y <= pyEnd2)//
: (pyEnd2 <= y && y <= pyStart2))
return new Point2D.Double(x, y);
else
return null;
}
if (slope_cd == 0.0) {
y = pyStart2;
// slope_ab cannot be Infinity (second group of checks) and zero (first ones)
x = (y - q_ab) / slope_ab;
if ((pxStart2 <= pxEnd2) ? (x < pxStart2 || x > pxEnd2)
// point are reversed
: (x > pxStart2 || x < pxEnd2))
return null;
if ((pxStart1 <= pxEnd1) ? (x < pxStart1 || x > pxEnd1)
// point are reversed
: (x > pxStart1 || x < pxEnd1))
return null;
if ((pyStart1 < pyEnd1) ? (pyStart1 <= y && y <= pyEnd1)//
: (pyEnd1 <= y && y <= pyStart1))
return new Point2D.Double(x, y);
else
return null;
}
denominator = slope_cd - slope_ab;
numerator = q_ab - q_cd;
x = (numerator / denominator);
y = (q_ab + (slope_ab * x));
p = new Point2D.Double(x, y);
if (isBetween(p.getX(), p.getY(), pxStart1, pyStart1, pxEnd1, pyEnd1)
&& isBetween(p.getX(), p.getY(), pxStart2, pyStart2, pxEnd2, pyEnd2))
return p;
y = (q_cd + (slope_cd * x));
p = new Point2D.Double(x, y);
if ((isBetween(p.getX(), p.getY(), pxStart1, pyStart1, pxEnd1, pyEnd1)
&& isBetween(p.getX(), p.getY(), pxStart2, pyStart2, pxEnd2, pyEnd2)))
return p;
return null;
}