Я видел много Screen-Coordinate для мировых координационных постов, но не видел обратного. Есть ли простой способ получить координаты экрана из трехмерной точки, с любого угла, с которого я его просматриваю? Я использую С++ и opengl
Как получить координаты экрана из 3D-точки? OPENGL
Ответ 1
Ответ erjot не завершен.
Есть два дополнительных вопроса, которые необходимо учитывать.
- с
homogeneous = P . M . world
, векторhomogeneous
представляет собой 4-й вектор в однородном пространстве. В частности, чтобы вернуть его к кубу [-1:1] ^ 3, вам нужно разделить его первые 3 координаты наhomogeneous.w
.cube.x = homogeneous.x / homogeneous.w
(что некоторые называют разложением проекции). - Затем вам необходимо преобразовать куб [-1:1] ^ 3 в координаты окна, применив к нему преобразование Viewport.
window.x = viewport.x + viewport.width * (cube.x+1)/2
Если вы заботитесь о последнем Z, преобразование не проходит через окно просмотра, а DepthRange вместо этого.
Ответ 2
Экранные координаты для вершины являются результатом умножения такой вершины на ее проекцию и матрицу вида:
screen_coordinates = projection_matrix * modelview_matrix * world_coordinates
Вы можете сделать это вручную (особенно если вы используете некоторую библиотеку математики для выполнения операций над матрицами) или используйте gluProject, например:
std::array<GLfloat, 16> projection;
std::array<GLfloat, 16> modelview;
std::array<GLfloat, 3> screen_coords;
glGetFloatv(GL_PROJECTION_MATRIX, projection.data());
glGetFloatv(GL_MODELVIEW_MATRIX, modelview.data());
gluProject(world_coords[0], world_coords[1], world_coords[2],
modelview.data(), projection.data(),
screen_coords.data(), screen_coords.data() + 1, screen_coords.data() + 2);
Ответ 3
Еще одна вещь. Помните, gluProject дает координаты, где начало координат начинается в левом нижнем углу. Координаты экрана начинаются в верхнем левом углу. Для получения правильных значений координаты экрана значение y должно быть вычтено с высоты устройства OpenGL.
Например, в Qt GLWidget для рисования текста в (0,1,2) мировых координатах он идет:
gluProject (0,1,2, modelMatrix, projMatrix, sc.x, sc.y, sc.z); renderText (sc.x, высота() - sc.y, "(0,1,2)" );