我是c++ 3D的新手,所以我可能遗漏了一些显而易见的东西,但是如何从3D转换到2D,以及(对于给定的z位置)从2D转换到3D?
发布于 2010-11-30 18:31:40
您可以通过projection将三维映射到二维。通过在矢量的Z元素中插入适当的值,可以将2D映射到3D。
发布于 2010-11-30 18:48:22
它是将光线从屏幕投射到平行于x-y且位于所需z位置的平面上。然后,您需要找出光线在平面上的碰撞位置。
这里有一个示例,假设screen_x和screen_y的范围是0,1,其中0分别是最左侧或最顶部的坐标,1分别是最右侧或最底部的坐标:
Vector3 point_of_contact(-1.0f, -1.0f, -1.0f);
Matrix4 view_matrix = camera->getViewMatrix();
Matrix4 proj_matrix = camera->getProjectionMatrix();
Matrix4 inv_view_proj_matrix = (proj_matrix * view_matrix).inverse();
float nx = (2.0f * screen_x) - 1.0f;
float ny = 1.0f - (2.0f * screen_y);
Vector3 near_point(nx, ny, -1.0f);
Vector3 mid_point(nx, ny, 0.0f);
// Get ray origin and ray target on near plane in world space
Vector3 ray_origin, ray_target;
ray_origin = inv_view_proj_matrix * near_point;
ray_target = inv_view_proj_matrix * mid_point;
Vector3 ray_direction = ray_target - ray_origin;
ray_direction.normalise();
// Check for collision with the plane
Vector3 plane_normal(0.0f, 0.0f, 1.0f);
float denominator = plane_normal.dotProduct(ray_direction);
if (fabs(denom) >= std::numeric_limits<float>::epsilon())
{
float num = plane_normal.dotProduct(ray.getOrigin()) + Vector3(0, 0, z_pos);
float distance = -(num/denom);
if (distance > 0)
{
point_of_contact = ray_origin + (ray_direction * distance);
}
}
return point_of_contact免责声明:此解决方案取自零碎的Ogre3D图形库。
发布于 2010-12-02 03:53:59
最简单的方法是除以z。因此...
screenX = projectionX / projectionZ;
screenY = projectionY / projectionZ;根据距离进行透视投影。问题是,使用homgeneous coordinates通常更好,因为这简化了矩阵转换(一切都变成了乘法)。同样,这也是D3D和OpenGL所使用的。了解如何使用非齐次坐标(即一个(x,y,z)坐标三元组)将非常有助于着色器优化等事情。
https://stackoverflow.com/questions/4312652
复制相似问题