Shape Geom Relative Coordinate Question

I’m trying to convert the Visio basic shape funnel to an SVG path using the geom coordinate data. The circle comes in as an Ellipse (absolute coordinates) and the rest is all relative (RelMoveTo, RelLineTo, and RelCubBezTo) values. I’m not sure what they are relative to. Is it all the same starting point? Is it the last point that was placed? Is it based on the current viewed shape or the parent shape (possible the top most parent shape)? Something else? Can you point me to some documentation or explain it?

public static void addSvgPathsForShape(Shape shape, List<String> path)
   {
      GeomCollection geomCollection = shape.getGeoms();
      for (Geom geom : (Iterable<Geom>) geomCollection)
      {
         PathagonBuilder pathagonBuilder = new PathagonBuilder();
         for (Coordinate coordinate : (Iterable<Coordinate>) geom.getCoordinateCol())
         {
            if (coordinate instanceof Ellipse) {
               Ellipse ellipse = (Ellipse) coordinate;
               double centerX = ellipse.getX().getValue();
               double centerY = ellipse.getY().getValue();
               double x1 = ellipse.getA().getValue();
               double y1 = ellipse.getB().getValue();
               double x2 = ellipse.getC().getValue();
               double y2 = ellipse.getD().getValue();

               // this is based off the following assumptions:
               // center = 0,0
               // x1, y1 = 1,0
               // x2, y2 = 0,1
               // 0,0 is the top left corner and +,+ draws down and to the right

               boolean oneIsRadiusX = centerX != x1;
               boolean twoIsRadiusX = centerX != x2;
               if (oneIsRadiusX && twoIsRadiusX) {
                  throw new RuntimeException("something is broken here");
               }
               double rx = Math.abs(oneIsRadiusX ? centerX - x1 : centerX - x2);
               double ry = Math.abs(oneIsRadiusX ? centerY - y2 : centerY - y1);
               double angle = 0.0;
               pathagonBuilder.moveTo(x1, -y1);
               pathagonBuilder.ellipticalArcTo(rx, ry, angle, false, false, x2, -y2);
               pathagonBuilder.ellipticalArcTo(rx , ry, angle, true, false, x1, -y1);
            }
            // how are these supposed to be adjusted since they are relative?
            else if (coordinate instanceof RelLineTo) {
               RelLineTo relLineTo = (RelLineTo) coordinate;
               double x = relLineTo.getX().getValue();
               double y = relLineTo.getY().getValue();
               pathagonBuilder.lineTo(x, -y);
            }
            else if (coordinate instanceof RelMoveTo)
            {
               RelMoveTo relMoveTo = (RelMoveTo) coordinate;
               double x = relMoveTo.getX().getValue();
               double y = relMoveTo.getY().getValue();
               pathagonBuilder.moveTo(x,-y);
            }
            else if (coordinate instanceof RelCubBezTo) {
               RelCubBezTo relCubBezTo = (RelCubBezTo) coordinate;

               double cpx1 = relCubBezTo.getA().getValue();
               double cpy1 = relCubBezTo.getB().getValue();
               double cpx2 = relCubBezTo.getC().getValue();
               double cpy2 = relCubBezTo.getD().getValue();
               double endX = relCubBezTo.getX().getValue();
               double endY = relCubBezTo.getY().getValue();
               pathagonBuilder.bezierTo(cpx1, -cpy1, cpx2, -cpy2, endX, -endY);
            }
         }
         pathagonBuilder.closePath();
         path.add(pathagonBuilder.get().toSvgPath());
      }
   }

funnel.7z (20.1 KB)

@mcintken
Thanks for the template file.
Values in the RelLineTo row are equivalent to values in a [LineTo] row that are multiplied by the width and height of the shape.
The x -coordinate of the ending vertex of a straight line segment relative to the shape’s width.
The y -coordinate of the ending vertex of a straight line segment relative to the shape’s height.