TNT
TNT

Reputation: 2920

How to Draw a Smoother Path

I have a program that allows the user to select a size and draw a freeform curve, similar to a pen function for a graphics program. I am using Path2D for this.

I'm looking for a way to make the drawn path less jagged. Originally I had used path.lineTo for this function, resulting in the jagged path on the left. Then I tried path.curveTo, but this produced a variety of pointed areas along the path as seen on the right.

jagged pathjagged and pointed path

Is there a way to make curves smooth with Path2D?

import ...

public class Test extends JPanel implements MouseListener, MouseMotionListener {
    int count, midX, midY, curveX, curveY;
    Point startPoint, stopPoint, releasePoint;
    Shape pathShape;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        if (pathShape != null) {
            g2.setStroke(new BasicStroke(50));
            g2.draw(pathShape);
        }
    }

    @Override
    public void mousePressed(MouseEvent ev) {
        count = 1;
        startPoint = new Point(ev.getPoint());
        Path2D.Double path = new Path2D.Double();
        pathShape = path;
        repaint();
    }

    @Override
    public void mouseReleased(MouseEvent ev) {
        releasePoint = new Point(ev.getPoint());
        Path2D path = (Path2D) pathShape;
        path.moveTo(releasePoint.x,releasePoint.y);
        path.closePath();
        pathShape = path;
    }

    // The mouseDragged method where lineTo is used.
    @Override
    public void mouseDragged(MouseEvent ev) {
        stopPoint = ev.getPoint();
        Path2D path = (Path2D) pathShape;
        path.moveTo(startPoint.x,startPoint.y);
        path.lineTo(stopPoint.x,stopPoint.y);
        pathShape = path;
        startPoint = stopPoint;
        repaint();
    }

    // The mouseDragged method where curveTo is used.
    @Override
    public void mouseDragged(MouseEvent ev) {
        if (count == 2) {
            midX = stopPoint.x;
            midY = stopPoint.y;
        }
        if (count++ >= 3) {
            curveX = midX;
            curveY = midY;
            midX = stopPoint.x;
            midY = stopPoint.y;
        }
        stopPoint = ev.getPoint();
        Path2D path = (Path2D) pathShape;
        path.moveTo(startPoint.x,startPoint.y);
        if (count >= 3)
            path.curveTo(curveX,curveY,midX,midY,stopPoint.x,stopPoint.y);
        else
            path.lineTo(stopPoint.x,stopPoint.y);
        pathShape = path;
        startPoint = stopPoint;
        repaint();
    }
}

Upvotes: 1

Views: 595

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347204

Try using

g2.setStroke(new BasicStroke(50, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));

instead of g2.setStroke(new BasicStroke(50));

Upvotes: 3

Related Questions