Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Svg d3.js:如何通过绘制二次贝塞尔曲线将网络可视化中的边从直线转换为曲线路径?_Svg_D3.js_Geometry_Visualization_Spline - Fatal编程技术网

Svg d3.js:如何通过绘制二次贝塞尔曲线将网络可视化中的边从直线转换为曲线路径?

Svg d3.js:如何通过绘制二次贝塞尔曲线将网络可视化中的边从直线转换为曲线路径?,svg,d3.js,geometry,visualization,spline,Svg,D3.js,Geometry,Visualization,Spline,我有一个d3网络,点通过线连接。我想用弯曲的SVG路径替换这些线。我忘记了计算控制点坐标的数学。有人知道怎么做吗 例如,请看下图: 存在点A和B。我现在用一条线L将它们连接起来。我想用曲线C替换L。为此,我需要找到一条垂直于线L中点的线,长度为M(长度设置为L的百分比),作为样条曲线C的控制点。然后我需要定义一个SVG路径来定义C 在d3中如何使用SVG实现这一点?很久以前,我在Raphael/SVG中就做过这件事,但是数学问题让我不知所措。我不确定D3是怎么做到的。为了让其他人清楚,我们所说

我有一个d3网络,点通过线连接。我想用弯曲的SVG路径替换这些线。我忘记了计算控制点坐标的数学。有人知道怎么做吗

例如,请看下图:

存在点A和B。我现在用一条线L将它们连接起来。我想用曲线C替换L。为此,我需要找到一条垂直于线L中点的线,长度为M(长度设置为L的百分比),作为样条曲线C的控制点。然后我需要定义一个SVG路径来定义C


在d3中如何使用SVG实现这一点?很久以前,我在Raphael/SVG中就做过这件事,但是数学问题让我不知所措。我不确定D3是怎么做到的。

为了让其他人清楚,我们所说的是二次贝塞尔曲线。这将在两个点之间使用一个控制点生成平滑曲线

基本方法是:

  • 找到你的A-B中点,称之为J
  • 做一些trig来找到线段M末端的点,称之为K
  • 使用SVG Q或T path命令绘制二次贝塞尔曲线,从A开始,到B,控制点为K。(请注意,这看起来与您的图表并不完全相同,但可以通过更改M的长度来调整)
  • 下面是返回所需路径的javascript函数:

    function draw_curve(Ax, Ay, Bx, By, M) {
    
        // Find midpoint J
        var Jx = Ax + (Bx - Ax) / 2
        var Jy = Ay + (By - Ay) / 2
    
        // We need a and b to find theta, and we need to know the sign of each to make sure that the orientation is correct.
        var a = Bx - Ax
        var asign = (a < 0 ? -1 : 1)
        var b = By - Ay
        var bsign = (b < 0 ? -1 : 1)
        var theta = Math.atan(b / a)
    
        // Find the point that's perpendicular to J on side
        var costheta = asign * Math.cos(theta)
        var sintheta = asign * Math.sin(theta)
    
        // Find c and d
        var c = M * sintheta
        var d = M * costheta
    
        // Use c and d to find Kx and Ky
        var Kx = Jx - c
        var Ky = Jy + d
    
        return "M" + Ax + "," + Ay +
               "Q" + Kx + "," + Ky +
               " " + Bx + "," + By
    }
    
    函数绘制曲线(Ax、Ay、Bx、By、M){ //找到中点J var Jx=Ax+(Bx-Ax)/2 var Jy=Ay+(By-Ay)/2 //我们需要a和b来找到θ,我们需要知道每个θ的符号来确保方向是正确的。 变量a=Bx-Ax 变量asign=(a<0?-1:1) var b=按-Ay计算 变量bsign=(b<0?-1:1) 变量θ=数学常数(b/a) //找到边上垂直于J的点 var costheta=asign*Math.cos(θ) var sintheta=asign*Math.sin(θ) //找到c和d var c=M*sintheta var d=M*costheta //使用c和d查找Kx和Ky var Kx=Jx-c var Ky=Jy+d 返回“M”+Ax+,“+Ay”+ “Q”+Kx+,“+Ky”+ “+Bx+”,“+Bx+” } 你可以在网站上看到这一点


    编辑:如果二次曲线不合适,你可以很容易地调整函数来做三次贝塞尔曲线或圆弧段。

    第二部分对你没有帮助,但如果有用的话,我可以告诉你如何获得中点及其偏移量。如果你不喜欢d3/svg,我会查看sigma.js,这是一个图形可视化库。它内置了对弯曲边缘的支持。。。(defaultEdgeType:'curve')“我忘记了计算控制点坐标的数学。”真的吗?不如提醒自己它是如何工作的,而不是要求我们为您完成工作?检查svg中路径元素的规范。在路径中绘制曲线段有两种不同的可能性。在你的情况下,我认为“椭圆弧曲线命令”是合适的。您可以修改此示例,并使用点之间距离的百分比来设置参数的参数
    rx
    ry
    。这是一个愚蠢的简化例子。