Home > Blockchain >  How to calculate the exact rotation of the polygon?
How to calculate the exact rotation of the polygon?

Time:03-08

I am creating a star shape in svg <polygon></polygon> with this

The code is following

// targeting the svg itself
const svg = document.querySelector("svg");

// variable for the namespace 
const svgns = "http://www.w3.org/2000/svg"

//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";

let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);

svg.appendChild(bg);

let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")

svg.appendChild(ln1);

let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");

svg.appendChild(ln2);

let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");

svg.appendChild(circ);


var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));

var arms = 5;

function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
    var results = "";

    var angle = Math.PI / arms;

    for (var i = 0; i < 2 * arms; i  ) {
        // Use outer or inner radius depending on what iteration we are in.
        var r = (i % 2) == 0 ? outerRadius : innerRadius;

        var currX = centerX   Math.cos(i * angle) * r;
        var currY = centerY   Math.sin(i * angle) * r;

        // Our first time we simply append the coordinates, subsequet times
        // we append a ", " to distinguish each coordinate pair.
        if (i == 0) {
            results = currX   ","   currY;
        } else {
            results  = ", "   currX   ","   currY;
        }
    }

    return results;
};

//creates pentagram
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");


svg.appendChild(poly);
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <link rel="stylesheet" href="style.css"></link>
    <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
    
    
    <script href="index.js"></script>

    
    </svg>
</body>

</html>

I want to correctly align the star with the X Axis which is the red line so that the top of the star is exactly aligned. How do I calculate the exact angle that I can pass on the following code that would correctly align the shape

poly.setAttribute("transform", ``rotate(${exactAngle},${circleCX},${circleCY})``);

CodePudding user response:

Here's a solution that calculates rotation based on number of arms:

For 5 arms (as per question):

// targeting the svg itself
const svg = document.querySelector("svg");

// variable for the namespace 
const svgns = "http://www.w3.org/2000/svg"

//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";

let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);

svg.appendChild(bg);

let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")

svg.appendChild(ln1);

let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");

svg.appendChild(ln2);

let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");

svg.appendChild(circ);


var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));

var arms = 5;

function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
  var results = "";
  var angle = Math.PI / arms;

  for (var i = 0; i < 2 * arms; i  ) {
    // Use outer or inner radius depending on what iteration we are in.
    var r = (i % 2) == 0 ? outerRadius : innerRadius;

    var currX = centerX   Math.cos(i * angle) * r;
    var currY = centerY   Math.sin(i * angle) * r;

    // Our first time we simply append the coordinates, subsequet times
    // we append a ", " to distinguish each coordinate pair.
    if (i == 0) {
      results = currX   ","   currY;
    } else {
      results  = ", "   currX   ","   currY;
    }
  }

  return results;
};

function CalculateAngle(arms) {
  const angle = Math.PI / arms
  let exactAngle = 0
  
  // Conditions based on number of arms
  if (arms % 2 === 0) {
    if (arms % 4 === 0) {
      exactAngle = 0
    } else {
      exactAngle = angle
    }
  } else {
    exactAngle = Math.PI / 2 - angle
  }
  
  // Return as degrees
  return exactAngle * 180 / Math.PI
}

//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);

svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>


For 7 arms:

// targeting the svg itself
const svg = document.querySelector("svg");

// variable for the namespace 
const svgns = "http://www.w3.org/2000/svg"

//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";

let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);

svg.appendChild(bg);

let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")

svg.appendChild(ln1);

let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");

svg.appendChild(ln2);

let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");

svg.appendChild(circ);


var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));

var arms = 7;

function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
  var results = "";
  var angle = Math.PI / arms;

  for (var i = 0; i < 2 * arms; i  ) {
    // Use outer or inner radius depending on what iteration we are in.
    var r = (i % 2) == 0 ? outerRadius : innerRadius;

    var currX = centerX   Math.cos(i * angle) * r;
    var currY = centerY   Math.sin(i * angle) * r;

    // Our first time we simply append the coordinates, subsequet times
    // we append a ", " to distinguish each coordinate pair.
    if (i == 0) {
      results = currX   ","   currY;
    } else {
      results  = ", "   currX   ","   currY;
    }
  }

  return results;
};

function CalculateAngle(arms) {
  const angle = Math.PI / arms
  let exactAngle = 0
  
  // Conditions based on number of arms
  if (arms % 2 === 0) {
    if (arms % 4 === 0) {
      exactAngle = 0
    } else {
      exactAngle = angle
    }
  } else {
    exactAngle = Math.PI / 2 - angle
  }
  
  // Return as degrees
  return exactAngle * 180 / Math.PI
}

//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);

svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>


For 10 arms:

// targeting the svg itself
const svg = document.querySelector("svg");

// variable for the namespace 
const svgns = "http://www.w3.org/2000/svg"

//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";

let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);

svg.appendChild(bg);

let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")

svg.appendChild(ln1);

let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");

svg.appendChild(ln2);

let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");

svg.appendChild(circ);


var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));

var arms = 10;

function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
  var results = "";
  var angle = Math.PI / arms;

  for (var i = 0; i < 2 * arms; i  ) {
    // Use outer or inner radius depending on what iteration we are in.
    var r = (i % 2) == 0 ? outerRadius : innerRadius;

    var currX = centerX   Math.cos(i * angle) * r;
    var currY = centerY   Math.sin(i * angle) * r;

    // Our first time we simply append the coordinates, subsequet times
    // we append a ", " to distinguish each coordinate pair.
    if (i == 0) {
      results = currX   ","   currY;
    } else {
      results  = ", "   currX   ","   currY;
    }
  }

  return results;
};

function CalculateAngle(arms) {
  const angle = Math.PI / arms
  let exactAngle = 0
  
  // Conditions based on number of arms
  if (arms % 2 === 0) {
    if (arms % 4 === 0) {
      exactAngle = 0
    } else {
      exactAngle = angle
    }
  } else {
    exactAngle = Math.PI / 2 - angle
  }
  
  // Return as degrees
  return exactAngle * 180 / Math.PI
}

//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);

svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>


Let's see 51 arms:

// targeting the svg itself
const svg = document.querySelector("svg");

// variable for the namespace 
const svgns = "http://www.w3.org/2000/svg"

//make background
var fill1 = "#e6e6e6";
var fill2 = "transparent";

let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute("class", "bg");
bg.setAttribute("id", "bg");
bg.setAttribute("width", "500");
bg.setAttribute("height", "500");
bg.setAttribute("fill", fill1);

svg.appendChild(bg);

let ln1 = document.createElementNS(svgns, 'line');
ln1.setAttribute("x1", "250");
ln1.setAttribute("y1", "0");
ln1.setAttribute("x2", "250");
ln1.setAttribute("y2", "500");
ln1.setAttribute("stroke-width", "1");
ln1.setAttribute("stroke", "red");
ln1.setAttribute("class", "XAxis")

svg.appendChild(ln1);

let ln2 = document.createElementNS(svgns, 'line');
ln2.setAttribute("x1", "0");
ln2.setAttribute("y1", "250");
ln2.setAttribute("x2", "500");
ln2.setAttribute("y2", "250");
ln2.setAttribute("stroke-width", "2");
ln2.setAttribute("stroke", "green");
ln2.setAttribute("class", "YAxis");

svg.appendChild(ln2);

let circ = document.createElementNS(svgns, 'circle');
circ.setAttribute("cx", "250");
circ.setAttribute("cy", "250");
circ.setAttribute("r", "50");
circ.setAttribute("fill", "none");
circ.setAttribute("stroke", "blue");
circ.setAttribute("id", "circ");
circ.setAttribute("class", "circ");

svg.appendChild(circ);


var circle = document.getElementById('circ');
var circleCX = parseFloat(circle.getAttribute('cx'));
var circleCY = parseFloat(circle.getAttribute('cy'));
var circleR = parseFloat(circle.getAttribute('r'));

var arms = 51;

function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
  var results = "";
  var angle = Math.PI / arms;

  for (var i = 0; i < 2 * arms; i  ) {
    // Use outer or inner radius depending on what iteration we are in.
    var r = (i % 2) == 0 ? outerRadius : innerRadius;

    var currX = centerX   Math.cos(i * angle) * r;
    var currY = centerY   Math.sin(i * angle) * r;

    // Our first time we simply append the coordinates, subsequet times
    // we append a ", " to distinguish each coordinate pair.
    if (i == 0) {
      results = currX   ","   currY;
    } else {
      results  = ", "   currX   ","   currY;
    }
  }

  return results;
};

function CalculateAngle(arms) {
  const angle = Math.PI / arms
  let exactAngle = 0
  
  // Conditions based on number of arms
  if (arms % 2 === 0) {
    if (arms % 4 === 0) {
      exactAngle = 0
    } else {
      exactAngle = angle
    }
  } else {
    exactAngle = Math.PI / 2 - angle
  }
  
  // Return as degrees
  return exactAngle * 180 / Math.PI
}

//creates pentagon
let poly = document.createElementNS(svgns, 'polygon');
poly.setAttribute("points", CalculateStarPoints(circleCX, circleCY, arms, 40, 20));
poly.setAttribute("stroke", "black");
poly.setAttribute("transform", `rotate(${CalculateAngle(arms)},${circleCX},${circleCY})`);

svg.appendChild(poly);
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"></svg>

  • Related