Home > Blockchain >  Polygon Generator
Polygon Generator

Time:12-06

I'm trying to generate a polygon with circles inside (JS canvas). Here's a sample expected output:enter image description here

It's basically a 4-sided polygon (square) with circles next to the vertices. Here is what I tried:

However, I don't get the expected outcome. Note: I want this to work for any sized polygon and not just a square. Also, stopping the draw() function to execute gives me a proper square. I believe there's a problem in the draw() function. Any help is appreciated :)

function draw(x, y, ctx){
    ctx.arc(x, y, 4, 0, Math.PI * 2);
    ctx.fillStyle = "#283149";
    ctx.fill(); // create circle
}
function createPolygon(n){
    const canvas = document.getElementById("canvas");
    const ctx = canvas.getContext('2d');
    ctx.reset();
    var size = 60, Xcenter = 80, Ycenter = 80;
    ctx.beginPath();
    ctx.moveTo (Xcenter    size * Math.cos(0), Ycenter    size *  Math.sin(0));          
    
    for (var i = 1; i <= n; i  ) {
        ctx.lineTo (Xcenter   size * Math.cos(i * 2 * Math.PI / n), Ycenter   size * Math.sin(i * 2 * Math.PI / n));
        draw(Xcenter   Math.cos(i * 2 * Math.PI / n), Ycenter    Math.sin(i * 2 * Math.PI / n), ctx);
    }
    ctx.fillStyle = "#00818A"
    ctx.fill();
}
<button onclick="createPolygon(4)">Create 4</button>
<canvas id="canvas"></canvas>

CodePudding user response:

Focus on drawing the polygon first. Then you can add the circles relative to the points of the polygon.

const main = () => {
  const ctx = document.getElementById('poly').getContext('2d');
  Object.assign(ctx.canvas, { width: 350, height: 150 });
  Object.assign(ctx, { strokeStyle: 'red', lineWidth: 1 });
  drawPolygon(ctx, 60, 75, 6, 50, 0, 5, 10);
  drawPolygon(ctx, 180, 75, 4, 50, Math.PI / 4, 10, 25);
  drawPolygon(ctx, 290, 75, 3, 50, Math.PI / 3, 2, 20);
};

const drawPolygon = (
  ctx,
  x,
  y,
  points,
  radius,
  rotation = 0,
  nodeSize = 0,
  nodeInset = 0
) => {
  ctx.beginPath();
  ctx.moveTo(
    x   radius * Math.cos(rotation),
    y   radius * Math.sin(rotation)
  );          
  for (let i = 1; i <= points; i  = 1) {
    const angle = (i * (2 * Math.PI / points))   rotation;
    ctx.lineTo(
      x   radius * Math.cos(angle),
      y   radius * Math.sin(angle)
    );
  }
  ctx.stroke();

  if (!nodeSize) return;
  const dist = radius - nodeInset;
  for (let i = 1; i <= points; i  = 1) {
    const angle = (i * (2 * Math.PI / points))   rotation;
    let x1 = x   dist * Math.cos(angle);
    let y1 = y   dist * Math.sin(angle);
    ctx.beginPath();         
    ctx.arc(x1, y1, nodeSize, 0, 2 * Math.PI);
    ctx.stroke();
  }
};

main();
canvas { background: #FF0; }
<canvas id="poly"></canvas>

Inspired by: How to draw polygons on an HTML5 canvas?

CodePudding user response:

You have to close paths, so you have to use two loops

function draw(x, y, ctx) {
  ctx.beginPath();
  ctx.arc(x, y, 4, 0, Math.PI * 2);
  ctx.fillStyle = "#283149";
  ctx.fill(); // create circle
  ctx.closePath()
}

function createPolygon(n) {
  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext('2d');
  ctx.reset();
  var size = 60,
    Xcenter = 80,
    Ycenter = 80;

  ctx.beginPath();
  ctx.moveTo(Xcenter   size * Math.cos(0), Ycenter   size * Math.sin(0));

  for (let i = 1; i <= n; i  ) {
    ctx.lineTo(Xcenter   size * Math.cos(i * 2 * Math.PI / n), Ycenter   size * Math.sin(i * 2 * Math.PI / n));
  }




  ctx.fillStyle = "#00818A"
  ctx.fill();
  ctx.closePath()

  for (let i = 1; i <= n; i  ) {
    draw(Xcenter   Math.cos(i * 2 * Math.PI / n), Ycenter   Math.sin(i * 2 * Math.PI / n), ctx);
  }
}
<button onclick="createPolygon(4)">Create 4</button>
<canvas id="canvas"></canvas>

  • Related