public static Shape getConvexHullPath2D(Shape shape) {
        List<Point2D.Double> points = new LinkedList<Point2D.Double>();
        double[] coords = new double[6];
        for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i.next()) {
            switch (i.currentSegment(coords)) {
                case PathIterator.SEG_CLOSE:
                    break;
                case PathIterator.SEG_MOVETO:
                case PathIterator.SEG_LINETO:
                    points.add(new Point2D.Double(coords[0], coords[1]));
                    break;
                case PathIterator.SEG_QUADTO:
                    points.add(new Point2D.Double(coords[0], coords[1]));
                    points.add(new Point2D.Double(coords[2], coords[3]));
                    break;
                case PathIterator.SEG_CUBICTO:
                    points.add(new Point2D.Double(coords[0], coords[1]));
                    points.add(new Point2D.Double(coords[2], coords[3]));
                    points.add(new Point2D.Double(coords[4], coords[5]));
                    break;
            }

        }
        Path2D.Double path2d = new Path2D.Double();
        Point2D.Double[] chPoints = getConvexHull(points.toArray(new Point2D.Double[0]));
        if (!points.isEmpty()) {
            path2d.moveTo(chPoints[0].x, chPoints[0].y);
            for (int i = 1; i < chPoints.length; i++) {
                path2d.lineTo(chPoints[i].x, chPoints[i].y);
            }
        }
        return path2d;
    }