📄 quadcurve2d.java
字号:
* * <p>The left end point and the right start point will always be * identical. Memory-concious programmers thus may want to pass the * same array for both <code>left</code> and <code>right</code>, and * set <code>rightOff</code> to <code>leftOff + 4</code>. * * @param src an array containing the coordinates of the curve to be * subdivided. The <i>x</i> coordinate of the start point is * located at <code>src[srcOff]</code>, its <i>y</i> at * <code>src[srcOff + 1]</code>. The <i>x</i> coordinate of the * control point is located at <code>src[srcOff + 2]</code>, its * <i>y</i> at <code>src[srcOff + 3]</code>. The <i>x</i> * coordinate of the end point is located at <code>src[srcOff + * 4]</code>, its <i>y</i> at <code>src[srcOff + 5]</code>. * * @param srcOff an offset into <code>src</code>, specifying * the index of the start point’s <i>x</i> coordinate. * * @param left an array that will receive the coordinates of the * left half of <code>src</code>. It is acceptable to pass * <code>src</code>. A caller who is not interested in the left half * can pass <code>null</code>. * * @param leftOff an offset into <code>left</code>, specifying the * index where the start point’s <i>x</i> coordinate will be * stored. * * @param right an array that will receive the coordinates of the * right half of <code>src</code>. It is acceptable to pass * <code>src</code> or <code>left</code>. A caller who is not * interested in the right half can pass <code>null</code>. * * @param rightOff an offset into <code>right</code>, specifying the * index where the start point’s <i>x</i> coordinate will be * stored. */ public static void subdivide(double[] src, int srcOff, double[] left, int leftOff, double[] right, int rightOff) { double x1, y1, xc, yc, x2, y2; x1 = src[srcOff]; y1 = src[srcOff + 1]; xc = src[srcOff + 2]; yc = src[srcOff + 3]; x2 = src[srcOff + 4]; y2 = src[srcOff + 5]; if (left != null) { left[leftOff] = x1; left[leftOff + 1] = y1; } if (right != null) { right[rightOff + 4] = x2; right[rightOff + 5] = y2; } x1 = (x1 + xc) / 2; x2 = (xc + x2) / 2; xc = (x1 + x2) / 2; y1 = (y1 + yc) / 2; y2 = (y2 + yc) / 2; yc = (y1 + y2) / 2; if (left != null) { left[leftOff + 2] = x1; left[leftOff + 3] = y1; left[leftOff + 4] = xc; left[leftOff + 5] = yc; } if (right != null) { right[rightOff] = xc; right[rightOff + 1] = yc; right[rightOff + 2] = x2; right[rightOff + 3] = y2; } } /** * Finds the non-complex roots of a quadratic equation, placing the * results into the same array as the equation coefficients. The * following equation is being solved: * * <blockquote><code>eqn[2]</code> · <i>x</i><sup>2</sup> * + <code>eqn[1]</code> · <i>x</i> * + <code>eqn[0]</code> * = 0 * </blockquote> * * <p>For some background about solving quadratic equations, see the * article <a href= * "http://planetmath.org/encyclopedia/QuadraticFormula.html" * >“Quadratic Formula”</a> in <a href= * "http://planetmath.org/">PlanetMath</a>. For an extensive library * of numerical algorithms written in the C programming language, * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific * Library</a>. * * @see #solveQuadratic(double[], double[]) * @see CubicCurve2D#solveCubic(double[], double[]) * * @param eqn an array with the coefficients of the equation. When * this procedure has returned, <code>eqn</code> will contain the * non-complex solutions of the equation, in no particular order. * * @return the number of non-complex solutions. A result of 0 * indicates that the equation has no non-complex solutions. A * result of -1 indicates that the equation is constant (i.e., * always or never zero). * * @author <a href="mailto:bjg@network-theory.com">Brian Gough</a> * (original C implementation in the <a href= * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>) * * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a> * (adaptation to Java) */ public static int solveQuadratic(double[] eqn) { return solveQuadratic(eqn, eqn); } /** * Finds the non-complex roots of a quadratic equation. The * following equation is being solved: * * <blockquote><code>eqn[2]</code> · <i>x</i><sup>2</sup> * + <code>eqn[1]</code> · <i>x</i> * + <code>eqn[0]</code> * = 0 * </blockquote> * * <p>For some background about solving quadratic equations, see the * article <a href= * "http://planetmath.org/encyclopedia/QuadraticFormula.html" * >“Quadratic Formula”</a> in <a href= * "http://planetmath.org/">PlanetMath</a>. For an extensive library * of numerical algorithms written in the C programming language, * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific * Library</a>. * * @see CubicCurve2D#solveCubic(double[],double[]) * * @param eqn an array with the coefficients of the equation. * * @param res an array into which the non-complex roots will be * stored. The results may be in an arbitrary order. It is safe to * pass the same array object reference for both <code>eqn</code> * and <code>res</code>. * * @return the number of non-complex solutions. A result of 0 * indicates that the equation has no non-complex solutions. A * result of -1 indicates that the equation is constant (i.e., * always or never zero). * * @author <a href="mailto:bjg@network-theory.com">Brian Gough</a> * (original C implementation in the <a href= * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>) * * @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a> * (adaptation to Java) */ public static int solveQuadratic(double[] eqn, double[] res) { // Taken from poly/solve_quadratic.c in the GNU Scientific Library // (GSL), cvs revision 1.7 of 2003-07-26. For the original source, // see http://www.gnu.org/software/gsl/ // // Brian Gough, the author of that code, has granted the // permission to use it in GNU Classpath under the GNU Classpath // license, and has assigned the copyright to the Free Software // Foundation. // // The Java implementation is very similar to the GSL code, but // not a strict one-to-one copy. For example, GSL would sort the // result. double a, b, c, disc; c = eqn[0]; b = eqn[1]; a = eqn[2]; // Check for linear or constant functions. This is not done by the // GNU Scientific Library. Without this special check, we // wouldn't return -1 for constant functions, and 2 instead of 1 // for linear functions. if (a == 0) { if (b == 0) return -1; res[0] = -c / b; return 1; } disc = b * b - 4 * a * c; if (disc < 0) return 0; if (disc == 0) { // The GNU Scientific Library returns two identical results here. // We just return one. res[0] = -0.5 * b / a ; return 1; } // disc > 0 if (b == 0) { double r; r = Math.abs(0.5 * Math.sqrt(disc) / a); res[0] = -r; res[1] = r; } else { double sgnb, temp; sgnb = (b > 0 ? 1 : -1); temp = -0.5 * (b + sgnb * Math.sqrt(disc)); // The GNU Scientific Library sorts the result here. We don't. res[0] = temp / a; res[1] = c / temp; } return 2; } /** * Determines whether a point lies inside the area that is bounded * by the curve and the straight line connecting its end points. * * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180" * alt="A drawing of the area spanned by the curve" /> * * <p>The above drawing illustrates in which area points are * considered “contained” in a QuadCurve2D. */ public boolean contains(double x, double y) { // XXX Implement. throw new Error("not implemented"); } /** * Determines whether a point lies inside the area that is bounded * by the curve and the straight line connecting its end points. * * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180" * alt="A drawing of the area spanned by the curve" /> * * <p>The above drawing illustrates in which area points are * considered “contained” in a QuadCurve2D. */ public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } public boolean intersects(double x, double y, double w, double h) { // XXX Implement. throw new Error("not implemented"); } public boolean intersects(Rectangle2D r) { return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } public boolean contains(double x, double y, double w, double h) { // XXX Implement. throw new Error("not implemented"); } public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } /** * Determines the smallest rectangle that encloses the * curve’s start, end and control point. As the illustration * below shows, the invisible control point may cause the bounds to * be much larger than the area that is actually covered by the * curve. * * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180" * alt="An illustration of the bounds of a QuadCurve2D" /> */ public Rectangle getBounds() { return getBounds2D().getBounds(); } public PathIterator getPathIterator(final AffineTransform at) { return new PathIterator() { /** Current coordinate. */ private int current = 0; public int getWindingRule() { return WIND_NON_ZERO; } public boolean isDone() { return current >= 2; } public void next() { current++; } public int currentSegment(float[] coords) { int result; switch (current) { case 0: coords[0] = (float) getX1(); coords[1] = (float) getY1(); result = SEG_MOVETO; break; case 1: coords[0] = (float) getCtrlX(); coords[1] = (float) getCtrlY(); coords[2] = (float) getX2(); coords[3] = (float) getY2(); result = SEG_QUADTO; break; default: throw new NoSuchElementException("quad iterator out of bounds"); } if (at != null) at.transform(coords, 0, coords, 0, 2); return result; } public int currentSegment(double[] coords) { int result; switch (current) { case 0: coords[0] = getX1(); coords[1] = getY1(); result = SEG_MOVETO; break; case 1: coords[0] = getCtrlX(); coords[1] = getCtrlY(); coords[2] = getX2(); coords[3] = getY2(); result = SEG_QUADTO; break; default: throw new NoSuchElementException("quad iterator out of bounds"); } if (at != null) at.transform(coords, 0, coords, 0, 2); return result; } }; } public PathIterator getPathIterator(AffineTransform at, double flatness) { return new FlatteningPathIterator(getPathIterator(at), flatness); } /** * Creates a new curve with the same contents as this one. * * @return the clone. */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw (Error) new InternalError().initCause(e); // Impossible } } /** * A two-dimensional curve that is parameterized with a quadratic * function and stores coordinate values in double-precision * floating-point format. * * @see QuadCurve2D.Float * * @author Eric Blake (ebb9@email.byu.edu) * @author Sascha Brawer (brawer@dandelis.ch) */ public static class Double extends QuadCurve2D { /** * The <i>x</i> coordinate of the curve’s start point. */ public double x1; /** * The <i>y</i> coordinate of the curve’s start point. */ public double y1; /** * The <i>x</i> coordinate of the curve’s control point. */ public double ctrlx; /** * The <i>y</i> coordinate of the curve’s control point. */ public double ctrly; /** * The <i>x</i> coordinate of the curve’s end point. */ public double x2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -