SVG 样条(带贝塞尔曲线)到 three.js 车床对象

SVG spline (with Bézier curve) to three.js lathe object

我正在寻找一种获取 svg 样条曲线(使用贝塞尔曲线)并将其转换为 three.js?

中的车床对象的方法

在从服务器到客户端的数据传输方面,'fastest' 方法是:

  1. 将您的 spline/curve 从服务器
  2. 发送到客户端
  3. 将曲线转换为 客户端中的多边形
  4. 从多边形在客户端中创建车床

您首先需要将您的 SVG 样条线转换为多边形,然后您将其作为 Lathe 几何体输入 Three.js。

至于数据量 - 这取决于曲线到多边形转换的保真度有多高(将曲线转换为多边形时要使用多少 samples/subdivisions)但是因为这可以在客户端完成(请参阅下面的代码片段)然后你就不会太担心了。


  • 要从一系列点中创建 Lathe 几何,请参阅 this 回答

  • 要将 SVG curve 转换为一系列点,您可以使用此 一段代码:

    //convert path to polygon
    function pathToPolygon(path, samples) {
    
    if (!samples) samples = 0;
    
    var poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
    
    // Put all path segments in a queue
    for (var segs = [], s = path.pathSegList, i = s.numberOfItems - 1; i >= 0; --i) segs[i] = s.getItem(i);
    var segments = segs.concat();
    
    var seg, lastSeg, points = [],
        x, y;
    var addSegmentPoint = function(s) {
        if (s.pathSegType == SVGPathSeg.PATHSEG_CLOSEPATH) {
    
        } else {
            if (s.pathSegType % 2 == 1 && s.pathSegType > 1) {
                // All odd-numbered path types are relative, except PATHSEG_CLOSEPATH (1)
                x += s.x;
                y += s.y;
            } else {
                x = s.x;
                y = s.y;
            }
            var lastPoint = points[points.length - 1];
            if (!lastPoint || x != lastPoint[0] || y != lastPoint[1]) points.push([x, y]);
        }
    };
    for (var d = 0, len = path.getTotalLength(), step = len / samples; d <= len; d += step) {
        var seg = segments[path.getPathSegAtLength(d)];
        var pt = path.getPointAtLength(d);
        if (seg != lastSeg) {
            lastSeg = seg;
            while (segs.length && segs[0] != seg) addSegmentPoint(segs.shift());
        }
        var lastPoint = points[points.length - 1];
        if (!lastPoint || pt.x != lastPoint[0] || pt.y != lastPoint[1]) points.push([pt.x, pt.y]);
    }
    for (var i = 0, len = segs.length; i < len; ++i) addSegmentPoint(segs[i]);
    for (var i = 0, len = points.length; i < len; ++i) points[i] = points[i].join(',');
    poly.setAttribute('points', points.join(' '));
    return points;
    }