D3.js - 检测交叉区域 [英] D3.js - detect intersection area
问题描述
NB
此问题不重复..其他帖子正在寻找交叉点和不是交叉区域
我正在尝试检测3个圆的交叉区域,以便以不同于非交叉区域的方式处理它。 / p>
我的圈子看起来像:
此处的交叉区域不可见。到目前为止我能做的就是通过降低不透明度来显示它来得到这样的东西:
我正在寻找一种智能方法来检测这三个圈子的交叉区域。
EDIT
如果可以提供帮助,这是我的 d3.js
代码:
//代码圈
svg.append(circle)
.attr(class,services_nodes)
.attr(cx,7 * width / 16)
.attr(cy,height / 2)
.attr(r,height / 4)
。 attr('fill',blue)
//标签代码
svg.append(text)
.attr(class,label_services)
.attr(x,7 * width / 16 - 21 * width / 265)
.attr(y,35 * height / 64)
.text(Code) ;
//咨询
svg.append(circle)
.attr(class,services_nodes)
.attr(cx,9 * width / 16)
.attr(cy,height / 2)
.attr('fill',red)
.attr('r',height / 4)
//标签咨询
svg.append(text)
.attr(class,label_services)
.attr(x, 9 *宽度/ 16)
.attr(y,35 * height / 64)
.text(咨询);
//支持
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)
//标签支持
svg.append (text)
.attr(class,label_services)
.attr(x,7 * width / 16 + 3 * height / 64)
.attr( y,身高/ 2 - Math.sqrt(3)*身高/ 8 - 3 *身高/ 32)
.text(支持);
提前致谢!
正如我在评论中所说,交叉区域只是从每个圆上的交叉点绘制的两个弧。借用此处的交叉点代码。
var interPoints = intersection(x1,y1,r,x2,y2,r);
svg.append(g)
.append(path)
.attr(d,function(){
returnM + 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.3data-semver =3.5.3src =// cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js\"> < /脚本>< /头><身体GT; <脚本> 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(){returnM+ 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');函数交集(x0,y0,r0,x1,y1,r1){var a,dx,dy,d,h,rx,ry; var x2,y2; / * dx和dy是*圆心之间的垂直和水平距离。 * / dx = x1 - x0; dy = y1 - y0; / *确定中心之间的直线距离。 * / d = Math.sqrt((dy * dy)+(dx * dx)); / *检查可解决性。 * / if(d>(r0 + r1)){/ *无解。圆圈不相交。 * / return false; } if(d< Math.abs(r0 - r1)){/ *无解。一个圆圈包含在另一个* / return false中; } / *'point 2'是穿过圆*交叉点的直线与圆*中心之间的直线相交的点。 * / / *确定从0点到2点的距离。* / a =((r0 * r0) - (r1 * r1)+(d * d))/(2.0 * d); / *确定点2的坐标。* / x2 = x0 +(dx * a / d); y2 = y0 +(dy * a / d); / *确定从点2到任一交叉点的距离。 * / h = Math.sqrt((r0 * r0) - (a * a)); / *现在从*点2确定交叉点的偏移量。* / rx = -dy *(h / d); ry = dx *(h / d); / *确定绝对交叉点。 * / 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.3data-semver =3.5.3src =// cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js\"> < /脚本>< /头><身体GT; <脚本> 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(){returnM+ 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('填充','红色');函数交集(x0,y0,r0,x1,y1,r1){var a,dx,dy,d,h,rx,ry; var x2,y2; / * dx和dy是*圆心之间的垂直和水平距离。 * / dx = x1 - x0; dy = y1 - y0; / *确定中心之间的直线距离。 * / d = Math.sqrt((dy * dy)+(dx * dx)); / *检查可解决性。 * / if(d>(r0 + r1)){/ *无解。圆圈不相交。 * / return false; } if(d< Math.abs(r0 - r1)){/ *无解。一个圆圈包含在另一个* / return false中; } / *'point 2'是穿过圆*交叉点的直线与圆*中心之间的直线相交的点。 * / / *确定从0点到2点的距离。* / a =((r0 * r0) - (r1 * r1)+(d * d))/(2.0 * d); / *确定点2的坐标。* / x2 = x0 +(dx * a / d); y2 = y0 +(dy * a / d); / *确定从点2到任一交叉点的距离。 * / h = Math.sqrt((r0 * r0) - (a * a)); / *现在从*点2确定交叉点的偏移量。* / rx = -dy *(h / d); ry = dx *(h / d); / *确定绝对交叉点。 * / 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>
NB
This question is not a duplicate.. Other posts are looking for the intersection points and not intersection area
I am trying to detect the intersection area of 3 circles in order to process it differently than the non-intersection zone.
My circles look like:
The intersection area here is not visible. What I could do so far is to show it by decreasing the opacity to get something like this:
I am looking for a smart way to detect the intersection zone of this three circles.
EDIT
In case that can help, here is my d3.js
code:
// 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");
Thanks in advance!
As I stated in my comments, the area of intersection is simply the two arcs drawn from the intersection points on each circle. Borrowing the intersection code from 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');
Full working code for 2 circles is:
<!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>
Following this, the intersection of 3 circles becomes:
<!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>
这篇关于D3.js - 检测交叉区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!