我试图将使用d3.arc
生成的弧完美地嵌套在另一个弧内。
我可以通过绘制"我自己":
来做到这一点
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
function arc_position(x, y, radius, angle) {
return {
x: x + (radius * Math.cos(angle)),
y: y + (radius * Math.sin(angle))
};
}
function describe_arc(x, y, radius, startAngle, endAngle) {
var s = arc_position(x, y, radius, endAngle);
var e = arc_position(x, y, radius, startAngle);
var sweep = e - s <= 180 ? '0' : '1';
var d = [
'M', s.x, s.y,
'A', radius, radius, 0, sweep, 0, e.x, e.y
].join(' ');
return d;
}
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g");
var s = arc_position(250, 250, 200, Math.PI/2);
var e = arc_position(250, 250, 200, (Math.PI * 3)/2);
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "20px")
.attr("d", describe_arc(250,250,180,(Math.PI * 3)/2, Math.PI/2));
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "20px")
.attr("d", "M" + (s.x + 30) + "," + s.y + "L" + (e.x + 30) + "," + e.y);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "20px")
.attr("d", describe_arc(250,250,200,(Math.PI * 3)/2, Math.PI/2));
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "20px")
.attr("d", "M" + (s.x + 10) + "," + s.y + "L" + (e.x + 10) + "," + e.y);
</script>
</body>
</html>
&#13;
但我无法找出使用d3.arc
的方法:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform","translate(250,250)");
var arc = d3.arc()
.innerRadius(0)
.outerRadius(200)
.startAngle(0)
.endAngle(Math.PI);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "20px")
.attr("d", arc());
arc.outerRadius(200 - 40);
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "20px")
.attr("d", arc())
.attr("transform", "translate(20,0)")
</script>
</body>
</html>
&#13;
有什么想法吗?
答案 0 :(得分:5)
我认为只使用d3.arc
有一种很好的方法可以做到这一点,因为这是用于绘制圆圈的部分而你是在尝试绘制部分椭圆。
您可以使用笔划宽度和内弧半径offsetAngle = sin(stroke width / inner radius)
生成角度偏移。弧startAngle
为offsetAngle
,endAngle
为Math.PI - offsetAngle
。
不幸的是,这将生成包含圆的中心点的路径。你可以通过从生成的路径(L0,0
)中删除innerArc().replace("L0,0","")
来合并一些有效的东西,这样就会给你提供你想要的东西,尽管是一种丑陋的方式。
因为它是一个相当简单的路径,所以最好使用自己的路径生成器代替它。
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform","translate(250,250)");
var outerRadius = 200;
var stroke = 20;
var innerRadius = outerRadius - stroke;
var innerAngle = Math.sin(stroke/innerRadius);
var outerArc = d3.arc()
.innerRadius(0)
.outerRadius(outerRadius)
.startAngle(0)
.endAngle(Math.PI);
var innerArc = d3.arc()
.innerRadius(0)
.outerRadius(innerRadius)
.startAngle(innerAngle)
.endAngle(Math.PI - innerAngle);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", stroke)
.attr("d", outerArc());
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", stroke)
.attr("d", innerArc().replace("L0,0",""));
</script>
</body>
</html>
&#13;
答案 1 :(得分:3)
(这不是一个答案,只是一个评论,我选择伪装成答案,因为我需要S.O.片段)
我相信Paul S是正确的,他应该得到绿色标记的大奖:你在内(橙色)路径上想要画的是< strong>不圆弧,而是椭圆。并且,正如文档所说,
电弧发生器产生圆形或环形扇区
,这不适用于创建椭圆扇区。
您可以在以下演示中轻松看到:使用for循环,我们绘制外半径减小的弧。完美填充每个弧的内部空间的唯一方法是,如果下一个较小的拱门具有先前的相同的中心,则更大的一个:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform","translate(250,250)");
var arc = d3.arc()
.innerRadius(0)
.outerRadius(200)
.startAngle(0)
.endAngle(Math.PI);
var color = d3.scaleOrdinal(d3.schemeCategory10);
for(var i = 0; i<11; i++){
svg.append("path")
.style("stroke", color(i))
.style("fill", "none")
.style("stroke-width", "20px")
.attr("d", arc());
arc.outerRadius(200 - 20*i);
};
</script>
</body>
</html>
&#13;
有一种更简单的方法可视化。让我们创建一个具有巨大笔划的圆弧:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform","translate(250,250)");
var arc = d3.arc()
.innerRadius(0)
.outerRadius(150)
.startAngle(0)
.endAngle(Math.PI);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "100px")
.attr("d", arc());
</script>
</body>
</html>
&#13;
看看蓝色圆弧:它是一个半圆形。现在看看里面的白色空间:它显然不半圆形。蓝色的东西是半圆形,但它内部的空间不是。
因此,由于d3.arc()
现在没有设置两个不同焦点的选项,因此选项会创建您自己的功能(如您所做)或黑客攻击路径(正如Paul S所做的那样)。
答案 2 :(得分:0)
您绘制第二个弧,其外半径为cout << "Value of node in main.cpp before rotation: " << tree1.root->left->right->left->key << endl;
tree1.findParentRotate(5);
cout << "Value of node in main.cpp after rotation: " << tree1.root->left->right->left->key << endl;
,中心偏移R - 2 * strokewidth
。
但较小的弧应该与较大的弧相同相同的中心和外半径strokewidth