【问题标题】:SVG spline (with Bézier curve) to three.js lathe objectSVG 样条(带贝塞尔曲线)到three.js 车床对象
【发布时间】:2015-06-26 00:02:33
【问题描述】:
  • 我正在 LAX 机场为我编写的游戏创建 theme building 的模型

我正在寻找一种方法来获取 svg 样条曲线(使用贝塞尔曲线)并将其转换为 three.js 中的车床对象?

  • 在 3D 建模器中建模,因为我使用连续 LODing 并希望从服务器发送最少量的数据,所以这不起作用

【问题讨论】:

    标签: javascript svg three.js spline


    【解决方案1】:

    就从服务器到客户端的数据传输而言,“最快”的方法是:

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

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

    至于数据量 - 这取决于曲线到多边形转换的保真度有多高(在将曲线转换为多边形时要使用多少样本/细分)但是因为这可以完成在客户端中(见下面的代码 sn-p)那么你就不用太担心了。


    • 要从一系列点创建Lathe 几何体,请参阅this answer

    • 要将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;
      }
      

    【讨论】:

    • 我忘了说我也在使用贝塞尔曲线
    • 是的,这正是我所说的——上面的函数将具有贝塞尔曲线的 SVG 路径元素转换为它们的 'd' 属性。它将返回给您一系列点。因此,获取您的 SVG 路径(如果您只有贝塞尔点,只需构建一个带有贝塞尔点作为 'd' 属性的 SVG 路径)并将其传递给上面的 func - 它会返回给您一个可以传递到的点数组Three.js 的几何构造函数
    猜你喜欢
    • 1970-01-01
    • 2017-11-18
    • 2021-09-10
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    相关资源
    最近更新 更多