【问题标题】:Hit testing pseudo 3d space命中测试伪 3d 空间
【发布时间】:2010-10-12 17:56:23
【问题描述】:

所以我正在为 html5 中的 canvas 元素编写一个小型的伪 3d 引擎。在下面的代码中,我绘制了一堆具有不同位置和旋转的正方形(围绕 z 轴旋转,所以没有变形)

现在我想知道用户点击了哪个方块。在对象数组中,项目由 z 位置支持,从距离相机最远的正方形开始(以便它们正确绘制)。所以给定一个相对于画布左上角的 3d 点,我如何判断点击了哪个方块?

//Draw objects
for (var i = 0; i < objects.length; i++) {
    var object = objects[i];
    var cz = object.position.z - camera.position.z;

    if (cz > 0) {
        cz = 1 / ((cz - 1) * 0.75 + 1);

        context.save();

        context.translate(halfWidth, halfHeight); //viewport transform
        context.scale(1, -1); //invert y axis
        context.scale(cz, cz); //perspective
        context.translate(-camera.position.x, -camera.position.y); //camera transform
        context.translate(object.position.x, object.position.y); //world transform
        context.rotate(object.rotation);

        context.fillStyle = object.color;
        context.fillRect(-40, -40, 80, 80);

        context.restore();
    }
}

附:如果我在做任何奇怪或倒退的事情,并且您知道改进的方法,我很想听听建议

【问题讨论】:

    标签: html 3d canvas


    【解决方案1】:

    我建议您将具有相同变换的对象绘制到相同大小的隐藏画布上,但为每个方块赋予唯一的颜色(可能源自索引i)。

    你会这样做:

    var col = index.toString(16);                 // convert to hex
    while (col.length < 6) col = "0"+col;     // pad leading 0s
    ctx.fillStyle = "#"+col;
    ctx.fillRect(-40,-40,80,80);
    

    然后,当您在可见画布上获得鼠标点击事件时,查看隐藏画布中的该位置以获取所选对象的颜色(索引):

    var colData = ctx.getImageData(clickX, clickY, 1, 1).data;
    var index = (colData[2]<<16) | (colData[1]<<8) | colData[0];
    

    这将适用于多达 1600 万个对象,并且相当简单。

    【讨论】:

    • 我希望得到更多基于数学的东西,但这是一个非常有创意的解决方案
    • 这是对复杂场景进行命中测试的一种相当常见的方法。
    • 另一种选择是您以编程方式生成画布对形状所做的变换,在命中点上执行该变换以创建穿过场景的光线,然后计算出任何形状是否相交射线(如果有的话是最接近的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2021-07-12
    • 2020-06-14
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    相关资源
    最近更新 更多