📄 quadcurve2d.java
字号:
public abstract Point2D getP1(); /** * Returns the x coordinate of the control point in * <code>double</code> precision. * @return x coordinate the control point */ public abstract double getCtrlX(); /** * Returns the y coordinate of the control point in * <code>double</code> precision. * @return the y coordinate of the control point. */ public abstract double getCtrlY(); /** * Returns the control point. * @return a <code>Point2D</code> that is the control point of this * <code>Point2D</code>. */ public abstract Point2D getCtrlPt(); /** * Returns the x coordinate of the end point in * <code>double</code> precision. * @return the x coordiante of the end point. */ public abstract double getX2(); /** * Returns the y coordinate of the end point in * <code>double</code> precision. * @return the y coordinate of the end point. */ public abstract double getY2(); /** * Returns the end point. * @return a <code>Point</code> object that is the end point * of this <code>Point2D</code>. */ public abstract Point2D getP2(); /** * Sets the location of the endpoints and controlpoint of this curve * to the specified <code>double</code> coordinates. * @param x1, y1 the coordinates of the starting point * @param ctrlx, ctrly the coordinates of the control point * @param x2, y2 the coordinates of the ending point */ public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2); /** * Sets the location of the endpoints and controlpoints of this * <code>QuadCurve2D</code> to the <code>double</code> coordinates at * the specified offset in the specified array. * @param coords the array containing coordinate values * @param offset the index into the array from which to start * getting the coordinate values and assigning them to this * <code>QuadCurve2D</code> */ public void setCurve(double[] coords, int offset) { setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3], coords[offset + 4], coords[offset + 5]); } /** * Sets the location of the endpoints and controlpoint of this * <code>QuadCurve2D</code> to the specified <code>Point2D</code> * coordinates. * @param p1 the starting point * @param cp the control point * @param p2 the ending point */ public void setCurve(Point2D p1, Point2D cp, Point2D p2) { setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY()); } /** * Sets the location of the endpoints and controlpoints of this * <code>QuadCurve2D</code> to the coordinates of the * <code>Point2D</code> objects at the specified offset in * the specified array. * @param pts an array containing <code>Point2D</code> that define * coordinate values * @param offset the index into <code>pts</code> at which to start * getting the coordinate values and assigning them to this * <code>QuadCurve2D</code> */ public void setCurve(Point2D[] pts, int offset) { setCurve(pts[offset + 0].getX(), pts[offset + 0].getY(), pts[offset + 1].getX(), pts[offset + 1].getY(), pts[offset + 2].getX(), pts[offset + 2].getY()); } /** * Sets the location of the endpoints and controlpoint of this * <code>QuadCurve2D</code> to the same as those in the specified * <code>QuadCurve2D</code>. * @param c the specified <code>QuadCurve2D</code> */ public void setCurve(QuadCurve2D c) { setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(), c.getY2()); } /** * Returns the square of the flatness, or maximum distance of a * controlpoint from the line connecting the endpoints, of the * quadratic curve specified by the indicated controlpoints. * @param x1, y1 the coordinates of the starting point * @param ctrlx, ctrly the coordinates of the control point * @param x2, y2 the coordinates of the ending point * @return the square of the flatness of the quadratic curve * defined by the specified coordinates. */ public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) { return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly); } /** * Returns the flatness, or maximum distance of a * controlpoint from the line connecting the endpoints, of the * quadratic curve specified by the indicated controlpoints. * @param x1, y1 the coordinates of the starting point * @param ctrlx, ctrly the coordinates of the control point * @param x2, y2 the coordinates of the ending point * @return the flatness of the quadratic curve defined by the * specified coordinates. */ public static double getFlatness(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) { return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly); } /** * Returns the square of the flatness, or maximum distance of a * controlpoint from the line connecting the endpoints, of the * quadratic curve specified by the controlpoints stored in the * indicated array at the indicated index. * @param coords an array containing coordinate values * @param offset the index into <code>coords</code> at which to * to start getting the values from the array and * assigning them to a quadratic curve * @return the flatness of the quadratic curve that is defined by the * values in the specified array at the specified index. */ public static double getFlatnessSq(double coords[], int offset) { return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], coords[offset + 4], coords[offset + 5], coords[offset + 2], coords[offset + 3]); } /** * Returns the flatness, or maximum distance of a * controlpoint from the line connecting the endpoints, of the * quadratic curve specified by the controlpoints stored in the * indicated array at the indicated index. * @param coords an array containing coordinate values * @param offset the index into <code>coords</code> at which to * start getting the coordinate values and assigning * them to a quadratic curve * @return the flatness of a quadratic curve defined by the * specified array at the specified offset. */ public static double getFlatness(double coords[], int offset) { return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1], coords[offset + 4], coords[offset + 5], coords[offset + 2], coords[offset + 3]); } /** * Returns the square of the flatness, or maximum distance of a * controlpoint from the line connecting the endpoints, of this * <code>QuadCurve2D</code>. * @return the square of the flatness of this * <code>QuadCurve2D</code>. */ public double getFlatnessSq() { return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY()); } /** * Returns the flatness, or maximum distance of a * controlpoint from the line connecting the endpoints, of this * <code>QuadCurve2D</code>. * @return the flatness of this <code>QuadCurve2D</code>. */ public double getFlatness() { return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY()); } /** * Subdivides this <code>QuadCurve2D</code> and stores the resulting * two subdivided curves into the <code>left</code> and * <code>right</code> curve parameters. * Either or both of the <code>left</code> and <code>right</code> * objects can be the same as this <code>QuadCurve2D</code> or * <code>null</code>. * @param left the <code>QuadCurve2D</code> object for storing the * left or first half of the subdivided curve * @param right the <code>QuadCurve2D</code> object for storing the * right or second half of the subdivided curve */ public void subdivide(QuadCurve2D left, QuadCurve2D right) { subdivide(this, left, right); } /** * Subdivides the quadratic curve specified by the <code>src</code> * parameter and stores the resulting two subdivided curves into the * <code>left</code> and <code>right</code> curve parameters. * Either or both of the <code>left</code> and <code>right</code> * objects can be the same as the <code>src</code> object or * <code>null</code>. * @param src the quadratic curve to be subdivided * @param left the <code>QuadCurve2D</code> object for storing the * left or first half of the subdivided curve * @param right the <code>QuadCurve2D</code> object for storing the * right or second half of the subdivided curve */ public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) { double x1 = src.getX1(); double y1 = src.getY1(); double ctrlx = src.getCtrlX(); double ctrly = src.getCtrlY(); double x2 = src.getX2(); double y2 = src.getY2(); double ctrlx1 = (x1 + ctrlx) / 2.0; double ctrly1 = (y1 + ctrly) / 2.0; double ctrlx2 = (x2 + ctrlx) / 2.0; double ctrly2 = (y2 + ctrly) / 2.0; ctrlx = (ctrlx1 + ctrlx2) / 2.0; ctrly = (ctrly1 + ctrly2) / 2.0; if (left != null) { left.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx, ctrly); } if (right != null) { right.setCurve(ctrlx, ctrly, ctrlx2, ctrly2, x2, y2); } } /** * Subdivides the quadratic curve specified by the coordinates * stored in the <code>src</code> array at indices * <code>srcoff</code> through <code>srcoff</code> + 5 * and stores the resulting two subdivided curves into the two * result arrays at the corresponding indices. * Either or both of the <code>left</code> and <code>right</code> * arrays can be <code>null</code> or a reference to the same array * and offset as the <code>src</code> array. * Note that the last point in the first subdivided curve is the * same as the first point in the second subdivided curve. Thus, * it is possible to pass the same array for <code>left</code> and * <code>right</code> and to use offsets such that * <code>rightoff</code> equals <code>leftoff</code> + 4 in order * to avoid allocating extra storage for this common point. * @param src the array holding the coordinates for the source curve * @param srcoff the offset into the array of the beginning of the * the 6 source coordinates * @param left the array for storing the coordinates for the first * half of the subdivided curve * @param leftoff the offset into the array of the beginning of the * the 6 left coordinates * @param right the array for storing the coordinates for the second * half of the subdivided curve * @param rightoff the offset into the array of the beginning of the * the 6 right coordinates */ public static void subdivide(double src[], int srcoff, double left[], int leftoff, double right[], int rightoff) { double x1 = src[srcoff + 0]; double y1 = src[srcoff + 1]; double ctrlx = src[srcoff + 2]; double ctrly = src[srcoff + 3]; double x2 = src[srcoff + 4]; double y2 = src[srcoff + 5]; if (left != null) { left[leftoff + 0] = x1; left[leftoff + 1] = y1; } if (right != null) { right[rightoff + 4] = x2; right[rightoff + 5] = y2; } x1 = (x1 + ctrlx) / 2.0; y1 = (y1 + ctrly) / 2.0; x2 = (x2 + ctrlx) / 2.0; y2 = (y2 + ctrly) / 2.0; ctrlx = (x1 + x2) / 2.0; ctrly = (y1 + y2) / 2.0; if (left != null) { left[leftoff + 2] = x1; left[leftoff + 3] = y1; left[leftoff + 4] = ctrlx; left[leftoff + 5] = ctrly; } if (right != null) { right[rightoff + 0] = ctrlx; right[rightoff + 1] = ctrly; right[rightoff + 2] = x2; right[rightoff + 3] = y2; } } /** * Solves the quadratic whose coefficients are in the <code>eqn</code> * array and places the non-complex roots back into the same array, * returning the number of roots. The quadratic solved is represented * by the equation: * <pre> * eqn = {C, B, A}; * ax^2 + bx + c = 0 * </pre> * A return value of <code>-1</code> is used to distinguish a constant * equation, which might be always 0 or never 0, from an equation that * has no zeroes. * @param eqn the array that contains the quadratic coefficients * @return the number of roots, or <code>-1</code> if the equation is * a constant */ public static int solveQuadratic(double eqn[]) { return solveQuadratic(eqn, eqn); } /** * Solves the quadratic whose coefficients are in the <code>eqn</code> * array and places the non-complex roots into the <code>res</code> * array, returning the number of roots. * The quadratic solved is represented by the equation: * <pre> * eqn = {C, B, A}; * ax^2 + bx + c = 0 * </pre> * A return value of <code>-1</code> is used to distinguish a constant * equation, which might be always 0 or never 0, from an equation that * has no zeroes. * @param eqn the specified array of coefficients to use to solve * the quadratic equation * @param res the array that contains the non-complex roots * resulting from the solution of the quadratic equation * @return the number of roots, or <code>-1</code> if the equation is * a constant. */ public static int solveQuadratic(double eqn[], double res[]) { double a = eqn[2]; double b = eqn[1]; double c = eqn[0]; int roots = 0; if (a == 0.0) { // The quadratic parabola has degenerated to a line. if (b == 0.0) { // The line has degenerated to a constant. return -1; } res[roots++] = -c / b; } else { // From Numerical Recipes, 5.6, Quadratic and Cubic Equations double d = b * b - 4.0 * a * c; if (d < 0.0) { // If d < 0.0, then there are no roots return 0; } d = Math.sqrt(d); // For accuracy, calculate one root using: // (-b +/- d) / 2a // and the other using: // 2c / (-b +/- d) // Choose the sign of the +/- so that b+d gets larger in magnitude if (b < 0.0) { d = -d; } double q = (b + d) / -2.0; // We already tested a for being 0 above res[roots++] = q / a; if (q != 0.0) { res[roots++] = c / q; } } return roots; } /** * Tests if a specified coordinate is inside the boundary of the * shape of this <code>QuadCurve2D</code>. * @param x, y the specified coordinates * @return <code>true</code> if the specified coordinate is inside * the boundary of the shape of this * <code>QuadCurve2D</code>; <code>false</code> otherwise. */ public boolean contains(double x, double y) { // We count the "Y" crossings to determine if the point is // inside the curve bounded by its closing line. int crossings = 0; double x1 = getX1(); double y1 = getY1(); double x2 = getX2(); double y2 = getY2(); // First check for a crossing of the line connecting the endpoints double dy = y2 - y1; if ((dy > 0.0 && y >= y1 && y <= y2) || (dy < 0.0 && y <= y1 && y >= y2)) { if (x <= x1 + (y - y1) * (x2 - x1) / dy) { crossings++; } } // Solve the Y parametric equation for intersections with y double ctrlx = getCtrlX(); double ctrly = getCtrlY(); boolean include0 = ((y2 - y1) * (ctrly - y1) >= 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -