命中测试伪 3d 空间
所以我正在为 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();
}
}
PS如果我做了任何奇怪或倒退的事情,而你知道改进的方法,我很乐意听到建议
So I am writing a little mini pseudo 3d engine for the canvas element in html5. In the code below I am drawing a bunch of squares with varying positions and rotations (rotation around the z axis, so no deformation)
Now I want to be able to tell which square the user clicks on. In the objects array the items are supported by the z position starting with the squares the furthest away from the camera (so that they draw properly). So given a 3d point relative to the top left of the corner of the canvas how can I tell which square was clicked?
//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();
}
}
P.S. If I am doing anything weird or backwards and you know of a way to improve, I would love to hear suggestions
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议您将具有相同转换的对象绘制到相同大小的隐藏画布上,但为每个方块赋予唯一的颜色(可能源自索引
i
)。您可以这样做:
然后,当您在可见画布上收到鼠标单击事件时,查看隐藏画布中的该位置以获取所选对象的颜色(索引):
这将适用于最多 16M 对象,并且相当不错简单的。
I would suggest that you draw the objects with the same transformations to a hidden canvas of the same size, but give each square a unique color (maybe derived from the index
i
).You would do that like this:
Then when you get a mouseclick event on the visible canvas, look at that location in your hidden one to get the color (index) of the selected object:
This will work for up to 16M objects and is fairly simple.