<main class="pa4 dark-gray mw7 center sans-serif min-vh-100 flex flex-column flex-row-ns items-center">
  <form class="measure-wide mr4-ns mb4 mb0-ns f5">
    <fieldset class="ba b--transparent pa0 mh0">
     
      <legend class="f5 b ph0 mh0 ttu tracked bb bw2 pv2 db w-100">
        Polygon Generator
      </legend>
      
      <div class="mt5 mb4">
        <label class="f5 ttu tracked db b mb2" for="js-side-count">
          Number of Sides
        </label>
        <input class="b pa2 input-reset ba bw2 bg-white b--dark-gray w-100" 
               type="number" id="js-side-count" value="8">
      </div>
      
      <div class="mv4">
        <label class="f5 ttu tracked db b mb2" for="js-radius">
          Radius
        </label>
        <input class="b pa2 input-reset ba bw2 bg-white b--dark-gray w-100"
               type="number" id="js-radius" value="200">
      </div>      
      
      <fieldset class="ba b--transparent pa0 mh0 mt4 mb5">
        <legend class="f5 ttu tracked db b mb2">Center</legend>
        
        <label class="f5 ttu tracked db b mb2 clip" for="js-cx">
          Center X Coordinate
        </label>
        <label class="f5 ttu tracked db b mb2 clip" for="js-cy">
          Center Y Coordinate
        </label>
        <div class="flex">
          <input class="b pa2 input-reset ba bw2 bg-white b--dark-gray w-100 mr3"
               type="number" id="js-cx" value="396">        
          <input class="b pa2 input-reset ba bw2 bg-white b--dark-gray w-100"
               type="number" id="js-cy" value="418">
        </div>
      </fieldset>
    </fieldset>
    
    <div>
      <input class="b pa3 input-reset ba b--dark-gray bw2 bg-white grow pointer f6 dib ttu tracked"
             id="js-generate" type="button" value="Generate">
    </div>
  </form>
  
  <div class="flex-auto flex items-center justify-center w-100">
    <div class="w-100">
      <svg class="w-100 white debug-grid mb4 db" viewBox="0 0 800 800" 
           stroke="#111" fill="none" stroke-width="4"
           id="js-svg">
        <polygon id="js-polygon" points="" />
      </svg>

      <pre id="js-result" class="code pa3 bg-near-white mb0 overflow-scroll"></pre>
    </div>
  </div>
</main>
pre { 
  overflow-wrap: break-word;
}
const sideCountEl = document.querySelector('#js-side-count');
const radiusEl = document.querySelector('#js-radius');
const cxEl = document.querySelector('#js-cx');
const cyEl = document.querySelector('#js-cy');
const generateEl = document.querySelector('#js-generate');
const polygonEl = document.querySelector('#js-polygon');
const resultEl = document.querySelector('#js-result');
const svgEl = document.querySelector('#js-svg');

function pts(sideCount, radius) {
  const angle = 360 / sideCount;
  const vertexIndices = range(sideCount);
  const offsetDeg = 90 - ((180 - angle) / 2);
  const offset = degreesToRadians(offsetDeg);

  return vertexIndices.map((index) => {
    return {
      theta: offset + degreesToRadians(angle * index),
      r: radius,
    };
  });
}

function range(count) {
  return Array.from(Array(count).keys());
}

function degreesToRadians(angleInDegrees) {
  return (Math.PI * angleInDegrees) / 180;
}


function polygon([cx, cy], sideCount, radius) {
  return pts(sideCount, radius)
    .map(({ r, theta }) => [
      cx + r * Math.cos(theta), 
      cy + r * Math.sin(theta),
    ])
    .join(' '); 
}

function generatePolygon() {
  const sideCount = +sideCountEl.value;
  const radius = +radiusEl.value;
  const cx = +cxEl.value;
  const cy = +cyEl.value;
  const s = 2 * radius + 50;

  const res = polygon([cx, cy], sideCount, radius);
  const viz = polygon([s / 2, s / 2], sideCount, radius);
  
  svgEl.setAttribute('viewBox', `0 0 ${s} ${s}`);
  polygonEl.setAttribute('points', viz);
  resultEl.innerText = `<polygon points="${res}" />`;
}

generateEl.onclick = generatePolygon;
window.onload = generatePolygon;
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/tachyons/4.6.2/tachyons.min.css

External JavaScript

This Pen doesn't use any external JavaScript resources.