Offsetting a polyline

Thanks to a question on StackOverflow, I did some playing with Java’s Graphics2D. Below is some code to generate an offset of a polyline, i.e. given a polyline (a string of connected line segments), generate a polygon that represents a thick version of that line.

Clearly, the Java guys took some shortcuts here, because the polygon ends up including a lot of interior segments that you don’t really want, etc. However, filling it using a nonzero winding rule covers a lot of sins. And I can understand why they committed those sins, since it’s kinda hard to do in general. Read the CGAL page about offsetting for an intro. Sometime I’ll have to investigate the shortcut methods in the OpenJDK source; looking at this output, I’m definitely curious.


import java.awt.BasicStroke;
import java.awt.Shape;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;

public class StrokePath
    public static void main(String[] args)
        // set line width to 6, use bevel for line joins
        BasicStroke bs = new BasicStroke(6.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL);

        // create a path for the input
        Path2D p = new Path2D.Float();
        p.moveTo(50.0, 50.0);
        p.lineTo(65.0, 100.0);
        p.lineTo(70.0, 60.0);
        p.lineTo(120.0, 65.0);
        p.lineTo(40.0, 200.0);

        // create outline of wide lines by stroking the path with the stroke
        Shape s = bs.createStrokedShape(p);
        // output each of the segments of the stroked path for the output polygon
        PathIterator pi = s.getPathIterator(null);
        while (!pi.isDone())
            double[] coords = new double[6];
            int type = pi.currentSegment(coords);
            switch (type)
            case PathIterator.SEG_LINETO:
                System.out.println(String.format("SEG_LINETO %f,%f", coords[0], coords[1]));
            case PathIterator.SEG_CLOSE:
            case PathIterator.SEG_MOVETO:
                System.out.println(String.format("SEG_MOVETO %f,%f", coords[0], coords[1]));
                System.out.println("*** More complicated than LINETO... Maybe should use FlatteningPathIterator? ***");

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.