Проекция - преобразование 3d в 2d

У меня проблема или хорошо, я не знаю, как преобразовать трехмерную точку с значениями x, y, z в 2d-точку, Мне нужно рисовать проекцию, где у меня есть значения x, y, z для точек, но я не знаю, как преобразовать их в 2d, чтобы я мог перемещать их на мою ось.

enter image description here

Я искал вики и google, однако я не совсем уверен, какие преобразования матриц следует использовать для получения желаемого результата.

Ответ 1

Сначала предположим, что камера, смотрящая на вашу сцену, центрируется в начале координат и смотрит в направлении -z. Тогда:

  • перспективная проекция дается:
    x' = x/z
    y' = y/z

  • орфографическая проекция задается следующим образом:
    x' = x
    y' = y
    (т.е. просто отбросить компонент z)

Теперь, когда вы применили вышеприведенный шаг, вы можете получить точку, которая находится на (x',y') = (-28.4, +134.5). Теперь вам нужно масштабировать и центрировать их на основе разрешения экрана и коэффициента масштабирования камеры и соотношения сторон: например, вы можете увеличить значение на Zoom и добавить screen_center к вашим x и y компонентов (будьте осторожны: большинство систем рендеринга графики имеют направление y, указывающее вниз, поэтому вам может понадобиться поменять знаки для компонента y). Вы все равно можете получить пиксели с отрицательными координатами или чьи координаты больше размера вашего холста. Просто отбросьте их: это означает, что они находятся вне вашего взгляда.

Наконец, вы можете задаться вопросом, что делать, если ваша камера не указывает на -z или не центрирована в начале координат. Для более поздних версий это просто: просто вычтите координаты камеры компоненту всех трехмерных точек перед тем, как делать что-либо еще. Для вращения камеры это также на самом деле довольно просто: вам просто нужно повернуть ваши точки в обратном порядке, когда ваша камера повернута, прежде чем делать что-либо еще. Это означает, что вам нужно умножить все ваши 3D-координаты на транспонирование матрицы вращения камеры. Идея этого шага заключается в том, что перемещение камеры вокруг точно совпадает с перемещением ваших точек в обратном направлении (и случается, что обратная матрица вращения является транспонированием той же самой матрицы).

Ответ 2

Я бы очень рекомендовал использовать существующий графический пакет, чтобы сделать это, пытаясь написать собственные библиотеки. Я не знаю, на каком языке вы работаете, но OpenGL - это графический движок с открытым исходным кодом, который можно использовать для 3D-рендеринга и имеет сопоставимость на разных языках, поэтому это может быть место для начала.

Если вы настаиваете на том, чтобы делать это вручную, есть очень хороший пример кода в ответе на этот вопрос.

Ответ 3

Я нашел способ проектировать 3D в Изометрический 2D.

Я предположил угол для изометрического вида и, конечно, трехмерную точку для проекта, например

Dim IsometricViewAngle As Integer = 30
Dim RowPoint As New Point3D(dx,dy,dz)

где dx, dy и dz - ваши пользовательские значения. то мне пришлось вычислять значение Delta​​strong > для увеличения и уменьшения X и Y, например

Dim XDelta = Math.Cos(IsometricViewAngle * Math.PI / 180)
Dim YDelta = Math.Sin(IsometricViewAngle * Math.PI / 180)
Dim ZDelta = 0.5

ОК, что он, теперь я собираюсь 3D-точки проекта в 2D-точку:

Dim X As Double = (RowPoint.X * XDelta) + (RowPoint.Y * YDelta)
Dim Y As Double = (RowPoint.X * XDelta) + (RowPoint.Z * ZDelta)
Dim ProjectedPoint As New Point(X,Y)

и конечный результат лучше всего работает в RadDiagram. Отношения/

Ответ 4

Это работает для меня: (это в vb). f_nodes - это плоские узлы, a_nodes - это 3D-узлы после преобразования альфа, бета и гамма. (x, y, z) является точкой. Есть более сложные из них.

    ca = Cos(alpha)
    sa = Sin(alpha)
    cb = Cos(beta)
    sb = Sin(beta)
    cg = Cos(gamma)
    sg = Sin(gamma)
    q(1) = cg * (cb * X - sb * (sa * Y + ca * z)) - sg * (ca * Y - sa * z)
    q(2) = sg * (cb * X - sb * (sa * Y + ca * z)) + cg * (ca * Y - sa * z)
    q(3) = sb * X + cb * (sa * Y + ca * z)

    f_nodes(i, 1) = q(1)
    f_nodes(i, 2) = q(2)

    a_nodes(i, 1) = q(1)
    a_nodes(i, 2) = q(2)
    a_nodes(i, 3) = q(3)

Ответ 5

Вам нужно только учитывать угол обзора камеры, если вы намерены повернуть фигуру в 3 измерения. Если у вас есть четкое понимание линейной алгебры и тригонометрии, это стоит дополнительных усилий, так как это делает вашу программу более гибкой, но если вы не слишком строк в математике, я бы рекомендовал следующее решение.

То, что вам нужно, чтобы проектировать 3D-изображение в 2D-плоскость, - это создать и уравнение, которое будет отображаться.

(x,y,z) -> (x',y')

Вы можете сделать это, указав три отображения из трехмерной точки в двумерную точку.

(1,0,0) -> (  1,  0)
(0,1,0) -> (  0,  1)
(0,0,1) -> (-.7,-.7)

Я использовал (-7, -. 7) для доступа z, потому что эта точка составляет приблизительно 1 единицу от начала и на полпути между доступом x и y.

После того, как у вас есть три точки, у вас достаточно информации для вычисления любой произвольной точки x, y, z.

(x,y,z) -> (1*x - .7*z, 1*y - .7*z)

В компьютерной графике происхождение сетки находится не в центре экрана, а в верхнем левом углу. Чтобы использовать уравнение, которое мы только что сгенерировали в нашей программе, мы должны определить смещение, чтобы переместить начало координат в центр экрана. Мы будем называть эту точку смещения (Ox, Oy).

При смещении наше уравнение становится следующим.

(x,y,z) -> (Ox + 1*x - .7*z, Oy + 1*y - .7*z)