More documentation.

This commit is contained in:
Jindra Petřík
2024-08-08 19:27:14 +02:00
parent 5c1811582a
commit f219b49372
394 changed files with 13018 additions and 552 deletions
@@ -35,18 +35,40 @@ import java.util.Stack;
*/
public class BezierEdge implements Serializable {
/**
* Points of the Bezier edge.
*/
public List<Point2D> points = new ArrayList<>(3);
/**
* Points of the Bezier edge in reverse order.
*/
private List<Point2D> revPoints = new ArrayList<>();
/**
* Hash
*/
private int hash;
/**
* Hash of the reverse bezier edge.
*/
private int revHash;
/**
* Bounding box
*/
private Rectangle2D bbox;
/**
* Is the edge empty?
*/
private boolean empty;
/**
* Constructor.
* @param points Points
*/
public BezierEdge(List<Point2D> points) {
this.points = points;
calcParams();
@@ -57,16 +79,36 @@ public class BezierEdge implements Serializable {
return new BezierEdge(new ArrayList<>(points));
}
/**
* Is the edge empty?
* @return True if the edge is empty, false otherwise.
*/
public boolean isEmpty() {
return empty;
}
/**
* Constructor.
* @param x0 Start x
* @param y0 Start y
* @param x1 End x
* @param y1 End y
*/
public BezierEdge(double x0, double y0, double x1, double y1) {
points.add(new Point2D.Double(x0, y0));
points.add(new Point2D.Double(x1, y1));
calcParams();
}
/**
* Constructor.
* @param x0 Start x
* @param y0 Start y
* @param cx Control x
* @param cy Control y
* @param x1 End x
* @param y1 End y
*/
public BezierEdge(double x0, double y0, double cx, double cy, double x1, double y1) {
points.add(new Point2D.Double(x0, y0));
points.add(new Point2D.Double(cx, cy));
@@ -74,24 +116,45 @@ public class BezierEdge implements Serializable {
calcParams();
}
/**
* Gets the begin point.
* @return Begin point
*/
public Point2D getBeginPoint() {
return points.get(0);
}
/**
* Gets the end point.
* @return End point
*/
public Point2D getEndPoint() {
return points.get(points.size() - 1);
}
/**
* Sets the begin point.
* @param p Begin point
*/
public void setBeginPoint(Point2D p) {
points.set(0, p);
calcParams();
}
/**
* Sets the end point.
* @param p End point
*/
public void setEndPoint(Point2D p) {
points.set(points.size() - 1, p);
calcParams();
}
/**
* Gets the point at specified position.
* @param t Position
* @return Point at position
*/
public Point2D pointAt(double t) {
if (points.size() == 2) {
double x = (1 - t) * points.get(0).getX() + t * points.get(1).getX();
@@ -147,12 +210,20 @@ public class BezierEdge implements Serializable {
}
}
/**
* Calculates the bounding box.
* @return Bounding box
*/
public Rectangle2D bbox() {
return bbox;
}
private final double MIN_SIZE = 0.5;
/**
* Calculates the area.
* @return Area
*/
public double area() {
Rectangle2D rect = bbox();
double w = rect.getWidth();
@@ -185,6 +256,11 @@ public class BezierEdge implements Serializable {
return false;
}
/**
* Gets the intersections.
* @param b2 Bezier edge
* @return List of intersections
*/
public List<Point2D> getIntersections(BezierEdge b2) {
if (!Intersections.rectIntersection(bbox, b2.bbox)) {
return new ArrayList<>();
@@ -204,6 +280,13 @@ public class BezierEdge implements Serializable {
}
}
/**
* Gets the intersections. Old version.
* @param b2 Bezier edge 2
* @param t1Ref T1 reference
* @param t2Ref T2 reference
* @return True if the edges intersect, false otherwise
*/
public boolean intersectsOld(BezierEdge b2, List<Double> t1Ref, List<Double> t2Ref) {
List<Point2D> interPoints = new ArrayList<>();
List<Double> t1RefA = new ArrayList<>();
@@ -244,6 +327,14 @@ public class BezierEdge implements Serializable {
return ret;
}
/**
* Checks if the edges intersect.
* @param b2 Bezier edge 2
* @param t1Ref T1 reference
* @param t2Ref T2 reference
* @param intPoints Intersection points
* @return True if the edges intersect, false otherwise
*/
public boolean intersects(BezierEdge b2, List<Double> t1Ref, List<Double> t2Ref, List<Point2D> intPoints) {
List<Point2D> inter = getIntersections(b2);
BezierUtils utils = new BezierUtils();
@@ -327,6 +418,10 @@ public class BezierEdge implements Serializable {
return ok;
}
/**
* Gets the length.
* @return Length
*/
public double length() {
double distance = 0;
double epsilon = 1;
@@ -359,6 +454,10 @@ public class BezierEdge implements Serializable {
return "{" + String.join("-", list) + "}";
}
/**
* Converts the edge to SVG.
* @return SVG string
*/
public String toSvg() {
DecimalFormat df = new DecimalFormat("0.###", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
@@ -387,6 +486,12 @@ public class BezierEdge implements Serializable {
return ret;
}
/**
* Splits the edge.
* @param t Position
* @param left Left edge
* @param right Right edge
*/
public void split(double t, Reference<BezierEdge> left, Reference<BezierEdge> right) {
List<Point2D> leftPoints = new ArrayList<>();
List<Point2D> rightPoints = new ArrayList<>();
@@ -397,10 +502,18 @@ public class BezierEdge implements Serializable {
right.setVal(new BezierEdge(rightPoints));
}
/**
* Reverses the edge.
* @return Reversed edge
*/
public BezierEdge reverse() {
return new BezierEdge(revPoints);
}
/**
* Rounds the edge.
*/
public void round() {
for (int i = 0; i < this.points.size(); i++) {
this.points.set(i, new Point2D.Double(
@@ -411,6 +524,9 @@ public class BezierEdge implements Serializable {
calcParams();
}
/**
* Rounds the edge to half.
*/
public void roundHalf() {
for (int i = 0; i < this.points.size(); i++) {
this.points.set(i, new Point2D.Double(
@@ -446,6 +562,11 @@ public class BezierEdge implements Serializable {
return Objects.equals(this.points, other.points);
}
/**
* Checks if the edge is equal to another edge in reverse order.
* @param other Other edge
* @return True if the edges are equal in reverse order, false otherwise
*/
public boolean equalsReverse(BezierEdge other) {
if (hash != other.revHash) {
return false;
@@ -461,6 +582,10 @@ public class BezierEdge implements Serializable {
return true;
}
/**
* Test main.
* @param args Arguments
*/
public static void main(String[] args) {
List<Double> t1 = new ArrayList<>();
List<Double> t2 = new ArrayList<>();
@@ -33,12 +33,35 @@ public class BezierUtils {
private static final double[] Z_QUAD = new double[]{1.0, 2.0 / 3.0, 1.0 / 3.0, 1 / 3.0, 2.0 / 3.0, 1.0};
private static final double EPSILON = 1.0 * Math.pow(2, -MAX_DEPTH - 1); // flatness tolerance
/**
* Constructor.
*/
public BezierUtils() {
}
/**
* Calculate point at t.
* @param t Position
* @param p0 Start point
* @param p1 Control point
* @param p2 End point
* @return Point
*/
public Point2D pointAt(double t, Point2D p0, Point2D p1, Point2D p2) {
double xt = (1 - t) * (1 - t) * p0.getX() + 2 * (1 - t) * t * p1.getX() + t * t * p2.getX();
double yt = (1 - t) * (1 - t) * p0.getY() + 2 * (1 - t) * t * p1.getY() + t * t * p2.getY();
return new Point2D.Double(xt, yt);
}
/**
* Calculate closest point to bezier.
* @param _p Point
* @param p0 Start point
* @param p1 Control point
* @param p2 End point
* @return Position
*/
public double closestPointToBezier(Point2D _p, Point2D p0, Point2D p1, Point2D p2) {
Point2D p = p0;
double deltaX = p.getX() - _p.getX();
@@ -30,6 +30,12 @@ import java.util.List;
*/
public class Distances {
/**
* Get distance between two batches of Bezier edges.
* @param batch1 Batch of Bezier edges 1
* @param batch2 Batch of Bezier edges 2
* @return Distance between two batches of Bezier edges
*/
public static double getBatchDistance(List<BezierEdge> batch1, List<BezierEdge> batch2) {
Area a1 = batchToArea(batch1);
Area a2 = batchToArea(batch2);
@@ -138,10 +138,25 @@ public class Intersections {
}
}
/**
* Convert quadratic bezier curve to polyline.
* @param p1 Start point
* @param p2 Control point
* @param p3 End point
* @return
*/
public static List<Point2D> quadraticBezierToToPolyline(Point2D p1, Point2D p2, Point2D p3) {
return quadraticBezierToToPolyline(p1, p2, p3, null);
}
/**
* Convert quadratic bezier curve to polyline.
* @param p1 Start point
* @param p2 Control point
* @param p3 End point
* @param flatness Flatness
* @return List of points
*/
public static List<Point2D> quadraticBezierToToPolyline(Point2D p1, Point2D p2, Point2D p3, Double flatness) {
List<Point2D> points = new ArrayList<>();
Point2D zeroVector = new Point2D.Double(0, 0);
@@ -160,12 +175,28 @@ public class Intersections {
return points;
}
/**
* Gets intersection of two quadratic bezier curves.
* @param a1 Start point of first curve
* @param a2 Control point of first curve
* @param a3 End point of first curve
* @param b1 Start point of second curve
* @param b2 Control point of second curve
* @param b3 End point of second curve
* @return List of intersection points
*/
public static List<Point2D> intersectBezier2Bezier2Slow(Point2D a1, Point2D a2, Point2D a3, Point2D b1, Point2D b2, Point2D b3) {
List<Point2D> a = quadraticBezierToToPolyline(a1, a2, a3, FLATNESS);
List<Point2D> b = quadraticBezierToToPolyline(b1, b2, b3, FLATNESS);
return intersectPolylinePolyline(a, b);
}
/**
* Checks intersection of two rectangles.
* @param r1 Rectangle 1
* @param r2 Rectangle 2
* @return True if rectangles intersect
*/
public static boolean rectIntersection(Rectangle2D r1, Rectangle2D r2) {
double xmin = Math.max(r1.getX(), r2.getX());
double xmax1 = r1.getX() + r1.getWidth();
@@ -183,6 +214,11 @@ public class Intersections {
return false;
}
/**
* Gets bounding box of points.
* @param points Points
* @return Bounding box
*/
public static Rectangle2D getBBox(Point2D... points) {
double minX = Double.MAX_VALUE;
double minY = Double.MAX_VALUE;
@@ -206,6 +242,16 @@ public class Intersections {
return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
}
/**
* Gets intersection of two quadratic bezier curves.
* @param a1 Start point of first curve
* @param a2 Control point of first curve
* @param a3 End point of first curve
* @param b1 Start point of second curve
* @param b2 Control point of second curve
* @param b3 End point of second curve
* @return List of intersection points
*/
public static List<Point2D> intersectBezier2Bezier2(Point2D a1, Point2D a2, Point2D a3, Point2D b1, Point2D b2, Point2D b3) {
Point2D pa;
Point2D pb;
@@ -322,11 +368,29 @@ public class Intersections {
return p1.getX() * p2.getX() + p1.getY() * p2.getY();
}
/**
* Gets intersection of quadratic bezier curve and line. Slow version.
* @param p1 Start point of bezier curve
* @param p2 Control point of bezier curve
* @param p3 End point of bezier curve
* @param a1 Start point of line
* @param a2 End point of line
* @return List of intersection points
*/
public static List<Point2D> intersectBezier2LineSlow(Point2D p1, Point2D p2, Point2D p3, Point2D a1, Point2D a2) {
List<Point2D> p = quadraticBezierToToPolyline(p1, p2, p3, FLATNESS);
return intersectLinePolyline(a1, a2, p);
}
/**
* Gets intersection of quadratic bezier curve and line.
* @param p1 Start point of bezier curve
* @param p2 Control point of bezier curve
* @param p3 End point of bezier curve
* @param a1 Start point of line
* @param a2 End point of line
* @return List of intersection points
*/
public static List<Point2D> intersectBezier2Line(Point2D p1, Point2D p2, Point2D p3, Point2D a1, Point2D a2) {
Point2D a; // temporary variables
Point2D min = min(a1, a2); // used to determine if point is on line segment
@@ -405,6 +469,15 @@ public class Intersections {
return result;
}
/**
* Gets intersection of line and line.
* @param a1 Start point of first line
* @param a2 End point of first line
* @param b1 Start point of second line
* @param b2 End point of second line
* @param addCoincident Add coincident points
* @return List of intersection points
*/
public static List<Point2D> intersectLineLine(Point2D a1, Point2D a2, Point2D b1, Point2D b2, boolean addCoincident) {
List<Point2D> result = new ArrayList<>();
@@ -32,6 +32,10 @@ public class Polynomial {
private String _variable;
private int _s;
/**
* Constructor.
* @param coefs Coefficients of the polynomial
*/
public Polynomial(List<Double> coefs) {
this.coefs = new double[coefs.size()];
@@ -43,6 +47,10 @@ public class Polynomial {
this._s = 0;
}
/**
* Get the degree of the polynomial.
* @return Degree of the polynomial
*/
public int getDegree() {
return this.coefs.length - 1;
}
@@ -228,10 +236,19 @@ public class Polynomial {
return result;
}
/**
* Estimate the error of the polynomial.
* @return Error estimate
*/
public double zeroErrorEstimate() {
return zeroErrorEstimate(null);
}
/**
* Estimate the error of the polynomial.
* @param maxAbsX Maximum absolute value of x
* @return Error estimate
*/
public double zeroErrorEstimate(Double maxAbsX) {
Polynomial poly = this;
double ERRF = 1e-15;
@@ -260,6 +277,10 @@ public class Polynomial {
return x;
}
/**
* Gets the roots of the polynomial.
* @return List of roots
*/
public List<Double> getCubicRoots() {
List<Double> results = new ArrayList<>();
@@ -330,10 +351,17 @@ public class Polynomial {
return results;
}
/**
* Simplify the polynomial.
*/
public void simplifyEquals() {
simplifyEquals(1e-12);
}
/**
* Simplify the polynomial.
* @param tolerance Tolerance
*/
public void simplifyEquals(double tolerance) {
for (int i = this.getDegree(); i >= 0; i--) {
if (Math.abs(this.coefs[i]) <= tolerance) {
@@ -365,6 +393,10 @@ public class Polynomial {
return pol;
}
/**
* Get the roots of the polynomial.
* @return List of roots
*/
public List<Double> getRoots() {
List<Double> result;