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

基于Paper.js实现简单图形上A、B两点间路径高亮的最优方案问询

在Paper.js中高效高亮图形上两点间路径的方法

针对不同类型的基础图形,我们可以利用它们的几何特性和Paper.js内置API直接计算目标路径,替代暴力追踪的低效方案,具体实现如下:

1. 直线(Line)

直线上的A、B两点本身构成线段,直接提取即可:

// 假设原直线为line,A、B为两个Point对象
const highlightPath = new Path.Line({
    from: A,
    to: B,
    strokeColor: 'red',
    strokeWidth: 3
});

2. 圆形(Circle)

圆形上两点间有两条弧,按需选择短弧或长弧:

// 假设原圆形为circle,A、B为圆上的Point
const center = circle.position;
const radius = circle.radius;
// 计算两点相对圆心的角度
const angleA = (A - center).getAngle();
const angleB = (B - center).getAngle();
// 创建弧路径(默认短弧,需长弧可添加{clockwise: false}参数)
const highlightPath = new Path.Arc({
    from: A,
    through: center.add(new Point({ length: radius, angle: (angleA + angleB)/2 })),
    to: B,
    strokeColor: 'red',
    strokeWidth: 3
});

3. 多边形(三角形、矩形等)

先定位A、B所在的边,再根据位置生成路径:

// 假设原多边形为polygon,A、B为多边形上的Point
const segments = polygon.segments;
let startIndex = -1, endIndex = -1;
let startOffset = 0, endOffset = 0;

// 遍历线段,找到A、B所在的边和偏移量
for (let i = 0; i < segments.length; i++) {
    const seg1 = segments[i];
    const seg2 = segments[(i+1)%segments.length];
    const line = new Path.Line(seg1.point, seg2.point);
    if (line.getDistance(A) < 0.1) {
        startIndex = i;
        startOffset = line.getLocationOf(A).offset;
    }
    if (line.getDistance(B) < 0.1) {
        endIndex = i;
        endOffset = line.getLocationOf(B).offset;
    }
}

const highlightPath = new Path();
// 两点在同一条边的情况
if (startIndex === endIndex) {
    const seg1 = segments[startIndex];
    const seg2 = segments[(startIndex+1)%segments.length];
    const line = new Path.Line(seg1.point, seg2.point);
    highlightPath.add(line.getPointAt(startOffset), line.getPointAt(endOffset));
} else {
    // 跨边情况,按顺序拼接路径片段
    let i = startIndex;
    while (true) {
        const seg = segments[i];
        const nextSeg = segments[(i+1)%segments.length];
        if (i === startIndex) {
            highlightPath.add(A, nextSeg.point);
        } else if (i === endIndex) {
            highlightPath.add(seg.point, B);
            break;
        } else {
            highlightPath.add(seg.point, nextSeg.point);
        }
        i = (i+1)%segments.length;
    }
}
highlightPath.strokeColor = 'red';
highlightPath.strokeWidth = 3;

4. 椭圆(Ellipse)

通过椭圆参数方程转换坐标,生成精准弧路径:

// 假设原椭圆为ellipse,A、B为椭圆上的Point
const center = ellipse.position;
const size = ellipse.size;
const rotation = ellipse.rotation;

// 转换到椭圆局部坐标系
const localA = A.subtract(center).rotate(-rotation);
const localB = B.subtract(center).rotate(-rotation);

// 计算椭圆参数角度
const angleA = Math.atan2(localA.y / size.height * 2, localA.x / size.width * 2);
const angleB = Math.atan2(localB.y / size.height * 2, localB.x / size.width * 2);

// 生成弧路径
const highlightPath = new Path();
highlightPath.add(A);
const step = 0.1; // 弧度步长,控制路径精度
let currentAngle = angleA;
const direction = Math.sign(angleB - angleA);
while (Math.abs(currentAngle - angleB) > step) {
    currentAngle += direction * step;
    // 转换回全局坐标系的点
    const x = center.x + (size.width/2)*Math.cos(currentAngle)*Math.cos(rotation) - (size.height/2)*Math.sin(currentAngle)*Math.sin(rotation);
    const y = center.y + (size.width/2)*Math.cos(currentAngle)*Math.sin(rotation) + (size.height/2)*Math.sin(currentAngle)*Math.cos(rotation);
    highlightPath.add(new Point(x, y));
}
highlightPath.add(B);
highlightPath.strokeColor = 'red';
highlightPath.strokeWidth = 3;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 12:51:17