I want to create a function that generates a polygon with N edges and with different size L1 for even edges and L2 for odd edges.

This is my code so far:

function generatePolygon(n, L1, L2) {
    let longerEdges = Math.ceil(n / 2);
    let shorterEdges = n - longerEdges;
    let Lavg = (L1 * longerEdges + L2 * shorterEdges) / n;
    const r = Lavg / (2 * Math.sin(Math.PI / n)); 
    let startAngleRad = Math.PI * (90 - (2 - 1) * 360 / (2 * n)) / 180; 
    let angle = 0; 

    let vertices = [];

    for (let i = 0; i < n; i++) {
        let x = Math.round((r * Math.cos(angle + startAngleRad)) * 10) / 10;
        let y = Math.round((r * Math.sin(angle + startAngleRad)) * 10) / 10;
        
        vertices.push([x, y]);
        
        if ((i + 1) % 2 === 0) {
            angle += 2 * Math.PI * L1 / (Lavg * n);
        } else {
            angle += 2 * Math.PI * L2 / (Lavg * n);
        }
    }

    return vertices;
}

It works ok but i now want to have the base (bottom edge) of the polygon always perfectly horizontal.

This is the result of running my function with N = 10, L1 = 180, L2 = 144: outcome

The problem as you can see is that the base is not perfectly horizontal.

I should also mention that I want the first or the last edges to be the base and I also need this function to work with any N.

1

There are 1 best solutions below

0
maxim1000 On

To get a circle chord of length L, the corresponding angle should be 2*arcsin(L/2R). So to get any sequence of chord lengths (e.g. L1, L2, L1, ...) we can just go along the circle on the corresponding angles.

After making N steps we will walk some angle along the circle. It may be more than 360 degrees, may be less - depending on radius. And there will be radius where we will get exactly 360 degrees in total.

For now I don't see an easy formula for the needed radius, but if approximation is OK, it can be found by a binary search: if we walked more than 360 degrees, we need a smaller radius, if we walked less - a bigger one.

If you need the first edge to be horizontal, you can start at the point corresponding to angle=-arcsin(L1/2R).