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

标签 svg d3.js geometry visualization spline

我有一个 d3 网络,其中点由线连接。我想用弯曲的 SVG 路径替换线条。我忘记了计算控制点坐标的数学方法。有谁知道如何做到这一点?

例如,请看下图:

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

如何使用 SVG 在 d3 中执行此操作?很久以前我在 Raphael/SVG 中做过这个,但数学让我无法理解。而且我不确定它是如何在 D3 中完成的。

最佳答案

只是为了让其他人清楚,我们正在谈论的是二次贝塞尔曲线。这为您提供了具有一个控制点的两点之间的平滑曲线。

基本方法是:

  • 找到你的 A-B 中点,称之为 J.
  • 做一些trig找到线段M末端的点,称之为K
  • 使用 SVG Q 或 T 路径命令绘制二次贝塞尔曲线,从 A 开始,到 B,控制点 K。(注意这看起来与您的图表不完全一样,但可以通过更改M) 的长度。

  • enter image description here

    这是一个返回所需路径的 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
    }
    

    您可以在 this jsfiddle 上看到这一点。

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

    关于svg - d3.js:如何通过绘制二次贝塞尔曲线将网络可视化中的边从线条转换为曲线路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25595387/

    相关文章:

    svg - 使用 'month-year' 日期值创建带时间线的 D3.js 散点图

    javascript - 来自 contourDensity() 的过渡轮廓线

    math - 找到圆上的切点?

    opencv - 根据实际尺寸计算物体的图像尺寸

    algorithm - 计算不同引用系中的坐标

    css - SVG 数据图像不能用作伪元素中的背景图像

    html - 如何在不切断的情况下转换 SVG 中的对象?

    css - 将彩色不透明度应用于 SVG 图像

    d3.js - cubism.js 的色带

    javascript - 无法在 d3.js 中添加轴