gpt4 book ai didi

javascript - D3.js - 检测交叉区域

转载 作者:可可西里 更新时间:2023-11-01 02:39:26 24 4
gpt4 key购买 nike

注意

这个问题不是重复的。其他帖子正在寻找交点而不是交点区域

我正在尝试检测 3 个圆的交叉区域,以便以不同于非交叉区域的方式处理它。

我的圈子是这样的: enter image description here

这里的交叉区域是不可见的。到目前为止我能做的是通过降低不透明度来展示它,得到这样的东西:

enter image description here

我正在寻找一种智能方法来检测这三个圆圈的交叉区域。

编辑

如果有帮助,这是我的 d3.js 代码:

// Code circle 
svg.append("circle")
.attr("class","services_nodes")
.attr("cx",7*width/16)
.attr("cy",height/2)
.attr("r",height/4)
.attr('fill', "blue")

// Label code
svg.append("text")
.attr("class","label_services")
.attr("x", 7*width/16 - 21*width/265)
.attr("y",35*height/64)
.text("Code");

// Consulting
svg.append("circle")
.attr("class","services_nodes")
.attr("cx",9*width/16)
.attr("cy",height/2)
.attr('fill', "red")
.attr('r', height/4)

// Label Consulting
svg.append("text")
.attr("class","label_services")
.attr("x", 9*width/16)
.attr("y",35*height/64)
.text("Consulting");

// Support
svg.append("circle")
.attr("class","services_nodes")
.attr("cx",7*width/16 + height/8)
.attr("cy",height/2 - Math.sqrt(3)*height/8) // y +/- Math.sqrt(3)*r/2
.attr('fill', "green")
.attr('r',height/4)

// Label Support
svg.append("text")
.attr("class","label_services")
.attr("x", 7*width/16 + 3*height/64)
.attr("y",height/2 - Math.sqrt(3)*height/8 - 3*height/32)
.text("Support");

提前致谢!

最佳答案

正如我在评论中所述,相交区域只是从每个圆上的交点绘制的两条弧。借用here的交集代码.

var interPoints = intersection(x1, y1, r, x2, y2, r);

svg.append("g")
.append("path")
.attr("d", function() {
return "M" + interPoints[0] + "," + interPoints[2] + "A" + r + "," + r +
" 0 0,1 " + interPoints[1] + "," + interPoints[3]+ "A" + r + "," + r +
" 0 0,1 " + interPoints[0] + "," + interPoints[2];
})
.style('fill', 'red');

2 个圆圈的完整工作代码是:

<!DOCTYPE html>
<html>

<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>

<body>
<script>
var x1 = 100,
y1 = 100,
x2 = 150,
y2 = 150,
r = 70;

var svg = d3.select('body')
.append('svg')
.attr('width', 600)
.attr('height', 600);

svg.append('circle')
.attr('cx', x1)
.attr('cy', y1)
.attr('r', r)
.style('fill', 'steelblue');

svg.append('circle')
.attr('cx', x2)
.attr('cy', y2)
.attr('r', r)
.style('fill', 'orange');

var interPoints = intersection(x1, y1, r, x2, y2, r);

svg.append("g")
.append("path")
.attr("d", function() {
return "M" + interPoints[0] + "," + interPoints[2] + "A" + r + "," + r +
" 0 0,1 " + interPoints[1] + "," + interPoints[3]+ "A" + r + "," + r +
" 0 0,1 " + interPoints[0] + "," + interPoints[2];
})
.style('fill', 'red');


function intersection(x0, y0, r0, x1, y1, r1) {
var a, dx, dy, d, h, rx, ry;
var x2, y2;

/* dx and dy are the vertical and horizontal distances between
* the circle centers.
*/
dx = x1 - x0;
dy = y1 - y0;

/* Determine the straight-line distance between the centers. */
d = Math.sqrt((dy * dy) + (dx * dx));

/* Check for solvability. */
if (d > (r0 + r1)) {
/* no solution. circles do not intersect. */
return false;
}
if (d < Math.abs(r0 - r1)) {
/* no solution. one circle is contained in the other */
return false;
}

/* 'point 2' is the point where the line through the circle
* intersection points crosses the line between the circle
* centers.
*/

/* Determine the distance from point 0 to point 2. */
a = ((r0 * r0) - (r1 * r1) + (d * d)) / (2.0 * d);

/* Determine the coordinates of point 2. */
x2 = x0 + (dx * a / d);
y2 = y0 + (dy * a / d);

/* Determine the distance from point 2 to either of the
* intersection points.
*/
h = Math.sqrt((r0 * r0) - (a * a));

/* Now determine the offsets of the intersection points from
* point 2.
*/
rx = -dy * (h / d);
ry = dx * (h / d);

/* Determine the absolute intersection points. */
var xi = x2 + rx;
var xi_prime = x2 - rx;
var yi = y2 + ry;
var yi_prime = y2 - ry;

return [xi, xi_prime, yi, yi_prime];
}
</script>
</body>

</html>

接着,3个圆的交点变成:

<!DOCTYPE html>
<html>

<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>

<body>
<script>
var x1 = 150,
y1 = 100,
x2 = 200,
y2 = 150,
x3 = 100,
y3 = 150,
r = 70;

var svg = d3.select('body')
.append('svg')
.attr('width', 600)
.attr('height', 600);

svg.append('circle')
.attr('cx', x1)
.attr('cy', y1)
.attr('r', r)
.style('fill', 'steelblue');

svg.append('circle')
.attr('cx', x2)
.attr('cy', y2)
.attr('r', r)
.style('fill', 'orange');

svg.append('circle')
.attr('cx', x3)
.attr('cy', y3)
.attr('r', r)
.style('fill', 'green');

var interPoints1 = intersection(x1, y1, r, x2, y2, r);
var interPoints2 = intersection(x2, y2, r, x3, y3, r);
var interPoints3 = intersection(x1, y1, r, x3, y3, r);

svg.append("g")
.append("path")
.attr("d", function() {
return "M" + interPoints3[1] + "," + interPoints3[3] + "A" + r + "," + r +
" 0 0,1 " + interPoints1[0] + "," + interPoints1[2] + "A" + r + "," + r +
" 0 0,1 " + interPoints2[0] + "," + interPoints2[2] + "A" + r + "," + r +
" 0 0,1 " + interPoints3[1] + "," + interPoints3[3];
})
.style('fill', 'red');

function intersection(x0, y0, r0, x1, y1, r1) {
var a, dx, dy, d, h, rx, ry;
var x2, y2;

/* dx and dy are the vertical and horizontal distances between
* the circle centers.
*/
dx = x1 - x0;
dy = y1 - y0;

/* Determine the straight-line distance between the centers. */
d = Math.sqrt((dy * dy) + (dx * dx));

/* Check for solvability. */
if (d > (r0 + r1)) {
/* no solution. circles do not intersect. */
return false;
}
if (d < Math.abs(r0 - r1)) {
/* no solution. one circle is contained in the other */
return false;
}

/* 'point 2' is the point where the line through the circle
* intersection points crosses the line between the circle
* centers.
*/

/* Determine the distance from point 0 to point 2. */
a = ((r0 * r0) - (r1 * r1) + (d * d)) / (2.0 * d);

/* Determine the coordinates of point 2. */
x2 = x0 + (dx * a / d);
y2 = y0 + (dy * a / d);

/* Determine the distance from point 2 to either of the
* intersection points.
*/
h = Math.sqrt((r0 * r0) - (a * a));

/* Now determine the offsets of the intersection points from
* point 2.
*/
rx = -dy * (h / d);
ry = dx * (h / d);

/* Determine the absolute intersection points. */
var xi = x2 + rx;
var xi_prime = x2 - rx;
var yi = y2 + ry;
var yi_prime = y2 - ry;

return [xi, xi_prime, yi, yi_prime];
}
</script>
</body>

</html>

关于javascript - D3.js - 检测交叉区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33330074/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com