# Draw circle shape with vertex

I try to draw a circle with vertex, but my result is very dirty.
I read a few article about that but I don’t find a solution ready to eat, so I coded something like I think possible to work but…so if anybody have suggestion !

http://spencermortensen.com/articles/bezier-circle/

``````/*
* DRAW CIRCLE
*/
PVector [] pts = new PVector[4];
PVector [] pts_a = new PVector[4];
PVector [] pts_b = new PVector[4];
void setup() {
size(400,400,P2D);
PVector offset = new PVector(width/2,height/2);

// normal position
pts[0] = new PVector(0,-1);
pts[1] = new PVector(1,0);
pts[2] = new PVector(0,1);
pts[3] = new PVector(-1,0);

// kappa
int n = pts.length;
float magic_number = (4./3.)*tan(PI/(2*n));

// finalize position
for(int i = 0 ; i < pts.length ; i++) {
}
}

void draw() {
background(125);
fill(255);
stroke(0);
strokeWeight(1);

beginShape();
vertex(pts[0].x,pts[0].y);
bezierVertex(pts_a[0].x,pts_a[0].y,pts_b[0].x,pts_b[0].y,pts[0].x,pts[0].y);
bezierVertex(pts_a[1].x,pts_a[1].y,pts_b[1].x,pts_b[1].y,pts[1].x,pts[1].y);
bezierVertex(pts_a[2].x,pts_a[2].y,pts_b[2].x,pts_b[2].y,pts[2].x,pts[2].y);
bezierVertex(pts_a[3].x,pts_a[3].y,pts_b[3].x,pts_b[3].y,pts[3].x,pts[3].y);
endShape();

strokeWeight(10);
for(int i = 0 ; i < pts.length ; i++) {
stroke(255,0,0);
point(pts[i].x,pts[i].y);
stroke(0,255,0);
point(pts_a[i].x,pts_a[i].y);
stroke(0,255,0);
point(pts_b[i].x,pts_b[i].y);
}
}
``````

1 Like

Hi @Stanlepunk,

By eyeballing the green dots, it looks like the control points of the circle are ok, so maybe the order in which points are supplied to `bezierVertex` needs revising?

For debugging purposes, I find it helpful to distinguish the first from the second control point. This way I know which direction the circle is winding. For that reason, I began by changing one set of green dots to blue:

``````stroke(0, 0, 255);
point(pts_b[i].x, pts_b[i].y);
``````

Then I updated the `bezierVertex` calls:

``````  beginShape();
vertex(pts[0].x, pts[0].y);
bezierVertex(pts_b[0].x, pts_b[0].y,
pts_a[1].x, pts_a[1].y,
pts[1].x, pts[1].y);
bezierVertex(pts_b[1].x, pts_b[1].y,
pts_a[2].x, pts_a[2].y,
pts[2].x, pts[2].y);
bezierVertex(pts_b[2].x, pts_b[2].y,
pts_a[3].x, pts_a[3].y,
pts[3].x, pts[3].y);
bezierVertex(pts_b[3].x, pts_b[3].y,
pts_a[0].x, pts_a[0].y,
pts[0].x, pts[0].y);
endShape();
``````

The first control point supplied to the `bezierVertex` function call is associated with the second anchor point of the previous `bezierVertex` function call (or, at the curve’s beginning, with the anchor point given to the `vertex` call).

If you know about creating classes, a little organization goes a long way. One way to go about it, below, is an object-oriented approach (simplified from a p5.js version here ). First, a knot class which stores two control points along with one anchor point:

``````static class Knot {
PVector coord = new PVector();
PVector foreHandle = new PVector();
PVector rearHandle = new PVector();

Knot(float coordX, float coordY, float coordZ,
float foreX, float foreY, float foreZ,
float rearX, float rearY, float rearZ) {
set(coordX, coordY, coordZ,
foreX, foreY, foreZ,
rearX, rearY, rearZ);
}

Knot set(float coordX, float coordY, float coordZ,
float foreX, float foreY, float foreZ,
float rearX, float rearY, float rearZ) {
coord.set(coordX, coordY, coordZ);
foreHandle.set(foreX, foreY, foreZ);
rearHandle.set(rearX, rearY, rearZ);
return this;
}

static Knot fromAngle(float angle, float radius, float handleMag) {
float cosAngle = cos(angle);
float sinAngle = sin(angle);

float cox = cosAngle * radius;
float coy = sinAngle * radius;

// Tangent is perpendicular to coord. perp(x, y) := (-y, x).
float fhx = cox - sinAngle * handleMag;
float fhy = coy + cosAngle * handleMag;

float rhx = cox + sinAngle * handleMag;
float rhy = coy - cosAngle * handleMag;

return new Knot(
cox, coy, 0.0,
fhx, fhy, 0.0,
rhx, rhy, 0.0);
}
}
``````

It also defines the creation of points from polar coordinates. Then a curve object stores a list of the above.

``````static class Curve {
boolean loop = false;
Knot[] knots;

Curve(boolean loop, Knot... knots) {
this.loop = loop;
this.knots = knots;
}

void draw(PGraphics renderer) {
int knotLength = knots.length;
if (knotLength <= 2) {
// Ignores case where curve with 2 knots could
// be drawn by a single bezierCurve function.
return;
}

Knot prevKnot = knots[0];
Knot currKnot;
PVector coord, foreHandle, rearHandle;
int end = loop ? knotLength + 1: knotLength;

renderer.beginShape();
coord = prevKnot.coord;
renderer.vertex(coord.x, coord.y);

for (int i = 1; i < end; ++i) {
currKnot = knots[i % knotLength];
foreHandle = prevKnot.foreHandle;
coord = currKnot.coord;
rearHandle = currKnot.rearHandle;

renderer.bezierVertex(
foreHandle.x, foreHandle.y,
rearHandle.x, rearHandle.y,
coord.x, coord.y);

prevKnot = currKnot;
}
renderer.endShape();
}

static Curve circle(int count, float offsetAngle, float radius) {
Knot[] knots = new Knot[count];
float invKnCt = 1.0 / (float)count;
float toAngle = TWO_PI * invKnCt;
float mag = radius * (4.0 / 3.0) * tan(HALF_PI * invKnCt);
for (int i = 0; i < count; ++i) {
float angle = offsetAngle + i * toAngle;
}
return new Curve(true, knots);
}
}
``````

This can be tested out in a sketch with

``````Curve circ;

void setup() {
size(512, 512);
circ = Curve.circle(4, 0.0, 128.0);
}

void draw() {
background(255.0);
translate(width * 0.5, height * 0.5);
circ.draw(g);
}
``````
4 Likes

Whaouuuu, very interesting approach of class, I’m familiar with it, but your way is very cool, I love this part `circ = Curve.circle(4, 0.0, 128.0);`So I take a time to study deeply the possibility to customize that to my way, because my final purpose is create a strange circle with a misssing part. I think with our system on on the highway to hell Thanks a lot for your magic code.

Thx for the gold mine… I miss the 3 on 4 on my research of solution