# Need help with trigonometry or circle geometry

**URL:** <https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773>\
**Category:** Project Guidance\
**Created:** [March 23, 2021, 7:18pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773 "2021-03-23T19:18:17Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yom](https://avatars.discourse-cdn.com/v4/letter/y/c4cdca/32.png) [@Yom](https://discourse.processing.org/u/Yom)\
**Post date:** [March 23, 2021, 7:18pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/1 "2021-03-23T19:18:17Z")

</div>

Hello!

For a little project, I would like to put rectangles around a circle… _with a twist_ : the length of the rectangle, the space between each rectangle, and the circle diameter, are user parameters, they must not be calculated or modified by code. So there will be a maximum of full rectangles around the circle, and the last rectangle will be shorter, to fill the gap. No problem with this part.

My problem is that I would like the rectangles to be placed so that the outside corners of all rectangles are exactly on the circle (see the pictures below). I have no idea how to do that programmatically, without using hardcoded values. It must work for any circle diameter and any rectangle length.

Here is my code, you can try it, just change “showTheExpectedResult” to true, to see the result that I’m expecting

```auto
let showTheExpectedResult = false;
let hardcodedCircleOffset = 22;
let hardcodedRectOffset = 6;
let circleDiameter = 500;
let rectLength = 150;
let rectWidth = 50;
let rectSpacing = -3;

function setup()
{
  createCanvas( 600, 600 );
  background( 200 );
  rectMode( CENTER );
  angleMode( DEGREES );
  translate( width / 2, height / 2 );
  
  
  // Draw circle
  fill( 255, 255, 0 );
  circle( 0, 0, circleDiameter + ( showTheExpectedResult ? hardcodedCircleOffset : 0 ) );
  
  
  // Draw full rectangles
  fill( 0, 255, 0, 128 );
  let numRect = PI * circleDiameter / ( rectLength + rectSpacing );
  let numRectFloored = floor( numRect );
  let rotation = 360 / numRect;
  let radius = ( circleDiameter - rectWidth ) / 2;
  
  for ( let i = 0; i < numRectFloored; i++ )
  {
    let angle = i * rotation;
    push();
    translate( radius * cos( angle ), radius * sin( angle ) );
    rotate( angle );
    rect( 0, 0, rectWidth, rectLength );
    pop();
  }
  
  
  // Draw last rectangle to fill the gap
  radius += showTheExpectedResult ? hardcodedRectOffset : 0;
  let angle = ( numRectFloored - 1 ) * rotation / 2 - 180;
  translate( radius * cos( angle ), radius * sin( angle ) );
  rotate( angle );
  rect( 0, 0, rectWidth, rectLength * ( numRect - numRectFloored ) );
}

```

This is the result of this code (note the smaller rectangle in the upper right):

 ![circle1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/b/bbd1bd154e7a71079867c36feec101ad5902bd63.png)

And what I would like to do, without hardcoding anything:

 ![circle2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/d/de42d6b8823fa6def7a361a98610348d13757b10.png)

I hope someone will be able to help ! Thanks in advance 🙂

---

<div class="post-metadata">

**Author:** ![micycle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micycle/32/201_2.png) [@micycle](https://discourse.processing.org/u/micycle)\
**Post date:** [March 23, 2021, 8:20pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/2 "2021-03-23T20:20:14Z")

</div>

Using [trigonometry - Find distance between point on tangent line and circle. - Mathematics Stack Exchange](https://math.stackexchange.com/questions/1391470/find-distance-between-point-on-tangent-line-and-circle)…

Subtract `sqrt(radius*radius - (rectLength*rectLength)/4)` from the radius:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/e6f50965ab01bed94ee42f00afdb275466b92f3b.png)

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [March 23, 2021, 9:42pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/3 "2021-03-23T21:42:00Z")

</div>

Hi Yom,

The first thing you wanna do when having a problem like this is to draw a figure and start giving names on things. Something like this for example:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/f/f3c6c28248b7ef5e8af6ef5595be1a7ba620a2ab.png)

The segment [BC] correspond to the top of your first rectangle and [DE] the one of the second.  
Then you start labeling the things that you know:

- l: the length of your rectangle
- s: the space between your rectangles
- r: the radius of your circle

And finally you add the elements that you will need in your code:

- x: the distance from the top of one rectangle to the center of the circle
- alpha: the angle covered by a rectangle
- beta: the angle covered by the spacing

Now using basic trigonometry you can easily find formulas for those elements (see screenshot)

For the code, you can reuse the one that you have.  
You need to rotate by `alpha + beta` every time you want to draw a new rectangle.  
And you need to translate by `x - width / 2` since you are using `rectMode(CENTER)`.

To help you, here is the code I made. The last rectangle is missing, I’ll let you add it:

```auto
let r = 250;
let l = 130;
let w = 50;
let s = 15;

function setup()
{
  createCanvas( 600, 600 );
  background( 200 );
  rectMode(CENTER);
  angleMode(RADIANS);
  translate(width/2, height/2);
  
  
  // Draw circle
  fill( 255, 255, 0 );
  circle(0, 0, 2*r);
  
  
  // Compute main parameters
  let offset = sqrt(r*r-l*l/4)-w/2;
  let alpha = 2 * asin(l/(2*r));
  let beta = 2 * asin(s/(2*r));
  let rectNb = floor(TWO_PI / (alpha + beta));
  
  // Draw rectangles
  fill( 0, 255, 0, 128 ); // Set rect color
  for (let i = 0; i < rectNb; i++) {
    push();
    rotate(i * (alpha + beta));
    translate(0, -offset);
    rect(0, 0, l, w);
    pop();
  }
}

```

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [March 23, 2021, 11:26pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/4 "2021-03-23T23:26:42Z")

</div>

Hi,

Nice exercise here! 😉

Let’s first see how you can display a rectangle, you have two ways : either from it’s center (by using the `rectMode(CENTER)` function or by its upper left corner (by default).

Since you want the corners to touch, it will be easier to draw the rectangles from their corner.

So you’ll have this :

 ![Capture d’écran de 2021-03-23 21-25-25](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/b/bf1371c21348498fb83ffc5d354c7871353d4150.png)

The idea is that we are going to draw each rectangle from its corner and rotate each time (full circle divided by the number of rectangles).

After one rectangle, we need to translate to the next location, therefore translating on the x axis by the length of the side of the polygon.

Now let’s do the math part, with the help of a geometric figure :

 ![Capture d’écran de 2021-03-24 00-14-53](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/3a6c237f783cac52ae6e8051388091b4cfb10656.png)

In this case, we divided the circle into 8 parts (hence 8 rectangles) and we annotated the different segments.

We only know `alpha` and `b` (which is the radius of the circle) so let’s solve some equations :

 ![Capture d’écran de 2021-03-24 00-17-52](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/aee64bd006c15ba1686c3c6979f56c6b2a0e915b.png)

So we have this code :

```auto
void rectanglesAroundCircle(float x, float y, int sides, float radius) {
  pushMatrix();
  translate(x, y);
  
  fill(255, 255, 0);
  circle(0, 0, radius * 2);
  
  // The angle between two positions
  float alpha = TWO_PI / sides;
  
  // Translate to the first position
  translate(radius, 0);
  
  // We first do the initial rotation
  float oppositeAngle = (PI - alpha) / 2.0;
  rotate(PI - oppositeAngle);
  
  // Compute the length of a side of the polygon
  float sideLength = 2 * radius * sqrt(1 - pow(cos(alpha / 2), 2));
  
  fill(0, 255, 0, 100);
  
  // Display the rectangles
  for (int i = 0; i < sides; i++) {
    rect(0, 0, sideLength, 30);
    
    // Translate then rotate to the next position
    translate(sideLength, 0);
    rotate(alpha);
  }
  
  popMatrix();
}

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

void draw() {
  background(200);
  
  rectanglesAroundCircle(width / 2, height / 2, 8, 200);
  
  noLoop();
}

```

![rect_circle](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/3284a9567267310370bd730840c26acb91f8aa1d.png)

This is maybe not the ideal solution but I had fun doing it! 😀

Have fun too!

> Note : I realized that you wanted to have gaps between your rectangles, this code doesn’t provide this and @jb4x 's answer is the way to go!

---

<div class="post-metadata">

**Author:** ![Yom](https://avatars.discourse-cdn.com/v4/letter/y/c4cdca/32.png) [@Yom](https://discourse.processing.org/u/Yom)\
**Post date:** [March 24, 2021, 12:19pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/5 "2021-03-24T12:19:57Z")

</div>

Thank you so much for your help guys! jb4x won, but all answers were useful 🙂

I couldn’t find how to do the last rectangle until I realized that my calculation of its length was wrong!

So here is the final code, it works quite well 🙂 But do you see anything wrong, or which could be simplified maybe ?

```auto
let r = 250;
let l = 130;
let w = 50;
let s = 15;

function setup()
{
  createCanvas( 600, 600 );
  background( 200 );
  rectMode(CENTER);
  angleMode(RADIANS);
  translate(width/2, height/2);
  
  
  // Draw circle
  fill( 255, 255, 0 );
  circle(0, 0, 2*r);
  
  
  // Compute main parameters
  let offset = sqrt(r*r-l*l/4)-w/2;
  let alpha = 2 * asin(l/(2*r));
  let beta = 2 * asin(s/(2*r));
  let rectNbF = TWO_PI / (alpha + beta);
  let rectNb = floor(rectNbF);
  
  // Draw rectangles
  fill( 0, 255, 0, 128 ); // Set rect color
  for (let i = 0; i < rectNb; i++) {
    push();
    rotate(i * (alpha + beta));
    translate(0, -offset);
    rect(0, 0, l, w);
    pop();
  }
  
  // Draw last rectangle if it's not too small
  l = 2 * r * sin((TWO_PI-(rectNb*(alpha+beta))-beta)/2);
  if (l >= 5)
  {
    offset = sqrt(r*r-l*l/4)-w/2;
    alpha = (alpha + (2 * asin(l/(2*r)))) / 2;
    rotate( -(alpha + beta) );
    translate( 0, -offset );
    rect( 0, 0, l, w );
  }
}

```

 ![circle3](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/3273768bb8745bf53e6ee2465f771d057fee64cf.png)  
I’m always amazed by the beauty and power of maths!

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [March 24, 2021, 1:18pm UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/6 "2021-03-24T13:18:42Z")

</div>

Yey, looks good! 😉

Next step : find a way for the inside corners to touch which mean determining the the appropriate height of the rectangles.

---

<div class="post-metadata">

**Author:** ![Yom](https://avatars.discourse-cdn.com/v4/letter/y/c4cdca/32.png) [@Yom](https://discourse.processing.org/u/Yom)\
**Post date:** [March 25, 2021, 8:39am UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/7 "2021-03-25T08:39:55Z")

</div>

I thought I had it, but the length of the last rectangle was still wrong ! I noticed it after I “zoomed” a lot on the corners.

Here is, I think, the correct way to calculate it (but correct me if I’m still wrong!)

```auto
l = 2 * r * sin((TWO_PI-(rectNb*(alpha+beta))-beta)/2);

```

I have edited the previous code to hide my shame 😃

---

<div class="post-metadata">

**Author:** ![Yom](https://avatars.discourse-cdn.com/v4/letter/y/c4cdca/32.png) [@Yom](https://discourse.processing.org/u/Yom)\
**Post date:** [March 25, 2021, 8:51am UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/8 "2021-03-25T08:51:59Z")

</div>

Maybe as an another exercice, and that shouldn’t be too hard now, but for my needs I really needed the external space between rectangles, and the rectangle dimensions to be user parameters 🙂

And thanks for your detailed answer, even if the result wasn’t what I expected, I’m sure it will help other people 😉

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [March 25, 2021, 9:59am UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/9 "2021-03-25T09:59:29Z")

</div>

Hi Yom,

Happy to see that you are making nice progress.  
You got it right 👍

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [March 25, 2021, 10:23am UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/10 "2021-03-25T10:23:46Z")

</div>

understanding polar coordinates is a good place to start.

[https://www.mathsisfun.com/polar-cartesian-coordinates.html](https://www.mathsisfun.com/polar-cartesian-coordinates.html)

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [March 26, 2021, 4:51am UTC](https://discourse.processing.org/t/need-help-with-trigonometry-or-circle-geometry/28773/11 "2021-03-26T04:51:24Z")

</div>

here is a little sketch for rose petals that may help to understand a bit more about trig in context. Change the value of osc to change the number of petals, and change the function as you desire for different effects.

Then change the value of the offset for even more complexity. This is the basics for visualising most curves so you arent restricted to just rose petals, but in that case you need to pas different osc variables to x and y and different functions to x and y

```auto
int total = 1000;
float x,y,radius = 100;
PVector pos;
void setup(){
  size(400,400);
  pos = new PVector(width/2,height/2);
};

void draw(){
  background(255);
  //radius = 
  for(int i=0;i<total;i++){
    
    float angle = ((2*PI)/total)*i;
    int osc = 4;
    float offset = 0;
    //offset = cos(angle);
    //offset = sin(angle);
    //offset = tan(angle);
    //offset = 1/cos(angle);
    //offset = 1/sin(angle);
    //offset = 1/tan(angle);
    
    //offset = sin(angle*osc);
    //offset = tan(angle*osc);
    //offset = 1/cos(angle*osc);
    //offset = 1/sin(angle*osc);
    //offset = 1/tan(angle*osc);
    float func = 0;
    
    func = sin((angle+offset)*osc);
    //func = cos((angle+offset)*osc);
    //func = tan((angle+offset)*osc);
    
    //func = sin(angle+offset*osc);
    //func = cos(angle+offset*osc);
    //func = tan(angle+offset*osc);
    
    //func = sin((angle+offset)*osc)*cos((angle+offset)*osc);
    //func = sin((angle+offset)*osc)*cos(angle+offset*osc);
    //func = sin((angle+offset)*osc)*cos(angle+offset*osc);
    //func = sin((angle+offset)*osc)*cos(angle+offset*osc);
    //func = sin((angle+offset)*osc)*cos(angle+offset*osc);
    //func = sin((angle+offset)*osc)*cos(angle+offset*osc);
    x = pos.x+radius * cos(angle)*func;
    y = pos.y+radius * sin(angle)*func;
    stroke(0);
    strokeWeight(1);
    point(x,y);
  }
};

```
