mirror of
https://github.com/octoleo/plantuml.git
synced 2024-09-22 03:59:03 +00:00
133 lines
3.9 KiB
Java
133 lines
3.9 KiB
Java
package net.sourceforge.plantuml.awt.geom;
|
|
|
|
import net.sourceforge.plantuml.awt.XShape;
|
|
|
|
public class XLine2D implements XShape {
|
|
|
|
final public double x1;
|
|
final public double y1;
|
|
final public double x2;
|
|
final public double y2;
|
|
|
|
public XLine2D() {
|
|
this(0, 0, 0, 0);
|
|
}
|
|
|
|
public XLine2D(double x1, double y1, double x2, double y2) {
|
|
this.x1 = x1;
|
|
this.y1 = y1;
|
|
this.x2 = x2;
|
|
this.y2 = y2;
|
|
|
|
}
|
|
|
|
public XPoint2D getMiddle() {
|
|
final double mx = (this.x1 + this.x2) / 2;
|
|
final double my = (this.y1 + this.y2) / 2;
|
|
return new XPoint2D(mx, my);
|
|
}
|
|
|
|
public XLine2D(XPoint2D p1, XPoint2D p2) {
|
|
this(p1.getX(), p1.getY(), p2.getX(), p2.getY());
|
|
}
|
|
|
|
public final double getX1() {
|
|
return x1;
|
|
}
|
|
|
|
public final double getY1() {
|
|
return y1;
|
|
}
|
|
|
|
public final double getX2() {
|
|
return x2;
|
|
}
|
|
|
|
public final double getY2() {
|
|
return y2;
|
|
}
|
|
|
|
public XPoint2D getP1() {
|
|
return new XPoint2D(x1, y1);
|
|
}
|
|
|
|
public XPoint2D getP2() {
|
|
return new XPoint2D(x2, y2);
|
|
}
|
|
|
|
public XLine2D withPoint1(XPoint2D other) {
|
|
return new XLine2D(other.x, other.y, x2, y2);
|
|
}
|
|
|
|
public XLine2D withPoint2(XPoint2D other) {
|
|
return new XLine2D(x1, y1, other.x, other.y);
|
|
}
|
|
|
|
/**
|
|
* Returns the square of the distance from a point to a line segment. The
|
|
* distance measured is the distance between the specified point and the closest
|
|
* point between the specified end points. If the specified point intersects the
|
|
* line segment in between the end points, this method returns 0.0.
|
|
*
|
|
* @param x1 the X coordinate of the start point of the specified line segment
|
|
* @param y1 the Y coordinate of the start point of the specified line segment
|
|
* @param x2 the X coordinate of the end point of the specified line segment
|
|
* @param y2 the Y coordinate of the end point of the specified line segment
|
|
* @param px the X coordinate of the specified point being measured against the
|
|
* specified line segment
|
|
* @param py the Y coordinate of the specified point being measured against the
|
|
* specified line segment
|
|
* @return a double value that is the square of the distance from the specified
|
|
* point to the specified line segment.
|
|
* @see #ptLineDistSq(double, double, double, double, double, double)
|
|
* @since 1.2
|
|
*/
|
|
public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px, double py) {
|
|
// Adjust vectors relative to x1,y1
|
|
// x2,y2 becomes relative vector from x1,y1 to end of segment
|
|
x2 -= x1;
|
|
y2 -= y1;
|
|
// px,py becomes relative vector from x1,y1 to test point
|
|
px -= x1;
|
|
py -= y1;
|
|
double dotprod = px * x2 + py * y2;
|
|
double projlenSq;
|
|
if (dotprod <= 0.0) {
|
|
// px,py is on the side of x1,y1 away from x2,y2
|
|
// distance to segment is length of px,py vector
|
|
// "length of its (clipped) projection" is now 0.0
|
|
projlenSq = 0.0;
|
|
} else {
|
|
// switch to backwards vectors relative to x2,y2
|
|
// x2,y2 are already the negative of x1,y1=>x2,y2
|
|
// to get px,py to be the negative of px,py=>x2,y2
|
|
// the dot product of two negated vectors is the same
|
|
// as the dot product of the two normal vectors
|
|
px = x2 - px;
|
|
py = y2 - py;
|
|
dotprod = px * x2 + py * y2;
|
|
if (dotprod <= 0.0) {
|
|
// px,py is on the side of x2,y2 away from x1,y1
|
|
// distance to segment is length of (backwards) px,py vector
|
|
// "length of its (clipped) projection" is now 0.0
|
|
projlenSq = 0.0;
|
|
} else {
|
|
// px,py is between x1,y1 and x2,y2
|
|
// dotprod is the length of the px,py vector
|
|
// projected on the x2,y2=>x1,y1 vector times the
|
|
// length of the x2,y2=>x1,y1 vector
|
|
projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
|
|
}
|
|
}
|
|
// Distance to line is now the length of the relative point
|
|
// vector minus the length of its projection onto the line
|
|
// (which is zero if the projection falls outside the range
|
|
// of the line segment).
|
|
double lenSq = px * px + py * py - projlenSq;
|
|
if (lenSq < 0) {
|
|
lenSq = 0;
|
|
}
|
|
return lenSq;
|
|
}
|
|
}
|