Is it possible to draw a heart shape using the ellipse command and setting the diameter to a function of x?
coding train just did this. subscribe if you haven’t it’s great.
Shameless self-promotion: you can also draw a heart using the curveVertex() function:
I am trying to draw this heart using the coding train video you suggested and substituting the formulas with the ones in the image, but it seems like the frequency of the corner/triangle thingies is too low…
and instead it looks like this 
I’ve tried changing some coefficients in the formula and stuff but nothing seems to work, any ideas on how I could make it look like the original one?
I was just faced with the issue of drawing a heart, and while I realize that there are many solutions, here is mine:
void heart(float x, float y, float s) {
pushMatrix();
rotate(radians(45));
rect(x, y, s, s);
circle(x, y - s/2, s);
circle(x - s/2, y, s);
popMatrix();
}
The result:
I came across a way to draw a heart piecewise out of circle segments, like this:
ellipseMode(RADIUS);
float R0 = 150;
float x1 = -R0;
float y1 = 3*R0/2;
float x2 = -R0;
float y2 = -R0/2;
float x3 = R0;
float y3 = -R0/2;
arc(x1, y1, R0, R0, -PI/2, 0);
arc(x1, y2, R0, R0, HALF_PI, PI);
arc(x1, y2, R0, R0, PI, PI+HALF_PI);
arc(x1, y2, R0, R0, -HALF_PI, 0);
arc(x3, y3, R0, R0, -PI, HALF_PI);
arc(x3, y1, R0, R0, PI, PI+HALF_PI);
It looks like this:
Maybe some day I will re-implement this so that it’s an actual shape (that can be filled), but for now, I didn’t want to try and wrap my head around bezierVertex or curveVertex or whatever of that family would be best for this.
So, I tried implementing filling for the arc heart. After some failures with bezierVertexes and curveVertexes, I became frustrated because simply adding a fill for the shape created by the arcs is so close to being correct - see the image:
Now, I want to ask: is there nothing in Processing, like what I seem to be remembering from OpenGL: an inside/outside “hint” that I can explicitly pass? Or, some other way to manually determine which side of the arc to fill.
As far as I am aware there is no way to fill outside of the arc. I have never seen code for a reverse arc. It sounds like you need a flood fill where everything inside of the lines is filled. I have seen some Processing code for that, but it seems pretty complicated and I always had a difficult time getting it to work correctly. An AI generated example using bezierVertex doesn’t look too bad if you could clean up where the curves meet:
size(600,600);
beginShape();
strokeWeight(3.0);
fill(color(255, 0, 0));
vertex(50, 70); // Bottom tip
bezierVertex(50, 70, 0, 20, 25, 10); // Left curve
bezierVertex(40, 0, 50, 20, 50, 20); // Top left (center)
bezierVertex(50, 20, 60, 0, 75, 10); // Top right (center)
bezierVertex(100, 20, 50, 70, 50, 70); // Right curve
endShape(CLOSE);
Your original idea doesn’t look too bad either. Here’s a resizable example using two arcs and a rotated square:
int w = 100;
void setup() {
size(600, 600);
noStroke();
fill(color(255, 0, 0));
translate(width/2, height/2);
rotate(radians(45));
arc(0, -w/2, w, w, radians(180), radians(360));
arc(-w/2, 0, w, w, radians(90), radians(270));
rect(-w/2, -w/2, w, w);
}
These can be a challenge!
I am comfortable with these now and here is a example to get you started:
// Author: glv
// Date: 2026-02-06
size(300, 500);
background(0);
// Styles
strokeWeight(4);
stroke(128);
noFill();
textSize(24);
textAlign(CENTER, CENTER);
int idx = 0;
beginShape();
for(int i=0; i<270; i+=16)
{
float th = -TWO_PI/360; // These are in radians = 1 deg. increments
float x = 100*cos(i*th) + 150;
float y = 100*sin(i*th) + 150;
vertex(x, y);
//Generate points. These can also be stored!
int xt = round(x);
int yt = round(y);
println(idx, xt, yt);
idx++;
// Added to show steps
pushStyle();
fill(255, 0, 0);
text(i/16, x, y);
popStyle();
}
for(int i=0; i<180; i+=16)
{
float th = -TAU/360; //
int j = 90-i; // reversed order
float x = 100*cos(j*th)+150;
float y = 100*sin(j*th)+150 +200;
vertex(x, y);
// Generate points. These can also be stored!
int xt = round(x);
int yt = round(y);
println(idx, xt, yt);
idx++;
// Added to show steps
push();
fill(0, 255, 0);
text(i/16, x, y);
pop();
}
endShape();
You can modify above to generate:
I later stored the points in an array and plotted one shape:
I did substitute curveVertex() for vertex() and added extra start and end point (see reference below) and got a smooth heart!
Reference:
curveVertex() / Reference / Processing.org
A lot of this was from experience.
:)
Thank you very much! That’s a nice implementation; I did try a similar approach, with a set of points in an array and a curve running through them, but I guess I gave up before I had the points down pat.
Hello @appas,
Another approach…
You can create layers:
size(500, 500);
background(0);
strokeWeight(3);
// Layer 0
//stroke(255, 0, 0);
//left circle
//right circle
// layer 1
translate(100+150, height/2);
fill(255);
noStroke();
rectMode(CENTER);
rect(0, 0, 200, 200 );
// layer 2
// Overlay of rect() + arc()
fill(0);
stroke(255, 0, 0);
ellipseMode(RADIUS);
float R0 = 100;
float x1 = -R0;
float y1 = 3*R0/2.0;
float y2 = -R0/2;
float x3 = R0;
arc(x1, y2+R0+R0/2, R0, R0, -HALF_PI, 0);
arc(x3, y1-R0/2, R0, R0, PI, PI+HALF_PI);
saveFrame("layer.png");
Layered on top of circles:
This can also be done with createGraphics():
createGraphics() / Reference / Processing.org
I’ve picked up plenty of tricks and workarounds over the years!
Have fun!
:)
Hi @svan thanks, I converted your Processing code to L5 code and it works right out of the box:
require ‘L5’
w = 100
function setup()
size(600, 600)
noStroke()
fill(255,0,0)
translate(width/2, height/2)
rotate(radians(45))
arc(0, -w/2, w, w, radians(180), radians(360))
arc(-w/2, 0, w, w, radians(90), radians(270))
rect(-w/2, -w/2, w, w)
end










