【问题标题】:Slice path into two separate paths using paper.js使用 paper.js 将路径分割成两个单独的路径
【发布时间】:2021-01-25 07:10:22
【问题描述】:

我需要使用一条线将一条大路径“分割”成两条较小的路径。例如,您可能有以下配置:

手术后,我应该有两条截然不同的封闭路径。我可能应该找到两个交叉点并使用Path.split 函数来分割矩形路径,但我并不完全理解 paper.js API,我不确定使用 paper.js API 的最佳方法。

例如,我通过执行以下命令分割原始矩形:

 var starting_shape = new paper.Path.Rectangle([paper.view.center.x - 200, paper.view.center.y - 200], 400);
 starting_shape.strokeColor = "#aaa";
 starting_shape.strokeWidth = 2;
 starting_shape.fullySelected = true;

 var p1 = starting_shape.split(starting_shape.getNearestLocation([paper.view.center.x - 40, paper.view.center.y - 250]));
 var p2 = starting_shape.split(starting_shape.getNearestLocation([paper.view.center.x + 50, paper.view.center.y + 250]));

我得到以下信息:

我尝试执行以下操作:

p1.closed = true;
p2.closed = true;

p1.position.x += 10;

我得到了必要的结果:

但是有没有办法让它更聪明?

【问题讨论】:

  • 快速浏览一下 API,您可以使用 path1.getIntersections(path2) 抓取交叉点,然后使用它们创建 2 个新矩形。
  • 是的,我知道如何获得交叉点,我不确定是否使用split,因为它使用位置。我可以编一些晦涩难懂的代码,但我确信它甚至不会接近优化。

标签: javascript paperjs


【解决方案1】:

是的,您可以使用path.divide(path2) 执行除法布尔运算。如果你从 github 克隆项目,Examples > Scripts > BooleanOperations.html中的所有布尔函数都有一个测试

我认为这目前无法像您希望的那样仅使用一行。封闭路径似乎更稳定。

【讨论】:

    【解决方案2】:

    这里的splitUsingPath函数可以使用路径将复杂的形状一分为二,甚至可以使用曲线分割。

    const rectangle = new Shape.Rectangle(new Point(200, 200), new Size(300, 300)).toPath();
    const path = new Path([
        new Point(300, 150),
        new Segment(new Point(325, 350), new Point(-90, -90), new Point(90, 90)),
        new Point(400, 550)
    ])
    
    rectangle.strokeColor = 'black'
    path.strokeColor = 'black'
    
    const splitUsingPath = (target, path) => {
        const paths = [path];
        const targets = [target];
        
        const originalTarget = target.clone({ insert: false })
        const intersections = target.getIntersections(path)
    
        intersections.forEach(location => {
          const newTarget = target.splitAt(location)
          const isNew = newTarget !== target
          
          if (isNew) targets.push(newTarget)
        
          paths.forEach(path => {
              const offset = path.getOffsetOf(location.point)
              const pathLocation = path.getLocationAt(offset)
    
              if (pathLocation) {
                    paths.push(path.splitAt(pathLocation))
              }
          })
        })
    
        const innerPath = paths.find(p => 
            originalTarget.contains(p.bounds.center))
    
        paths
            .filter(path => path !== innerPath)
            .forEach(item => item.remove())
    
        targets.forEach((target, i) => {
            const isFirst = i === 0
            const innerPathCopy = isFirst ? innerPath : innerPath.clone()
            
            target.join(innerPathCopy, innerPathCopy.length)
            target.closed = true
        })
    
        return targets
    }
    
    const splitPaths = splitUsingPath(rectangle, path)
    
    splitPaths.forEach((path, i) => {
        path.position.x += i * -10
    })
    

    【讨论】:

      猜你喜欢
      • 2019-10-01
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多