圆近似,即具有 N 个角的正多边形

Fab*_*res 5 javascript svg d3.js

我必须实现圆形近似的想法,即具有 N 个角的正多边形,而 N 是由用户定义的。

例如,如果 N=3,我将得到一个三角形。当 n=5 时,我会得到一个开始类似于圆形的形状。随着 N 的增加,我会越来越接近圆形。

这个想法与以下问题/解决方案中的提问和回答非常相似: 绘制圆内接的正多边形,但是,他们使用了 raphael.js 而不是 D3.js。

我尝试做的事情:

var vis = d3.select("body").append("svg")
         .attr("width", 1000)
         .attr("height", 667);


var svg = d3.select('svg');
var originX = 200;
var originY = 200;
var outerCircleRadius = 60;


var outerCircle = svg.append("circle").attr({
    cx: originX,
    cy: originY,
    r: outerCircleRadius,
    fill: "none",
    stroke: "black"
});

var chairWidth = 10;

var chairOriginX = originX + ((outerCircleRadius) * Math.sin(0));
var chairOriginY = originY - ((outerCircleRadius) * Math.cos(0));



var chair = svg.append("rect").attr({
    x: chairOriginX - (chairWidth / 2),
    y: chairOriginY - (chairWidth / 2),
    width: chairWidth,
    opacity: 1,
    height: 20,
    fill: "none",
    stroke: "blue"
});

var n_number = 5
var n_angles = 360/n_number
var angle_start=0;
var angle_next;

console.log(chair.node().getBBox().x);
console.log(chair.node().getBBox().y);
chair.attr("transform", "rotate(" + (angle_start+n_angles+n_angles) + ", 200, 200)");



        var circle = svg.append("circle")
                    .attr("cx", 195)
                    .attr("cy", 135)
                    .attr("r", 50)
                    .attr("fill", "red");




var chairOriginX2 = originX + ((outerCircleRadius) * Math.sin(0));
var chairOriginY2 = originY - ((outerCircleRadius) * Math.cos(0));


var chair2 = svg.append("rect").attr({
    x: chairOriginX2 - (chairWidth / 2),
    y: chairOriginY2 - (chairWidth / 2),
    width: chairWidth,
    opacity: 1,
    height: 20,
    fill: "none",
    stroke: "blue"
});

console.log(chair2.node().getBBox().x);
console.log(chair2.node().getBBox().y);
Run Code Online (Sandbox Code Playgroud)

我的想法不起作用,试图创建一个圆(“outerCircle”),我将在圆的圆周(“chair.attr(“transform”...”))内滑动,基于N,获得几个不同的 (x,y) 坐标。然后,我将 (x,y) 坐标提供给多边形。

我相信我解决这个问题的方法是错误的。另外,我遇​​到的问题是我无法在圆周上保持滑动并存储每个不同的(x,y)坐标。我尝试了“console.log(chair2.node().getBBox().x);” 但它总是存储相同的坐标,即它的原点。

enx*_*eta 4

为了清楚起见,我简化了您的代码。要获取圆上某个点的 x,请使用 ,Math.cos(angle)要获取 y,请使用Math.sin(angle)。这是你的错误。现在您可以更改n_number

var SVG_NS = 'http://www.w3.org/2000/svg';

var originX = 200;
var originY = 200;
var outerCircleRadius = 60;

var polygon = document.createElementNS(SVG_NS, 'polygon');
svg.appendChild(polygon);

let points="";

var n_number = 5;
var n_angles = 2*Math.PI/n_number
// building the value of the `points` attribute for the polygon
for(let i = 0; i < n_number; i++){
  let x = originX + outerCircleRadius * Math.cos(i*n_angles);
  let y = originY + outerCircleRadius * Math.sin(i*n_angles);
  points += ` ${x},${y} `;
}
// setting the value of the points attribute of the polygon
polygon.setAttributeNS(null,"points",points)
Run Code Online (Sandbox Code Playgroud)
svg{border:1px solid;width:90vh;}

polygon{fill: none;
    stroke: blue}
Run Code Online (Sandbox Code Playgroud)
<svg id="svg" viewBox = "100 100 200 200" >
  <circle cx="200" cy="200" r="60" fill="none" stroke="black" />  
</svg>
Run Code Online (Sandbox Code Playgroud)

这是另一个演示,我使用输入类型范围来更改n_number变量

var SVG_NS = 'http://www.w3.org/2000/svg';

var originX = 200;
var originY = 200;
var outerCircleRadius = 60;

var polygon = document.createElementNS(SVG_NS, 'polygon');
svg.appendChild(polygon);

let points="";

var n_number = 5;

setPoints(n_number);


theRange.addEventListener("input", ()=>{
  n_number = theRange.value;
  setPoints(n_number)
});


function setPoints(n_number){
var n_angles = 2*Math.PI/n_number;
  points = ""
// building the value of the `points` attribute for the polygon
for(let i = 0; i < n_number; i++){
  let x = originX + outerCircleRadius * Math.cos(i*n_angles);
  let y = originY + outerCircleRadius * Math.sin(i*n_angles);
  points += ` ${x},${y} `;
}
// setting the value of the points attribute of the polygon
polygon.setAttributeNS(null,"points",points);
}
Run Code Online (Sandbox Code Playgroud)
svg{border:1px solid; width:90vh;}

polygon{fill: none;
    stroke: blue}
Run Code Online (Sandbox Code Playgroud)
<p><input type="range" min="3" max="50" value="5" id="theRange" /></p>
<svg id="svg" viewBox = "100 100 200 200" >
  <circle cx="200" cy="200" r="60" fill="none" stroke="black" />  
</svg>
Run Code Online (Sandbox Code Playgroud)