# arranging s around a polygon (HTML, css, .ejs)

I want to arrange some rectangular div components around a regular polygon. Basically one of the long sides of the divs will be coincident with a line segment around the polygon.

In the final code, I’ll use .ejs (since the number of sides of the polygon is dynamic, 3-10 sides). In my “quick and dirty” testing I’m doing a triangle in just HTML and CSS to get the math right.

I have a “very close” solution already and am wondering how to get it “exact” and am also wondering why my geometry intuition is so far off.

HTML and CSS:

```div {
position: absolute;
left: 200px;
top: 200px;
width: 80px;
height: 40px;
background-color: skyblue;
}

.rotatedA {
transform: translateY(-60px) translateX(-35px) rotate(300deg);
background-color: blue;
}

.rotatedB {
transform: translateY(-60px) translateX(35px)  rotate(60deg);
background-color: red;
}```
```<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<title>title</title>
<body>
<div>Normal</div>
<div class="rotatedA">Rotated</div>
<div class="rotatedB">Rotated</div>
</body>
</html>```

The first attempt I rotated “A” by 60 and “B” by -60 and did a translateY equal to the div height. When that did not work I played around with it. On this last attempt (close but not perfect since the rotations won’t give an integer) it seems like the Y adjustment is 1.5x (item height + cos(60)) but the X adjustment is 1/2 of sin(60) (I don’t understand why).

Since my results aren’t going to be an integer number of pixels what is the correct way to do this? Also, I don’t understand why my geometry is so off (I could understand sin(60) but 1/2(sin(60)) doesn’t make sense to me

Here’s a mathematical way; the number and dimensions are read by the script, then the divs are arranged accordingly. I also made sure that the wrapper container has the correct dimensions so it can be used with other elements:

```function arrange(wrapper) {
wrapper.style.position = "relative";
const rects = Array.from(wrapper.children);

const n = rects.length;
/* dimensions of a rectangle */
const bb = rects.getBoundingClientRect();
const a = bb.width;
const h = bb.height;

/* incircle radius of regular polygon */
const r = a * 0.5 / Math.tan(Math.PI / n);

/* radius of outer circle */
const bigR = Math.sqrt((r + h) * (r + h) + a * a / 4);

rects.forEach((rect, i) => {
const angle = i * (360 / n);
if (angle) rect.style.transform = `rotate(\${angle}deg)`;
rect.style.position = angle ? "absolute" : "relative";
rect.style.marginBottom = bigR + r + "px";
rect.style.transformOrigin = `\${a/2}px \${-r}px`;
rect.style.left = bigR - a / 2 + "px";
rect.style.top = bigR + r + "px";
});
if (window.getComputedStyle(wrapper).display == "inline-block")
wrapper.style.width = 2 * bigR + "px";
}

arrange(document.querySelector('#polygon'));```
```#polygon {
border: 1px solid black;
display: inline-block;
}

#polygon div {
width: 80px;
height: 20px;
background-color: skyblue;
text-align: center;
}```
```<div id="polygon">
<div>Normal</div>
<div>Rotated</div>
<div>Rotated</div>
<div>Rotated</div>
<div>Rotated</div>
<div>Rotated</div>
<div>Rotated</div>
</div>```

The basic idea is to

1. calculate the in-circle’s radius of the polygon based on the width of a rectangle
2. set `transform-origin` accordingly centered and above the first rectangle
3. arrange the others by rotating them
4. (do more calculations so the wrapper element encompasses everything exactly)