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);” 但它总是存储相同的坐标,即它的原点。
为了清楚起见,我简化了您的代码。要获取圆上某个点的 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)