Equation-defined shapes - created from sampling lines or SVG import... or....?

I am thinking about how I can best create equation defined shapes that can be manipulated as shapes, and am looking for advice about good ways forward for doing this.

I would like to replicate these shapes in my design and scale them and fill them and give them other custom dynamic behaviours. FYI in this instance I am looking at creating a shape based on touching mirrored ogive curves, forming a closed shape. (Though I’m not sure whether that matters - the key point is that the shape I want to create isn’t a primitive, and can’t be super-obviously assembled from primitives.) I could DRAW the shape I want on the canvas point by point by stepping through an equation at pixel resolution. But that just leaves me with a bunch of pixels.

Instead I think PShape seems the right construct to use. But I’m uncertain about the best way forward for creating a PShape. It seems to me like there are two possibilities:

  • One would be to mock the shape up by creating a whole huge bunch of vertices, stepping through the equation just as I would when I plot it out iteratively. This seems not super efficient…

  • Another approach would be to create an SVG in an external program, and import it into a Pshape. Then I guess I would be at the mercy of whatever vertex approximation happens under the hood? Which is probably better than my brute force attempt.

Am I missing some other approach that would be better? Anyone have any advice about good ways forward? (Including ‘Don’t do this’… :wink: )


1 Like

Can you give an example of an equation?

Because y = 3 * x + 8; doesn’t make much sense to make a shape from.

1 Like

Hm. You could make a path from that… which might make sense. Depending what you want.

But what I had in mind was a mirrored ogive arch, reflected on X, that could be filled. I am on my mobile for rest of day so can’t give you the formula atm. I’ll get back on this tomorrow though.

Meanwhile if you can make any sense of the question curious to hear your thoughts.


The actual equation I want to use is something like this, reflected over x and y and plotted over a domain and range which would create a closed figure, which I brute forced here to be -2 to 2, to show you. I think the actual equation isn’t so important maybe - it’s just something I can piece together by brute force that doesn’t use primitives. I am thinking maybe this is just going to be too expensive and pita-ish to do ‘by hand’ i.e. by modelling it with a plethora of vertices and I would be better off re-thinking what I want to do, so that I could use primitives. What do you think?

looks nice, what did you try with processing so far
some old tests:
see here
Math and processing ,

Did you consider writing a function that converts the formula you use to tangent points, save these points in an array, and thereafter plot it on the graph? You could manipulate the values within this array to adjust your plotted line. Or won’t this work?

1 Like

Thanks for the Kango link. Lots of stuff to check out.

I think my current problem is that I am not sure how best to bridge the gap between a functionally defined line or shape, vs what I understand to be available construction/definition methods for PShape.

Fun! My focus at the moment is really on trying to bridge the gap between a functional specification for a shape, as per the geogrebra example, and the available construction methods for PShape. The more I play with this the more I think I need to back out of the rabbit hole .:face_with_monocle:

Aha!!! This seems like it could be the missing link for what I’m trying to do. If I can model this as a set of tangent points, that would be a good way forward, as I can let the bezier built-ins take the load. Totally happy to back off the initial specification to do something more tractable.

I’ll have a scoot round about how this could be done - but if you have quick references you can sling me that would be useful. tx!

Addendum: looks like I need to find the formula for the first derivative and calculate it… which I assume I can figure out how to do… but not sure how best to determine which points to select?

Addendum2: a sensible place to put joints between the different contributing models could be the inflection points maybe…? not sure I’m up to finding that analytically just this moment (without relearning my calculus) -

Addendum 3: I might be best off, pragmatically, fussing around in Inkscape or similar til I find the right bezier approximation/mockup/model, then re-using the params in Processing. A toolchain is worth avoiding in general but as a one off it could be the best way forward…

Yeah, ArrayList of PVectors, use .add() to hammer the values of x and y in (all in setup())

then in draw()

  • say beginShape()
  • for loop over the ArrayList and
  • vertex() or something and
  • after the for loops } say endShape();
ArrayList<PVector> list = new ArrayList(); 

void setup() {
  size(880, 880);
  for (int i =-250; i < 250; i++) {
    float y=(i*0.1)*(i*0.1)+0; 
    list.add(new PVector (i+width/2, height-y-30));

void draw() {
  for (PVector pv : list) {
    vertex(pv.x, pv.y);

I’ve been trying to work with built-ins rather than approximating the function iteratively, on the theory that Processing can do that better than I can, and after messing around with a demo program in desmos to get the right specification for the Bezier control point coordinates, I can create the shape I want with a Bezier and a reflection of its control points in Processing. So - that’s nice.

But in taking the next step and adapting that definition to PShape I’ve run into the ‘bezier is flaky inside PShape’ problem - bezierVertex() draws straight lines, not a curved line? :wink: - but that’s ok as I can either add an argument to createShape that fixes it for the default renderer, or change the renderer. It’s an open bug so there isn’t a solution that works for both situations.

1 Like

Cool beans. Are you trying to make a general method for converting any old function into a Pshape, or did you want that one shape in particular?

Great – glad that you have workarounds. It sounds like you are tackling the problem in detail. Any chance you are interested in investigating what specifically changed between 3.2.3 and 3.2.4 that introduced the bug in the first place? A third option, of course, is to use v3.2.3.