Example usage for java.awt.geom GeneralPath curveTo

List of usage examples for java.awt.geom GeneralPath curveTo

Introduction

In this page you can find the example usage for java.awt.geom GeneralPath curveTo.

Prototype

public abstract void curveTo(double x1, double y1, double x2, double y2, double x3, double y3);

Source Link

Document

Adds a curved segment, defined by three new points, to the path by drawing a Bézier curve that intersects both the current coordinates and the specified coordinates (x3,y3) , using the specified points (x1,y1) and (x2,y2) as Bézier control points.

Usage

From source file:Main.java

public static void main(String[] args) {
    GeneralPath shape = new GeneralPath();
    shape.moveTo(1, 1);//w w  w.jav  a2s.  c o m
    shape.lineTo(2, 2);
    shape.quadTo(3, 3, 4, 4);
    shape.curveTo(5, 5, 6, 6, 7, 7);
    shape.closePath();
}

From source file:Main.java

public static void main(String[] args) {
    GeneralPath shape = new GeneralPath();
    shape.moveTo(1, 1);//from www .j ava2  s  . c  om
    shape.lineTo(2, 2);
    shape.quadTo(3, 3, 4, 4);
    shape.curveTo(5, 5, 6, 6, 7, 7);
    shape.closePath();

    System.out.println("done");
}

From source file:Main.java

/**
 * Reads a <code>Shape</code> object that has been serialised by the
 * {@link #writeShape(Shape, ObjectOutputStream)} method.
 *
 * @param stream  the input stream (<code>null</code> not permitted).
 *
 * @return The shape object (possibly <code>null</code>).
 *
 * @throws IOException  if there is an I/O problem.
 * @throws ClassNotFoundException  if there is a problem loading a class.
 *//*from   w w w  .ja v a2  s. c  o  m*/
public static Shape readShape(final ObjectInputStream stream) throws IOException, ClassNotFoundException {

    if (stream == null) {
        throw new IllegalArgumentException("Null 'stream' argument.");
    }
    Shape result = null;
    final boolean isNull = stream.readBoolean();
    if (!isNull) {
        final Class c = (Class) stream.readObject();
        if (c.equals(Line2D.class)) {
            final double x1 = stream.readDouble();
            final double y1 = stream.readDouble();
            final double x2 = stream.readDouble();
            final double y2 = stream.readDouble();
            result = new Line2D.Double(x1, y1, x2, y2);
        } else if (c.equals(Rectangle2D.class)) {
            final double x = stream.readDouble();
            final double y = stream.readDouble();
            final double w = stream.readDouble();
            final double h = stream.readDouble();
            result = new Rectangle2D.Double(x, y, w, h);
        } else if (c.equals(Ellipse2D.class)) {
            final double x = stream.readDouble();
            final double y = stream.readDouble();
            final double w = stream.readDouble();
            final double h = stream.readDouble();
            result = new Ellipse2D.Double(x, y, w, h);
        } else if (c.equals(Arc2D.class)) {
            final double x = stream.readDouble();
            final double y = stream.readDouble();
            final double w = stream.readDouble();
            final double h = stream.readDouble();
            final double as = stream.readDouble(); // Angle Start
            final double ae = stream.readDouble(); // Angle Extent
            final int at = stream.readInt(); // Arc type
            result = new Arc2D.Double(x, y, w, h, as, ae, at);
        } else if (c.equals(GeneralPath.class)) {
            final GeneralPath gp = new GeneralPath();
            final float[] args = new float[6];
            boolean hasNext = stream.readBoolean();
            while (!hasNext) {
                final int type = stream.readInt();
                for (int i = 0; i < 6; i++) {
                    args[i] = stream.readFloat();
                }
                switch (type) {
                case PathIterator.SEG_MOVETO:
                    gp.moveTo(args[0], args[1]);
                    break;
                case PathIterator.SEG_LINETO:
                    gp.lineTo(args[0], args[1]);
                    break;
                case PathIterator.SEG_CUBICTO:
                    gp.curveTo(args[0], args[1], args[2], args[3], args[4], args[5]);
                    break;
                case PathIterator.SEG_QUADTO:
                    gp.quadTo(args[0], args[1], args[2], args[3]);
                    break;
                case PathIterator.SEG_CLOSE:
                    gp.closePath();
                    break;
                default:
                    throw new RuntimeException("JFreeChart - No path exists");
                }
                gp.setWindingRule(stream.readInt());
                hasNext = stream.readBoolean();
            }
            result = gp;
        } else {
            result = (Shape) stream.readObject();
        }
    }
    return result;

}

From source file:BezLab.java

public void paint(Graphics g) {
    for (int i = 0; i < 4; i++) {
        if (i == 0 || i == 3)
            g.setColor(Color.blue);
        else//from  w w w .  j  a  v  a  2s  . c o m
            g.setColor(Color.cyan);
        g.fillOval(xs[i] - 6, ys[i] - 6, 12, 12);
    }
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.black);
    GeneralPath path = new GeneralPath();
    path.moveTo(xs[0], ys[0]);
    path.curveTo(xs[1], ys[1], xs[2], ys[2], xs[3], ys[3]);
    g2d.draw(path);
}

From source file:Bouncer.java

protected Shape createShape() {
    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, mPoints.length);
    path.moveTo(mPoints[0], mPoints[1]);
    for (int i = 2; i < mN; i += 6)
        path.curveTo(mPoints[i], mPoints[i + 1], mPoints[i + 2], mPoints[i + 3], mPoints[i + 4],
                mPoints[i + 5]);//from   w w  w .j a v a  2 s  .  com
    path.closePath();
    return path;
}

From source file:CustomStrokes.java

public Shape createStrokedShape(Shape shape) {
    GeneralPath newshape = new GeneralPath(); // Start with an empty shape

    // Iterate through the specified shape, perturb its coordinates, and
    // use them to build up the new shape.
    float[] coords = new float[6];
    for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i.next()) {
        int type = i.currentSegment(coords);
        switch (type) {
        case PathIterator.SEG_MOVETO:
            perturb(coords, 2);//from  w w  w.j a  v a2s  . c om
            newshape.moveTo(coords[0], coords[1]);
            break;
        case PathIterator.SEG_LINETO:
            perturb(coords, 2);
            newshape.lineTo(coords[0], coords[1]);
            break;
        case PathIterator.SEG_QUADTO:
            perturb(coords, 4);
            newshape.quadTo(coords[0], coords[1], coords[2], coords[3]);
            break;
        case PathIterator.SEG_CUBICTO:
            perturb(coords, 6);
            newshape.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
            break;
        case PathIterator.SEG_CLOSE:
            newshape.closePath();
            break;
        }
    }

    // Finally, stroke the perturbed shape and return the result
    return stroke.createStrokedShape(newshape);
}

From source file:org.broad.igv.renderer.SpliceJunctionRenderer.java

/**
 * Draw a filled arc representing a single feature. The thickness and height of the arc are proportional to the
 * depth of coverage.  Some of this gets a bit arcane -- the result of lots of visual tweaking.
 *
 * @param pixelFeatureStart  the starting position of the feature, whether on-screen or not
 * @param pixelFeatureEnd    the ending position of the feature, whether on-screen or not
 * @param pixelJunctionStart the starting position of the junction, whether on-screen or not
 * @param pixelJunctionEnd   the ending position of the junction, whether on-screen or not
 * @param depth              coverage depth
 * @param trackRectangle/* w w w .j av  a2 s. c o  m*/
 * @param context
 * @param strand
 * @param junctionFeature
 * @param shouldHighlight
 * @param featureColor       the color specified for this feature.  May be null.
 */
protected void drawFeature(int pixelFeatureStart, int pixelFeatureEnd, int pixelJunctionStart,
        int pixelJunctionEnd, float depth, Rectangle trackRectangle, RenderContext context, Strand strand,
        SpliceJunctionFeature junctionFeature, boolean shouldHighlight, Color featureColor,
        boolean shouldShowFlankingRegions) {

    boolean isPositiveStrand = true;
    // Get the feature's direction, color appropriately
    if (strand != null && strand.equals(Strand.NEGATIVE))
        isPositiveStrand = false;

    //If the feature color is specified, use it, except that we set our own alpha depending on whether
    //the feature is highlighted.  Otherwise default based on strand and highlight.
    Color color;
    if (featureColor != null) {
        int r = featureColor.getRed();
        int g = featureColor.getGreen();
        int b = featureColor.getBlue();
        int alpha = shouldHighlight ? 255 : 140;
        color = new Color(r, g, b, alpha);
    } else {
        if (isPositiveStrand)
            color = shouldHighlight ? ARC_COLOR_HIGHLIGHT_POS : ARC_COLOR_POS;
        else
            color = shouldHighlight ? ARC_COLOR_HIGHLIGHT_NEG : ARC_COLOR_NEG;
    }

    Graphics2D g2D = context.getGraphic2DForColor(color);
    if (PreferenceManager.getInstance().getAsBoolean(PreferenceManager.ENABLE_ANTIALISING)) {
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    }
    //Height of top of an arc of maximum depth
    int maxPossibleArcHeight = (trackRectangle.height - 1) / 2;

    if (shouldShowFlankingRegions) {
        if (junctionFeature.hasFlankingRegionDepthArrays()) {
            //draw a wigglegram of the splice junction flanking region depth of coverage

            int startFlankingRegionPixelLength = pixelJunctionStart - pixelFeatureStart;
            int endFlankingRegionPixelLength = pixelFeatureEnd - pixelJunctionEnd;

            drawFlankingRegion(g2D, pixelFeatureStart, startFlankingRegionPixelLength,
                    junctionFeature.getStartFlankingRegionDepthArray(), maxPossibleArcHeight, trackRectangle,
                    isPositiveStrand);
            drawFlankingRegion(g2D, pixelJunctionEnd + 1, endFlankingRegionPixelLength,
                    junctionFeature.getEndFlankingRegionDepthArray(), maxPossibleArcHeight, trackRectangle,
                    isPositiveStrand);
        } else {
            //Draw rectangles indicating the overlap on each side of the junction
            int overlapRectHeight = 3;
            int overlapRectTopX = (int) trackRectangle.getCenterY() + (isPositiveStrand ? -2 : 0);
            if (pixelFeatureStart < pixelJunctionStart) {
                g2D.fillRect(pixelFeatureStart, overlapRectTopX, pixelJunctionStart - pixelFeatureStart,
                        overlapRectHeight);
            }
            if (pixelJunctionEnd < pixelFeatureEnd) {
                g2D.fillRect(pixelJunctionEnd, overlapRectTopX, pixelFeatureEnd - pixelJunctionEnd,
                        overlapRectHeight);
            }
        }
    }

    //Create a path describing the arc, using Bezier curves. The Bezier control points for the top and
    //bottom arcs are based on the boundary points of the rectangles containing the arcs

    //proportion of the maximum arc height used by a minimum-height arc
    double minArcHeightProportion = 0.33;

    int innerArcHeight = (int) (maxPossibleArcHeight * minArcHeightProportion);
    float depthProportionOfMax = Math.min(1, depth / maxDepth);
    int arcWidth = Math.max(1,
            (int) ((1 - minArcHeightProportion) * maxPossibleArcHeight * depthProportionOfMax));
    int outerArcHeight = innerArcHeight + arcWidth;

    //Height of bottom of the arc
    int arcBeginY = (int) trackRectangle.getCenterY() + (isPositiveStrand ? -1 : 1);
    int outerArcPeakY = isPositiveStrand ? arcBeginY - outerArcHeight : arcBeginY + outerArcHeight;
    int innerArcPeakY = isPositiveStrand ? arcBeginY - innerArcHeight : arcBeginY + innerArcHeight;
    //dhmay: I don't really understand Bezier curves.  For some reason I have to put the Bezier control
    //points farther up or down than I want the arcs to extend.  This multiplier seems about right
    int outerBezierY = arcBeginY + (int) (1.3 * (outerArcPeakY - arcBeginY));
    int innerBezierY = arcBeginY + (int) (1.3 * (innerArcPeakY - arcBeginY));

    //Putting the Bezier control points slightly off to the sides of the arc 
    int bezierXPad = Math.max(1, (pixelJunctionEnd - pixelJunctionStart) / 30);

    GeneralPath arcPath = new GeneralPath();
    arcPath.moveTo(pixelJunctionStart, arcBeginY);
    arcPath.curveTo(pixelJunctionStart - bezierXPad, outerBezierY, //Bezier 1
            pixelJunctionEnd + bezierXPad, outerBezierY, //Bezier 2
            pixelJunctionEnd, arcBeginY); //Arc end
    arcPath.curveTo(pixelJunctionEnd + bezierXPad, innerBezierY, //Bezier 1
            pixelJunctionStart - bezierXPad, innerBezierY, //Bezier 2
            pixelJunctionStart, arcBeginY); //Arc end

    //Draw the arc, to ensure outline is drawn completely (fill won't do it, necessarily). This will also
    //give the arc a darker outline
    g2D.draw(arcPath);
    //Fill the arc
    g2D.fill(arcPath);

    g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);
    g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);

}

From source file:org.jcurl.math.ShaperUtils.java

/**
 * Compute the control points and add one <a
 * href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">Cubic Bezier Curve</a>
 * to a {@link GeneralPath}. Does <b>no</b> initial
 * {@link GeneralPath#moveTo(float, float)}.
 * /*from   w w  w  .ja  v  a 2 s .  c o m*/
 * <h3>Approximation algorithm</h3>
 * <p>
 * This ansatz uses no adaptive optimisation but the nature of curves as
 * they're typical to curling:
 * <ul>
 * <li>continuous within [tmin:tmax] - at least C0, C1</li>
 * <li>smoothly increasing curvature</li>
 * <li>not meandering</li>
 * </ul>
 * So we use
 * <ul>
 * <li>the start- and endpoint of each interval als control points k0 and
 * k3</li>
 * <li>the directions (normalised velocities) in the control points k0 and
 * k3</li>
 * <li>a ratio 3:2:1 of the distances |k0-k1| : |k1-k2| : |k2-k3|</li>
 * </ul>
 * <p>
 * This causes quite a computation - without iteration/recursion though, but
 * 1 square root and many double multiplications - but this is well worth
 * while as we can reduce the curve segments to draw significantly. One
 * cubic bezier curve per seven meters curve length gives an error &lt; 2 mm
 * (using {@link CurlerDenny} with 24s draw-to-tee and 1m curl)!
 * </p>
 * <p>
 * TODO maybe re-use endpoint location and velocity. This can cause pain at
 * C1 discontinuous t's (collissions).
 * </p>
 * <h3><a href="http://en.wikipedia.org/wiki/Maxima_(software)">Maxima</a>
 * Solution</h3>
 * 
 * <pre>
 *    radsubstflag: true$
 *    k1_0 = k0_0 + l * v0_0;
 *    k1_1 = k0_1 + l * v0_1;
 *    k2_0 = k3_0 - n * v3_0;
 *    k2_1 = k3_1 - n * v3_1;
 *    l/n=a/c;
 *    ((k2_0 - k1_0)*(k2_0 - k1_0) + (k2_1 - k1_1)*(k2_1 - k1_1)) / (n*n) = b*b / (c*c);
 *    solve([%th(6), %th(5), %th(4), %th(3), %th(2), %th(1)],[k1_0, k1_1, k2_0, k2_1, l, n]);
 *    factor(%);
 *    ratsimp(%);
 *    ratsubst(V0, v0_1&circ;2+v0_0&circ;2, %);
 *    ratsubst(V3, v3_1&circ;2+v3_0&circ;2, %);
 *    ratsubst(A, k0_1-k3_1, %);
 *    ratsubst(B, k0_0-k3_0, %);
 *    ratsubst(T, 2*a*c*v0_0*v3_0+a&circ;2*v0_1&circ;2+a&circ;2*v0_0&circ;2-b&circ;2, %);
 *    ratsubst(Q, c&circ;2*V3+a&circ;2*V0+T+2*a*c*v0_1*v3_1-a&circ;2*v0_1&circ;2-a&circ;2*v0_0&circ;2, %);
 *    ratsubst(W, B&circ;2*T+B&circ;2*(b&circ;2-Q)+c&circ;2*(v3_0&circ;2*B&circ;2-v3_0&circ;2*A&circ;2)-a&circ;2*v0_1&circ;2*B&circ;2+v3_1*(2*c&circ;2*v3_0*A*B
 *    +2*a*c*v0_0*A*B)+v0_1*(2*a*c*v3_0*A*B+2*a&circ;2*v0_0*A*B)-2*a*c*v0_0*v3_0*A&circ;2-a&circ;2*v0_0&circ;2*A&circ;2
 *    +b&circ;2*A&circ;2, %);
 *    expand(%);
 *    factor(%);
 *    ratsubst(R, c*v3_0*B+a*v0_0*B+c*v3_1*A+a*v0_1*A, %);
 * </pre>
 */
static void curveTo(final R1RNFunction f, final double tmin, final double tmax, final GeneralPath gp,
        final float zoom) {
    final double eps = 1e-6;

    // first control point (startpoint). The same as gp.getCurrentPoint()
    final double k0_0 = f.at(tmin, 0, 0);
    final double k0_1 = f.at(tmin, 0, 1);
    // normalized startpoint velocity
    double v0_0 = f.at(tmin, 1, 0);
    double v0_1 = f.at(tmin, 1, 1);
    if (v0_0 * v0_0 + v0_1 * v0_1 < eps) {
        v0_0 = f.at(tmin + eps, 1, 0);
        v0_1 = f.at(tmin + eps, 1, 1);
    }
    double v = Math.sqrt(v0_0 * v0_0 + v0_1 * v0_1);
    v0_0 /= v;
    v0_1 /= v;

    // 4th control point (endpoint).
    final double k3_0 = f.at(tmax, 0, 0);
    final double k3_1 = f.at(tmax, 0, 1);
    // normalized endpoint velocity
    double v3_0 = f.at(tmax, 1, 0);
    double v3_1 = f.at(tmax, 1, 1);
    if (v3_0 * v3_0 + v3_1 * v3_1 < eps) {
        v3_0 = f.at(tmax - eps, 1, 0);
        v3_1 = f.at(tmax - eps, 1, 1);
    }
    v = Math.sqrt(v3_0 * v3_0 + v3_1 * v3_1);
    v3_0 /= v;
    v3_1 /= v;

    final double a = 3;
    final double b = 2;
    final double c = 1;
    final double V0 = v0_1 * v0_1 + v0_0 * v0_0;
    final double V3 = v3_1 * v3_1 + v3_0 * v3_0;
    final double A = k0_1 - k3_1;
    final double B = k0_0 - k3_0;
    final double T = 2 * a * c * v0_0 * v3_0 + a * a * v0_1 * v0_1 + a * a * v0_0 * v0_0 - b * b;
    final double Q = c * c * V3 + a * a * V0 + T + 2 * a * c * v0_1 * v3_1 - a * a * v0_1 * v0_1
            - a * a * v0_0 * v0_0;
    double W = B * B * T + B * B * (b * b - Q) + c * c * (v3_0 * v3_0 * B * B - v3_0 * v3_0 * A * A)
            - a * a * v0_1 * v0_1 * B * B + v3_1 * 2 * c * c * v3_0 * A * B + 2 * a * c * v0_0 * A * B
            + v0_1 * (2 * a * c * v3_0 * A * B + 2 * a * a * v0_0 * A * B) - 2 * a * c * v0_0 * v3_0 * A * A
            - a * a * v0_0 * v0_0 * A * A + b * b * A * A;
    if (W < 0) {
        if (log.isWarnEnabled()) {
            log.warn("Arithmetic trouble:");
            log.warn("v0=(" + v0_0 + ", " + v0_1 + ")");
            log.warn("v3=(" + v3_0 + ", " + v3_1 + ")");
            log.warn("V0=" + V0);
            log.warn("V3=" + V3);
            log.warn("A=" + A);
            log.warn("B=" + B);
            log.warn("T=" + T);
            log.warn("Q=" + Q);
            log.warn("W=" + W);
        }
        gp.moveTo(zoom * (float) k3_0, zoom * (float) k3_1);
        return;
    }
    W = Math.sqrt(W);
    final double R = c * v3_0 * B + a * v0_0 * B + c * v3_1 * A + a * v0_1 * A;

    final double l, n;
    if (true) {
        final double F = (W + R) / Q;
        l = -a * F;
        n = -c * F;
    } else {
        final double F = (W - R) / Q;
        l = a * F;
        n = c * F;
    }
    if (Double.isNaN(l) || Double.isNaN(n)) {
        log.warn("v0=(" + v0_0 + ", " + v0_1 + ")");
        log.warn("v3=(" + v3_0 + ", " + v3_1 + ")");
        log.warn("V0=" + V0);
        log.warn("V3=" + V3);
        log.warn("A=" + A);
        log.warn("B=" + B);
        log.warn("T=" + T);
        log.warn("Q=" + Q);
        log.warn("W=" + W);
        log.warn("R=" + R);
    }

    final float k1_0 = (float) (k0_0 + l * v0_0);
    final float k1_1 = (float) (k0_1 + l * v0_1);
    final float k2_0 = (float) (k3_0 - n * v3_0);
    final float k2_1 = (float) (k3_1 - n * v3_1);
    if (log.isDebugEnabled())
        log.debug("(" + k1_0 + ", " + k1_1 + "), (" + k2_0 + ", " + k2_1 + "), (" + (float) k3_0 + ", "
                + (float) k3_1 + ")");
    gp.curveTo(zoom * k1_0, zoom * k1_1, zoom * k2_0, zoom * k2_1, zoom * (float) k3_0, zoom * (float) k3_1);
}