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

修改VertexBufferReader数组旋转2D模型实例时出现异常

2D模型元素旋转异常问题排查与修复

我已参考Autodesk的2D绘图元素平移方案实现了平移功能,但用类似方法处理2D模型元素旋转时出现异常。

原始元素:
原始元素

旋转后元素:
旋转后异常元素

原始实现代码

VBR.prototype.rotateLine = function (vindex, layer, vpId, angle, center) {
    var baseOffset = this.stride * vindex;
    var i = 0;
    while (i < 4) {
        const point = new THREE.Vector3(
            this.vbf[baseOffset + i * this.stride],
            this.vbf[baseOffset + i * this.stride + 1],
            0,
        );
        const rotated = RotatePoint(point, center, angle);

        this.vbf[baseOffset + i * this.stride] = rotated.x;
        this.vbf[baseOffset + i * this.stride + 1] = rotated.y;
        this.vbf[baseOffset + i * this.stride + 2] += 0.5;
        i++;
    }
};
function RotatePoint(point, around, angle)
{
    var start = new THREE.Vector3(point.x - around.x, point.y - around.y);
    point.x = Math.cos(angle) * start.x - Math.sin(angle) * start.y + around.x;
    point.y = Math.sin(angle) * start.x + Math.cos(angle) * start.y + around.y;
    return point;
}

问题分析与修复

核心问题1:不必要的Z轴偏移

代码中this.vbf[baseOffset + i * this.stride + 2] += 0.5;是错误操作——2D元素旋转不需要修改Z轴坐标,四次循环后Z轴总共累加了2,导致元素在Z方向错位,这就是视觉异常的直接原因。

核心问题2:函数副作用风险

RotatePoint函数直接修改了传入的point对象,虽然当前场景中每次都会新建Vector3暂时没引发问题,但这种写法容易在其他场景中导致意外的对象修改,属于不良实践。

修复后的代码

修正rotateLine方法

VBR.prototype.rotateLine = function (vindex, layer, vpId, angle, center) {
    var baseOffset = this.stride * vindex;
    var i = 0;
    while (i < 4) {
        const point = new THREE.Vector3(
            this.vbf[baseOffset + i * this.stride],
            this.vbf[baseOffset + i * this.stride + 1],
            0,
        );
        const rotated = RotatePoint(point, center, angle);

        this.vbf[baseOffset + i * this.stride] = rotated.x;
        this.vbf[baseOffset + i * this.stride + 1] = rotated.y;
        // 移除不必要的Z轴累加操作
        i++;
    }
};

优化RotatePoint函数

function RotatePoint(point, around, angle) {
    // 计算相对旋转中心的偏移量
    const dx = point.x - around.x;
    const dy = point.y - around.y;
    // 应用旋转公式计算新坐标
    const rotatedX = Math.cos(angle) * dx - Math.sin(angle) * dy + around.x;
    const rotatedY = Math.sin(angle) * dx + Math.cos(angle) * dy + around.y;
    // 返回新的Vector3对象,避免修改原输入
    return new THREE.Vector3(rotatedX, rotatedY, 0);
}

内容的提问来源于stack exchange,提问作者Eslam Khaled Mohamed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:20:05