Shape Drawing Guidance - how to draw symmetric filled curves?


Hey guys, I’ve used a curve vertex tool to draw these eye lids on top of a sphere but they turn out pretty asymmetric since usually you need to define points on either side as ‘training’/‘direction’ points to get symmetry but due to the fact that the vertices switch direction, i don’t have a training/direction point at one side. Any tips on how to get symmetry? If you don’t understand what I mean, my code is here:

translate(200,220);
//LEFT EYE TOP 
beginShape();
    curveVertex(-130,-20);
    curveVertex(-117,-80);
    curveVertex(-110,-101.7);
    curveVertex(-95,-113.8);
    curveVertex(-80,-117);
    curveVertex(-65,-113.8);
    curveVertex(-50,-101.7);
    curveVertex(-43,-80);
    curveVertex(-80,-105);
    curveVertex(-117,-80);
     curveVertex(-130,-40);
    endShape();
//LEFT EYE BOTTOM
    beginShape();
    curveVertex(-130,-140);
    curveVertex(-117,-80);
    curveVertex(-110,-59.3);
    curveVertex(-95,-47.2);
    curveVertex(-80,-44);
    curveVertex(-65,-47.2);
    curveVertex(-50,-59.3);
    curveVertex(-43,-80);
    curveVertex(-80,-55);
    curveVertex(-117,-80);
     curveVertex(-130,-120);
    endShape();
//RIGHT EYE TOP
    beginShape();
    curveVertex(130,-20);
    curveVertex(117,-80);
    curveVertex(110,-101.7);
    curveVertex(95,-113.8);
    curveVertex(80,-117);
    curveVertex(65,-113.8);
    curveVertex(50,-101.7);
    curveVertex(43,-80);
    curveVertex(80,-105);
    curveVertex(117,-80);
     curveVertex(130,-40);
    endShape();
//RIGHT EYE BOTTOM
    beginShape();
    curveVertex(130,-140);
    curveVertex(117,-80);
    curveVertex(110,-59.3);
    curveVertex(95,-47.2);
    curveVertex(80,-44);
    curveVertex(65,-47.2);
    curveVertex(50,-59.3);
    curveVertex(43,-80);
    curveVertex(80,-55);
    curveVertex(117,-80);
     curveVertex(130,-120);
    endShape();

Hi,

I think the best way is to use bezierVertex() because curveVertex() does the following :

The first and last points in a series of curveVertex() lines will be used to guide the beginning and end of a the curve.

Here is a simple example where you have a function drawEye() (remember that defining functions is a better way of programming because then if you need to change the location and the size of your eyes for any reason, it’s super easy as changing parameters :wink: ) that does the job with bezier curves (you have an angle parameter to control the shape of the eye) :

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

void draw(){
  background(255);
  
  int eyeAngle = int(map(mouseX, 0, width, 0, 100));
  
  drawEye(width/2 - 110, height/2, 200, 100, eyeAngle);
  drawEye(width/2 + 110, height/2, 200, 100, eyeAngle);
}

void drawEye(int x, int y, int w, int h, int angle){
  noFill();
  
  // DEBUG ------------------------------------------
  //Control points
  stroke(255, 150, 0);
  strokeWeight(2);
  //Up
  line(x - w/2, y, x - w/2 + angle, y - h/2);
  line(x + w/2, y, x + w/2 - angle, y - h/2);
  
  //Down
  line(x - w/2, y, x - w/2 + angle, y + h/2);
  line(x + w/2, y, x + w/2 - angle, y + h/2);
  
  // Points
  strokeWeight(10);
  point(x - w/2 + angle, y - h/2);
  point(x + w/2 - angle, y - h/2);
  point(x - w/2 + angle, y + h/2);
  point(x + w/2 - angle, y + h/2);
  // END DEBUG ----------------------------------------
  
  //Bezier curves
  stroke(0);
  strokeWeight(1);
  
  beginShape();
  vertex(x - w / 2, y); // Left point
  // Up curve
  bezierVertex(x - w/2 + angle, y - h/2, x + w/2 - angle, y - h/2, x + w/2, y);
  // Down curve
  bezierVertex(x + w/2 - angle, y + h/2, x - w/2 + angle, y + h/2, x - w/2, y);
  endShape();
}

Capture d’écran de 2020-05-28 01-10-12

PS: The code is a little bit inefficient because it’s computing the point coordinates multiple times. You can either pre compute them or encapsulate everything in a class. :wink:

1 Like