沿现有路径均匀分布给定数量的线段

Evenly distribute a given number of segments along an existing path

在没有看到 codepen 的情况下,很难解释我的情况,但就这样吧。我正在通过使用 opentype.js 获取 pathData 创建一些路径。然后我将随机形状放置在路径段点的位置。由于字体路径的性质,某些路径的段数比其他路径多得多,例如“1”的段数比“0”少。我想平均出每条路径上的段数,这样当我添加形状时,它们看起来是一致的段数。提前致谢。

是否可以沿现有路径均匀分布给定数量的线段?

Here is a link to the Codepen

paper.install(window);
const minMax = (min, max) => {
  return Math.floor(Math.random() * max + min);
};
window.onload = () => {
  paper.setup("canvas");
  let pathData;
  const font = opentype.load(
    "https://assets.codepen.io/1070/pphatton-ultralight-webfont.woff",
    (err, font) => {
      if (err) {
        console.log(err);
      } else {
        class Doughnut {
          constructor(x, y) {
            this.x = x;
            this.y = y;
            this.shape = new paper.Path.RegularPolygon({
              position: [this.x, this.y],
              sides: minMax(3, 8),
              radius: minMax(6, 12),
              fillColor: "black"
            });
          }
          // makeShape(){
          //   this.shape
          // }
        }
        pathData = font.getPath("100", 0, 600, 600).toSVG();
        // const rect = new paper.Path.Rectangle({
        //   point: [80, 25],
        //   size: [300, 200],
        //   fillColor: "black"
        // });
        const number = new paper.Path(pathData);
        number.selected = true;
        // number.flatten(10);
        const amount = 50;
        const length = number.length
        const points = [];

        const segments = number.segments;
        number.fitBounds(paper.view.bounds);
        for(let i = 0; i < amount; i++){
          const offset = i / amount * length
          const point = number.getPointAt(offset)
                    new Doughnut(point.x, point.y);

        }
        segments.forEach((seg) => {
          points.push(number.getPointAt(seg));
        });


        points.forEach((point) => {
          console.log(point);
          new Doughnut(point.x, point.y);
        });
        number.reduce();
      }
    }
  );

  const shapes = [];
  class Doughnut {
    constructor(x, y) {
      this.x = x;
      this.y = y;
      this.shape = new paper.Path.RegularPolygon({
        position: [this.x, this.y],
        sides: minMax(3, 8),
        radius: minMax(6, 12),
        fillColor: "black"
      });
    }
    // makeShape(){
    //   this.shape
    // }
  }

  // for (let i = 0; i < 10; i++) {
  //   shapes.push(new Doughnut(minMax(100, 500), minMax(100, 500)));
  // }
  // console.log(shapes)
  // shapes.makeShape()
};

path.divideAt()方法可以帮到你很大的忙。
在您的情况下棘手的是,为了保留路径外观,您不能移动现有的线段。所以你必须找到一种方法来只在需要的地方添加段。
否则,这里有一个简单的 sketch 演示可能的解决方案。它应该可以帮助您找到更适合您的用例的解决方案。

const circle = new Path.Circle({
    center: [0, 0],
    radius: 75,
    selected: true
});

const rectangle = new Path.Rectangle({
    from: [0, 0],
    to: [200, 100],
    selected: true
});

rectangle.position = circle.position + [circle.bounds.width + rectangle.bounds.width, 0];

const cloneAndAddSegments = (item) => {
    const clone = item.clone().translate(0, 200);
    const length = clone.length;
    const step = 20;
    const iterations = Math.floor(length / step);
    for (let i = 1; i <= iterations; i++) {
        const offset = i * step;
        clone.divideAt(offset);
    }
    return clone;
};

const circleClone = cloneAndAddSegments(circle);
const rectangleClone = cloneAndAddSegments(rectangle);

const showSegments = (item) => {
    item.segments.forEach(({ point }) => new Path.Circle({
        center: point,
        radius: 5,
        fillColor: 'orange'
    }))
}

showSegments(circle);
showSegments(rectangle);
showSegments(circleClone);
showSegments(rectangleClone);

project.activeLayer.fitBounds(view.bounds.scale(0.8));