You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用直线切割多边形?Paper.js+Canvas游戏开发技术问询

解决Paper.js中沿任意直线分割凸多边形的问题

你当前的代码能检测到多边形与分割线的交点,但分割后无法得到正确的闭合多边形,核心问题出在Path对象的复制方式、分割顺序处理以及交点排序上。

原代码的关键问题

  • 用Object.assign(p1)复制Paper.js的Path对象无效:Paper.js的Path是带有内部状态的复杂对象,浅拷贝会丢失关键属性,必须用clone()方法
  • 未对交点排序:直接按交点数组顺序分割,可能导致分割顺序错误,生成无效形状
  • 分割对象引用错误:第二次分割的对象应该是第一次分割后的剩余路径,而非原路径

修正后的完整代码

// 初始化凸多边形
var polygon = new Path.RegularPolygon(new Point(200, 300), 4, 100);
polygon.strokeColor = 'blue';
polygon.fullySelected = true;

var shapesArray = [polygon];
var myPath;

function splitShape(targetShapes, cutLine) {
    var updatedShapes = [];
    
    targetShapes.forEach(function(shape) {
        var intersections = shape.getIntersections(cutLine);
        
        // 凸多边形与直线最多有2个交点,确保有效分割条件
        if (intersections.length === 2) {
            // 获取交点在多边形路径上的位置对象
            var loc1 = shape.getNearestLocation(intersections[0].point);
            var loc2 = shape.getNearestLocation(intersections[1].point);
            
            // 按路径偏移量排序交点,保证分割顺序正确
            if (loc1.offset > loc2.offset) {
                [loc1, loc2] = [loc2, loc1];
            }
            
            // 第一次分割得到第一个子路径
            var part1 = shape.split(loc1);
            // 第二次分割剩余路径得到第二个子路径
            var part2 = shape.split(loc2);
            
            // 确保子路径为闭合多边形
            part1.closed = true;
            part2.closed = true;
            
            // 用clone()复制路径,避免引用冲突
            updatedShapes.push(part1.clone());
            updatedShapes.push(part2.clone());
            
            // 移除原路径,清理画布
            shape.remove();
        } else {
            // 无交点时保留原形状
            updatedShapes.push(shape.clone());
        }
    });
    
    // 更新全局形状数组
    shapesArray = updatedShapes;
    cutLine.remove(); // 直接移除分割线,替代隐藏操作
}

// 鼠标绘制分割线事件
function onMouseDown(event) {
    myPath = new Path();
    myPath.strokeColor = 'black';
    myPath.add(event.point);
}

function onMouseDrag(event) {
    myPath.segments.pop();
    myPath.add(event.point);
}

function onMouseUp(event) {
    splitShape(shapesArray, myPath);
}

关键修改说明

  1. Path对象复制:使用clone()方法完整复制Paper.js Path的所有属性和内部状态,避免浅拷贝导致的异常
  2. 交点排序:通过比较交点在路径上的offset值,确保分割顺序符合多边形的路径走向,生成正确的闭合子多边形
  3. 分割逻辑优化:第一次分割后,原路径自动变为剩余部分,第二次分割直接操作该剩余路径,确保得到两个完整的子形状
  4. 画布清理:分割完成后移除原多边形和分割线,避免画布上残留无效元素

内容的提问来源于stack exchange,提问作者DYM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:50:28