# Pro Question: get ALL in-between points from beginShape curveVertex() endShape

**URL:** <https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693>\
**Category:** Coding Questions\
**Created:** [September 9, 2022, 4:18pm UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693 "2022-09-09T16:18:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 9, 2022, 4:18pm UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693/1 "2022-09-09T16:18:31Z")

</div>

Hello all!

as we all know, we can use  
beginShape curveVertex() endShape to make long complex curves.

See [Reference / Processing.org](https://processing.org/reference/curveVertex_.html)

But it’s pretty much a black box.

How can I receive ALL points that are shown by curveVertex?

Apparently similar to curvePoint (with t / amt) but alas not quite

For a mcve see [Easing equations with 'Influence' and 'In-/Outgoing Velocity' like in Adobe After Effects - #2 by Chrisir](https://discourse.processing.org/t/easing-equations-with-influence-and-in-outgoing-velocity-like-in-adobe-after-effects/38687/2)

Thank you all!

Chrisir

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [September 10, 2022, 9:28am UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693/2 "2022-09-10T09:28:39Z")

</div>

Hi @Chrisir,

> [@Chrisir](#):
>
> How can I receive ALL points that are shown by curveVertex?

Not that easy as each implementation JAVA2D, P2D,etc handles it different. There is a native catmul-rom implementation in PGraphics which would store the vertices as float array, but it doesn’t seems to be used at all…  
for OpenGL related (P2D/P3D) ones there is an internal class _InGeometry_ used to store the vertices which are not accessable and for JAVA2D it uses the awt.geom stuff.  
Here is a quick and evil hack for the latter… 🙂

Cheers  
— mnse

```auto
import java.lang.reflect.*;
import java.awt.geom.*;

ArrayList<PVector> points = null;

void setup() {
  size(300, 300);
}

void draw() {
  background(0);
  stroke(255);
  noFill();
  beginShape();
  for (int x = 0; x < width; x+=width/8) {
    curveVertex(x, x%2==0 ? height*0.25:height*0.75);
  }
  endShape();

  if (points == null)
    points = getVertices();

  PVector current = points.get(int(millis()/100) % points.size());
  noStroke();
  fill(255, 0, 0);  
  ellipse(current.x, current.y, 8, 8);
}

Class findClass(Class c, String search) {
  if (c.getName().endsWith(search))
    return c;
  else if (c.getSuperclass() != null)
    return findClass(c.getSuperclass(), search);
  return null;
}

ArrayList<PVector> getVertices() {
  ArrayList<PVector> list = new ArrayList<PVector>(); 
  try {
    GeneralPath gpath = null;
    Class pgclass = findClass(g.getClass(), "PGraphicsJava2D");
    if (pgclass == null) {
      throw new Exception("PGraphicsJava2D class not found");
    }
    Field[] fields = pgclass.getDeclaredFields();
    for (Field f : fields) {
      if ("gpath".equals(f.getName())) {      
        f.setAccessible(true);
        gpath = (GeneralPath) f.get(g);
      }
    }

    if (gpath == null) {
      throw new Exception("class member gpath not found");
    }

    PathIterator i = gpath.getPathIterator(null, 1);
    while (!i.isDone()) {
      double[] coords = new double[6];
      int segType = i.currentSegment(coords);
      if (segType != PathIterator.SEG_CLOSE) {
        list.add(new PVector((float)coords[0], (float)coords[1]));
      }
      i.next();
    }
  } 
  catch(Exception e) {
    println("Error: " + e);
  }
  return list;
}

```

![video](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/8/9/899c0d7293d27dba2a4a3d1f5ac61fbaa50aafa5.gif)

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [September 10, 2022, 1:10pm UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693/3 "2022-09-10T13:10:35Z")

</div>

Hello @mnse,

> [@mnse](#):
>
> There is a native catmul-rom implementation in PGraphics which would store the vertices as float array, but it doesn’t seems to be used at all…

> [@mnse](#):
>
> Here is a quick and evil hack for the latter…

Please provide some context to above with links to the source in GitHub.

I took a quick look already but you have done the groundwork and others would benefit from that journey.

`:)`

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [September 12, 2022, 6:08am UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693/4 "2022-09-12T06:08:12Z")

</div>

Hi,

Git-References:

- PGraphics  
[curveVertex()](https://github.com/processing/processing/blob/8b15e4f548c1426df3a5ebe4c2106619faf7c4ba/core/src/processing/core/PGraphics.java#L2249) and [curveVertexSegment](https://github.com/processing/processing/blob/8b15e4f548c1426df3a5ebe4c2106619faf7c4ba/core/src/processing/core/PGraphics.java#L2323) which not seems to be used.

- PGraphicsJava2D  
[gpath variable](https://github.com/processing/processing/blob/8b15e4f548c1426df3a5ebe4c2106619faf7c4ba/core/src/processing/awt/PGraphicsJava2D.java#L68) which the curve data is stored for Java2D mode.  
[curveVertexSegment](https://github.com/processing/processing/blob/8b15e4f548c1426df3a5ebe4c2106619faf7c4ba/core/src/processing/awt/PGraphicsJava2D.java#L1152) which adds the curve data by using awt.geom methods

Additional info:

- [about reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html)
- [about awt.geom.GeneralPath.curveTo](https://docs.oracle.com/javase/6/docs/api/java/awt/geom/Path2D.Float.html#curveTo(float,%20float,%20float,%20float,%20float,%20float))
- [about PathIterator](https://docs.oracle.com/javase/6/docs/api/java/awt/geom/PathIterator.html)

Cheers  
— mnse

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [September 12, 2022, 2:04pm UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693/5 "2022-09-12T14:04:52Z")

</div>

Hi,

Just to add a way for P2D mode …

Cheers  
— mnse

PS: _For demonstration purposes only_ … so still quick hack without following good coding conventions. 🙂

```auto
import java.lang.reflect.*;
import java.awt.geom.*;

ArrayList<PVector> points = null;

void setup() {
  size(300, 300, P2D);
}

void draw() {
  background(0);
  stroke(255);
  noFill();
  beginShape();
  for (int x = 0; x < width; x+=width/8) {
    curveVertex(x, x%2==0 ? height*0.25:height*0.75);
  }
  endShape();

  if (points == null) {
    try {
      points = getPoints();
      if (points.isEmpty())
        throw new Exception("no data found !?");
    } 
    catch(Exception e) {
      println("Error: " + e);
      exit();
      return;
    }
  }

  PVector current = points.get(int(frameCount/5.) % points.size());
  noStroke();
  fill(255, 0, 0);  
  ellipse(current.x, current.y, 8, 8);
}

Class findClass(Class c, String search) {
  if (c.getName().endsWith(search))
    return c;
  else if (c.getSuperclass() != null)
    return findClass(c.getSuperclass(), search);
  return null;
}

ArrayList<PVector> getPoints() throws Exception {
  if (sketchRenderer().endsWith("PGraphics2D")) {
    return getVerticesP2D();
  } else if (sketchRenderer().endsWith("PGraphicsJava2D")) {
    return getVerticesJAVA2D();
  } else {
    throw new Exception("unsupported renderer " + sketchRenderer() + " !?");
  }
}

// JAVA2D Mode
ArrayList<PVector> getVerticesJAVA2D() throws Exception {
  ArrayList<PVector> list = new ArrayList<PVector>(); 
  GeneralPath gpath = null;
  Class pgclass = findClass(g.getClass(), "PGraphicsJava2D");
  if (pgclass == null) {
    throw new Exception("PGraphicsJava2D class not found");
  }
  Field[] fields = pgclass.getDeclaredFields();
  for (Field f : fields) {
    if ("gpath".equals(f.getName())) {      
      f.setAccessible(true);
      gpath = (GeneralPath) f.get(g);
      break;
    }
  }

  if (gpath == null) {
    throw new Exception("class member gpath not found");
  }

  PathIterator i = gpath.getPathIterator(null, 1);
  while (!i.isDone()) {
    double[] coords = new double[6];
    int segType = i.currentSegment(coords);
    if (segType != PathIterator.SEG_CLOSE) {
      list.add(new PVector((float)coords[0], (float)coords[1]));
    }
    i.next();
  }
  return list;
}

// P2D Mode
ArrayList<PVector> getVerticesP2D() throws Exception {
  ArrayList<PVector> list = new ArrayList<PVector>(); 
  float[] vertices = {};
  int vertexCount = 0;
  Class pgclass = findClass(g.getClass(), "PGraphicsOpenGL");
  if (pgclass == null) {
    throw new Exception("PGraphicsOpenGL class not found");
  }
  for (Field pgField : pgclass.getDeclaredFields()) {
    if ("tessellator".equals(pgField.getName())) {      
      pgField.setAccessible(true);        
      Object tessellatorObj = pgField.get(g);               
      for (Field tessellatorField : tessellatorObj.getClass().getDeclaredFields()) {
        if ("pathVertexCount".equals(tessellatorField.getName())) {      
          tessellatorField.setAccessible(true);        
          vertexCount = (int) tessellatorField.get(tessellatorObj);
        }          
        else if ("pathVertices".equals(tessellatorField.getName())) {      
          tessellatorField.setAccessible(true);        
          vertices = (float[]) tessellatorField.get(tessellatorObj);
        }
      }
    }
  }
  if (vertexCount == 0) {
    throw new Exception("no Vertices found");
  }    
  for (int i = 0; i < vertexCount*3; i+=3) {
    list.add(new PVector(vertices[i], vertices[i+1]));
  }
  return list;
}

```

![video2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/7/0/70a8e80598c7f494f29c5ccff1895dbc75897e1b.gif)

Github refs:

- [Object which handles the curve data](https://github.com/processing/processing/blob/8b15e4f548c1426df3a5ebe4c2106619faf7c4ba/core/src/processing/opengl/PGraphicsOpenGL.java#L226)
- [responsible class (Tessellator)](https://github.com/processing/processing/blob/8b15e4f548c1426df3a5ebe4c2106619faf7c4ba/core/src/processing/opengl/PGraphicsOpenGL.java#L10922)

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [September 12, 2022, 3:35pm UTC](https://discourse.processing.org/t/pro-question-get-all-in-between-points-from-beginshape-curvevertex-endshape/38693/6 "2022-09-12T15:35:09Z")

</div>

Hi,

finally, to be somehow complete, add version for P3D. Nearly the same as P2D just convert the 2D to 3D coords.

Cheers  
— mnse

```auto
import java.lang.reflect.*;
import java.awt.geom.*;

ArrayList<PVector> points = null;

void setup() {
  size(300, 300, P3D);
}

void draw() {  
  background(0);
  stroke(255);
  noFill();
  beginShape();
  for (int x = 0; x < width; x+=width/8) {
    if (g.is3D())
      curveVertex(x, x%2==0 ? height*0.25:height*0.75,x*-3.);
    else
      curveVertex(x, x%2==0 ? height*0.25:height*0.75);
  }
  endShape();

  if (points == null) {
    try {
      points = getPoints();
      if (points.isEmpty())
        throw new Exception("no data found !?");
    } 
    catch(Exception e) {
      println("Error: " + e);
      exit();
      return;
    }
  }

  PVector current = points.get(int(frameCount/5.) % points.size());
  noStroke();
  fill(255, 0, 0);
  if (g.is3D())
    translate(current.x,current.y,current.z);
  else
    translate(current.x,current.y);

  ellipse(0,0,5,5);    
}

Class findClass(Class c, String search) {
  if (c.getName().endsWith(search))
    return c;
  else if (c.getSuperclass() != null)
    return findClass(c.getSuperclass(), search);
  return null;
}

ArrayList<PVector> getPoints() throws Exception {
  if (sketchRenderer().equals(P2D)) {
    return getVerticesP2D();
  } else if (sketchRenderer().equals(P3D)) {
    return getVerticesP3D();
  } else if (sketchRenderer().equals(JAVA2D)) {
    return getVerticesJAVA2D();
  } else {
    throw new Exception("unsupported renderer " + sketchRenderer() + " !?");
  }
}

// JAVA2D Mode
ArrayList<PVector> getVerticesJAVA2D() throws Exception {
  ArrayList<PVector> list = new ArrayList<PVector>(); 
  GeneralPath gpath = null;
  Class pgclass = findClass(g.getClass(), "PGraphicsJava2D");
  if (pgclass == null) {
    throw new Exception("PGraphicsJava2D class not found");
  }
  Field[] fields = pgclass.getDeclaredFields();
  for (Field f : fields) {
    if ("gpath".equals(f.getName())) {      
      f.setAccessible(true);
      gpath = (GeneralPath) f.get(g);
      break;
    }
  }

  if (gpath == null) {
    throw new Exception("class member gpath not found");
  }

  PathIterator i = gpath.getPathIterator(null, 1);
  while (!i.isDone()) {
    double[] coords = new double[6];
    int segType = i.currentSegment(coords);
    if (segType != PathIterator.SEG_CLOSE) {
      list.add(new PVector((float)coords[0], (float)coords[1], 0));
    }
    i.next();
  }
  return list;
}

// P2D Mode
ArrayList<PVector> getVerticesP2D() throws Exception {
  ArrayList<PVector> list = new ArrayList<PVector>(); 
  float[] vertices = {};
  int vertexCount = 0;
  Class pgclass = findClass(g.getClass(), "PGraphicsOpenGL");
  if (pgclass == null) {
    throw new Exception("PGraphicsOpenGL class not found");
  }
  for (Field pgField : pgclass.getDeclaredFields()) {
    if ("tessellator".equals(pgField.getName())) {      
      pgField.setAccessible(true);        
      Object tessellatorObj = pgField.get(g);               
      for (Field tessellatorField : tessellatorObj.getClass().getDeclaredFields()) {
        if ("pathVertexCount".equals(tessellatorField.getName())) {      
          tessellatorField.setAccessible(true);        
          vertexCount = (int) tessellatorField.get(tessellatorObj);
        }          
        if ("pathVertices".equals(tessellatorField.getName())) {      
          tessellatorField.setAccessible(true);        
          vertices = (float[]) tessellatorField.get(tessellatorObj);
        }
      }
    }
  }
  if (vertexCount == 0) {
    throw new Exception("no Vertices found");
  }    
  for (int i = 0; i < vertexCount*3; i+=3) {
    list.add(new PVector(vertices[i], vertices[i+1],0));
  }
  return list;
}

// P3D Mode
ArrayList<PVector> getVerticesP3D() throws Exception {
  ArrayList<PVector> list = new ArrayList<PVector>(); 
  float[] vertices = {};
  int vertexCount = 0;
  Class pgclass = findClass(g.getClass(), "PGraphicsOpenGL");
  if (pgclass == null) {
    throw new Exception("PGraphicsOpenGL class not found");
  }
  for (Field pgField : pgclass.getDeclaredFields()) {
    if ("tessellator".equals(pgField.getName())) {      
      pgField.setAccessible(true);        
      Object tessellatorObj = pgField.get(g);               
      for (Field tessellatorField : tessellatorObj.getClass().getDeclaredFields()) {
        if ("pathVertexCount".equals(tessellatorField.getName())) {      
          tessellatorField.setAccessible(true);        
          vertexCount = (int) tessellatorField.get(tessellatorObj);
        }          
        if ("pathVertices".equals(tessellatorField.getName())) {      
          tessellatorField.setAccessible(true);        
          vertices = (float[]) tessellatorField.get(tessellatorObj);
        }
      }
    }
  }
  if (vertexCount == 0) {
    throw new Exception("no Vertices found");
  }    
  for (int i = 0; i < vertexCount*3; i+=3) {
    PVector m = new PVector(modelX(vertices[i],vertices[i+1],vertices[i+2])
                           ,modelY(vertices[i],vertices[i+1],vertices[i+2])
                           ,modelZ(vertices[i],vertices[i+1],vertices[i+2]));   
    list.add(new PVector(screenX(m.x,m.y,m.z)
                        ,screenY(m.x,m.y,m.z)
                        ,screenZ(m.x,m.y,m.z)));
  }
  return list;
}

```

![video3](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/5/3/53582dae1b2685bfae427645d4cfeb7cdcd59a7d.gif)
