Filling a curveVertex shape

Hoping to get some help on a problem that has been baffling me for hours. There are two parts to the problem which may or may not be connected.

The code below will execute, but only after a length pause which I believe is tied to this error below about system memory:

java.lang.ArrayIndexOutOfBoundsException: 22
at jogamp.opengl.glu.tessellator.PriorityQSort.pqInit(PriorityQSort.java:151)
at jogamp.opengl.glu.tessellator.Sweep.InitPriorityQ(Sweep.java:1246)
at jogamp.opengl.glu.tessellator.Sweep.__gl_computeInterior(Sweep.java:1313)
at jogamp.opengl.glu.tessellator.GLUtessellatorImpl.gluTessEndPolygon(GLUtessellatorImpl.java:526)
at com.jogamp.opengl.glu.GLU.gluTessEndPolygon(GLU.java:896)
at processing.opengl.PJOGL$Tessellator.endPolygon(PJOGL.java:641)
at processing.opengl.PGraphicsOpenGL$Tessellator.tessellatePolygon(PGraphicsOpenGL.java:12621)
at processing.opengl.PGraphicsOpenGL.tessellate(PGraphicsOpenGL.java:2255)
at processing.opengl.PGraphicsOpenGL.endShape(PGraphicsOpenGL.java:1965)
at processing.core.PGraphics.endShape(PGraphics.java:1707)
at processing.core.PApplet.endShape(PApplet.java:11648)
at unknown_pleasures_ized.draw(unknown_pleasures_ized.java:81)
at processing.core.PApplet.handleDraw(PApplet.java:2482)
at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:866)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Tessellation Error: out of memory

The second part of the problem is the resulting image doesn’t properly implement the fill() as you can see in the image below. Notice how you can see underlying lines show up through the humps where there is overlap. Strangely, just the lines (stroke) and not the fill.

When I take out the “fill(0,0,0)” and just put in “noFill()” it runs without pause or error. But I lose the effect of the layering without the fill.

Any help on this would be greatly appreciated.

color[] colorArray = {
  color(238, 243, 239),
  color(69, 189, 207),
  color(234, 84, 93)
};

float theRad = 200;
int numLines = 20;     //number per half
float segmentSize = theRad / numLines;    //dy in source code
float lineSize = 4;            //make odd for a center point
float yStart = segmentSize / 2;

void setup(){
  size(650, 650, P3D);
  smooth(8);
  noLoop();
}

void draw(){
  background(colorArray[0]);
  translate(width/2, height/2);
  for(int i=0; i<(numLines*2)+1; i++){
    float yVal = -theRad + (yStart + (i * segmentSize));
    float pointY = yVal/theRad;
    float pointX = cos(asin(pointY));
    int peakPt = 0 + 50;  
    float mu = randNormal(peakPt, 50);
    float sigma = randNormal(30, 30);
    
    /* make lines from curves */
    //noFill();
    fill(0,0,0);
    beginShape();
    strokeWeight(lineSize);
    stroke(colorArray[1]);
    curveVertex(pointX*theRad, pointY*theRad);
    curveVertex(pointX*theRad, pointY*theRad);
    
    float lineLength = (pointX*theRad) * 2;       
    for(int j=0; j<lineLength; j++){
      float xPos = (pointX*theRad)-j;
      float yPos = 0;
      if(i >= 7 && i <= (numLines*2) - 13){  
        yPos = (pointY*theRad) - 1000 * normalPDF(xPos, mu, sigma);
      } else{
        yPos = pointY*theRad;
      }
      float lerpAmt = map(j, 0, lineLength, 0, 1);
      stroke(lerpColor(colorArray[1], colorArray[2], lerpAmt));
      curveVertex(xPos, yPos);
    }
    stroke(colorArray[2]);
    curveVertex(-pointX*theRad, pointY*theRad);
    curveVertex(-pointX*theRad, pointY*theRad);
    endShape();
    
    // end caps
    noStroke();
    fill(colorArray[1]);
    ellipse(pointX*theRad, pointY*theRad, lineSize, lineSize);
    fill(colorArray[2]);
    ellipse(-pointX*theRad, pointY*theRad, lineSize, lineSize);
  }
}

Hello,

I was just tinkering a bit with your code…

Your code was not complete so I embellished.

Some success with blendMode(DARKEST) and changing order that they they were drawn.

You may notice the black under the lines once you integrate your code.
You can spit up the curveVertex() and only fill areas you need to.

color[] colorArray = {
  color(238, 243, 239),
  color(69, 189, 207),
  color(234, 84, 93)
};

float theRad = 200;
int numLines = 20;     //number per half
float segmentSize = theRad / numLines;    //dy in source code
float lineSize = 4;            //make odd for a center point
float yStart = segmentSize / 2;

int mul;

void setup(){
  size(650, 650, P3D);
  smooth(8);
  //noLoop();
  blendMode(DARKEST);
}

void draw()
  {
  background(colorArray[0]);
  translate(width/2, height/2);
  
  //for(int i=0; i<(numLines*2)+1; i++)
  for(int i=(numLines*2); i>=0; i--)
    {  
    float yVal = -theRad + (yStart + (i * segmentSize));
    float pointY = yVal/theRad;
    float pointX = cos(asin(pointY));
    int peakPt = 0 + 50;  
    //float mu = randNormal(peakPt, 50);
    //float sigma = randNormal(30, 30);
    
    /* make lines from curves */
    //noFill();
    fill(0,0,0);
    beginShape();
    strokeWeight(lineSize);
    stroke(colorArray[1]);
    curveVertex(pointX*theRad, pointY*theRad);
    //curveVertex(pointX*theRad, pointY*theRad);
    
    float lineLength = (pointX*theRad) * 2;       
    
    for(int j=0; j<lineLength; j++)
      {
      float xPos = (pointX*theRad)-j;
      float yPos = 0;
      //if(i >= 7 && i <= (numLines*2) - 13)
      //(i >= 10 && i <20 && xPos>-100 && xPos< 100)
      if(i >= 10 && i <20)
        {  
        //yPos = (pointY*theRad) - 1000 * normalPDF(xPos, 5, 5);
        if (i%4==0)
          mul = 2;
        else
          mul = 1;
          
        yPos = (pointY*theRad) - (abs(mul*30*sin(xPos*(TAU)/(lineLength))));  
        } 
      else
        {
        yPos = pointY*theRad;
        }
      
      float lerpAmt = map(j, 0, lineLength, 0, 1);
      stroke(lerpColor(colorArray[1], colorArray[2], lerpAmt));
      curveVertex(xPos, yPos);
      }
    stroke(colorArray[2]);
    //curveVertex(-pointX*theRad, pointY*theRad);
    curveVertex(-pointX*theRad, pointY*theRad);
    //curveVertex(pointX*theRad, pointY*theRad);
    endShape();
    
    // end caps
    //noStroke();
    //fill(colorArray[1]);
    //ellipse(pointX*theRad, pointY*theRad, lineSize, lineSize);
    //fill(colorArray[2]);
    //ellipse(-pointX*theRad, pointY*theRad, lineSize, lineSize);
    }
  }

:)

Thanks for the response @glv. A couple of things:

  1. Getting rid of the second starting and second end curveVertex() seemed to solve the memory issue. Which I don’t quite understand because the Processing reference indicates you require both at either end.

  2. Your solution seems to be contingent on the blendMode(DARKEST) but what if black is not the fill() color? And drawing from the bottom-up would produce some unexpected results if the fill() wasn’t black. I would expect that if drawing from the top-down that the lower lines with a hump would cover any already drawn lines without a blendMode().

I’d really like to understand why my code as is doesn’t overwrite pixels and you can see lines underneath the fill()?

1 Like

Hello,

Works in P2D:

int mul;

int xPos;
int yPos;
int zPos;

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

void draw()
  {
  background(255);
  translate(width/2, height/2);
 
 //Try both of these:
  for(int y=-100; y<=100; y+=10)
  //for(int y=100; y>=-100; y-=10)
    {  
    fill(0);
    strokeWeight(2);
    stroke(0, 255, 0);
  
  beginShape();        
    for(int x=-100; x<=100; x+= 10)
      {      
      if (y%40==0)
        mul = 2;
      else
        mul = 1;
           
      float xPos = x;     
      float yPos = y-(mul*20+mul*20*sin((xPos*(TAU/200) +TAU/4)));  
      
      //Google 10+10*sin((x*(2*PI/200) -(2*PI)/4)
      vertex(xPos, yPos);   
      }
  endShape(CLOSE);
    }
  }

image

And with z offsets in P3D:


int mul;

int xPos;
int yPos;
float zPos;

void setup()
  {
  size(400, 400, P3D);
  ortho();
  }

void draw()
  {
  background(255);
  translate(width/2, height/2);
  
  zPos = 0;
  
  for(int y=-100; y<=100; y+=10)
  //for(int y=100; y>=-100; y-=10)
    {  
    fill(0);
    strokeWeight(2);
    stroke(0, 255, 0);
  
  beginShape();        
    for(int x=-100; x<=100; x+= 10)
      {      
      if (y%40==0)
        mul = 2;
      else
        mul = 1;
           
      float xPos = x;     
      float yPos = y-(mul*20+mul*20*sin((xPos*(TAU/200) +TAU/4)));  
      //Google 10+10*sin((x*(2*PI/200) -(2*PI)/4)
      vertex(xPos, yPos, zPos+=.1);   
      }
  endShape(CLOSE);
    }
  }

image

Related reference:

:)

interesting, that’s helpful. the one remaining issue is that in P2D i’m not able to vary the color of the stroke as in my original sketch. if i can accomplish that in P2D somehow, that would be even better. my goal in using curveVertex() for the lines was to be able to export as a SVG and have the lines. if i just use a series of ellipses then i wouldn’t be able to get that. or would i? or (as referenced in the link provided) if i explicit ly define a Z value for each curveVertex(), would that resolve the issue by forcing a layering?

@travis.stdenis

This is as far as my exploration into this goes.

Keep at it!

:)

It is the same here in P2D as in P3D and I tried your lerp code example.

Go for it!
I was able to glean insight from here:
https://processing.org/reference/libraries/svg/index.html
and generate an SVG within a few minutes.
I tried both vertex() and curveVertex() and also looked at the SVG file source.

Try it.
In both of my examples I provided I explored this by writing simple code examples.

:)