# Draw circle shape with vertex

**URL:** <https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558>\
**Category:** Coding Questions\
**Created:** [February 20, 2019, 11:10am UTC](https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558 "2019-02-20T11:10:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stanlepunk](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stanlepunk/32/11509_2.png) [@Stanlepunk](https://discourse.processing.org/u/Stanlepunk)\
**Post date:** [February 20, 2019, 11:10am UTC](https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558/1 "2019-02-20T11:10:08Z")

</div>

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 !

> <https://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%c3%a9zier-curves>

[http://spencermortensen.com/articles/bezier-circle/](http://spencermortensen.com/articles/bezier-circle/)

```auto
/*
* 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);
  float radius = 100;
  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));

  pts_a[0] = pts[0].copy().add(-magic_number,0);
  pts_a[1] = pts[1].copy().add(0,-magic_number);
  pts_a[2] = pts[2].copy().add(magic_number,0);
  pts_a[3] = pts[3].copy().add(0,magic_number);

  pts_b[0] = pts[0].copy().add(magic_number,0);
  pts_b[1] = pts[1].copy().add(0,magic_number);
  pts_b[2] = pts[2].copy().add(-magic_number,0);
  pts_b[3] = pts[3].copy().add(0,-magic_number);

  // finalize position
  for(int i = 0 ; i < pts.length ; i++) {
    pts[i].mult(radius).add(offset);
    pts_a[i].mult(radius).add(offset);
    pts_b[i].mult(radius).add(offset);
  }
}

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);
  }
}

```

 ![00](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/8/85a50c9b66e56d42672144706b508f36c4c3f3f7.png)

---

<div class="post-metadata">

**Author:** ![behreajj](https://avatars.discourse-cdn.com/v4/letter/b/b5a626/32.png) [@behreajj](https://discourse.processing.org/u/behreajj)\
**Post date:** [February 20, 2019, 4:01pm UTC](https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558/2 "2019-02-20T16:01:08Z")

</div>

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:

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

```

Then I updated the `bezierVertex` calls:

```auto
  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](https://www.openprocessing.org/sketch/616001) ). First, a knot class which stores two control points along with one anchor point:

```auto
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.

```auto
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;
      knots[i] = Knot.fromAngle(angle, radius, mag);
    }
    return new Curve(true, knots);
  }
}

```

This can be tested out in a sketch with

```auto
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);
}

```

---

<div class="post-metadata">

**Author:** ![Stanlepunk](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stanlepunk/32/11509_2.png) [@Stanlepunk](https://discourse.processing.org/u/Stanlepunk)\
**Post date:** [February 20, 2019, 8:55pm UTC](https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558/3 "2019-02-20T20:55:42Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [February 21, 2019, 7:12pm UTC](https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558/4 "2019-02-21T19:12:30Z")

</div>

Related past discussions about squircles / squarcles:

- [Rect corner radius issue. Squircles!?](https://discourse.processing.org/t/rect-corner-radius-issue-squircles/3924/5)
- [https://forum.processing.org/two/discussion/1941/transform-a-square-into-a-circle](https://forum.processing.org/two/discussion/1941/transform-a-square-into-a-circle)
- [https://forum.processing.org/two/discussion/1797/how-to-use-bezier-curve-to-approximate-one-quarter-of-a-circle](https://forum.processing.org/two/discussion/1797/how-to-use-bezier-curve-to-approximate-one-quarter-of-a-circle)
- [https://www.processing.org/discourse/beta/num\_1206172535.html](https://www.processing.org/discourse/beta/num_1206172535.html)

---

<div class="post-metadata">

**Author:** ![Stanlepunk](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stanlepunk/32/11509_2.png) [@Stanlepunk](https://discourse.processing.org/u/Stanlepunk)\
**Post date:** [February 22, 2019, 11:05am UTC](https://discourse.processing.org/t/draw-circle-shape-with-vertex/8558/5 "2019-02-22T11:05:11Z")

</div>

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