#c# #xna #3d #vector-graphics
#c# #xna #3D #векторная графика
Вопрос:
Я выполнил поиск по этому вопросу, но не нашел вопроса, который вполне соответствовал тому, что мне было нужно. Я хочу, чтобы пользователь мог определять текстурированную плоскость. У меня есть следующие параметры:
- Размер (вектор2)
- Направление (вектор3)
- Начало координат (вектор3)
Итак, я хочу иметь возможность вычислить 4 вершины прямоугольника с учетом приведенной выше информации. Итак, если бы я хотел, чтобы плоскость была обращена вверх, с шириной и высотой 1000:
- Размер = (1000, 1000)
- Направление = 0, 1, 0 (вверх)
- Начало координат = 0, 0, 0
Таким образом, это определило бы плоскость на оси X и Z, обращенную вверх. Чего я не понимаю, так это как рассчитать 4 угла в трехмерном пространстве с учетом этой информации. Нужна ли мне дополнительная информация или есть лучший способ произвольно указать плоскость?
Редактировать: текущий код
В следующем коде:
- Размер = 10000, 10000
- Центр = 0, 0, 0
-
Нормальный = 0, 1, 0
Vector3 arb = new Vector3(1, 1, 1); Vector3 planeY = Vector3.Normalize(Vector3.Cross(Normal, arb)); Vector3 planeX = Vector3.Normalize(Vector3.Cross(Normal, planeY)); planeX *= Size.X / 2; planeY *= Size.Y / 2; Vector3[] ret = new Vector3[4] { (Center - planeX - planeY), (Center - planeX planeY), (Center planeX - planeY), (Center planeX planeY) };
Ответ №1:
Ваша плоскость еще не полностью определена. Вам нужен другой вектор, идущий вдоль плоскости, так называемый «касательный» вектор. В приведенном выше примере, куда должна указывать ось Y текстуры? Вдоль оси X, вдоль оси Z? Или, может быть, совершенно другая пользовательская ось? Ваш касательный вектор — это вектор, который должен указывать в общем направлении, куда должна проходить ось X плоскости.
Допустим, у нас также есть касательный вектор, он не обязательно должен указывать вдоль плоскости. Вы можете построить плоскость следующим образом:
Vector3[] vertices(Vector2 size, Vector3 center, Vector3 normal, Vector3 tangent)
{
Vector3 planeY = Vector3.Normalize(Vector3.Cross(normal, tangent));
Vector3 planeX = Vector3.Normalize(Vector3.Cross(normal, planeY));
planeX *= size.X / 2;
planeY *= size.Y / 2;
vertices = new Vector3[]
{
(center - planeX - planeY),
(center - planeX planeY),
(center planeX - planeY),
(center planeX planeY),
};
return vertices;
}
planeX и planeY являются нормализованными векторами, которые указывают вдоль осей X и Y самой плоскости. Умножая их на size / 2, мы получаем 2 вектора, которые простираются от центра до края плоскости в обоих направлениях X и Y. Складывая эти два вместе разными способами, мы получаем четыре угла.
Вот диаграмма, чтобы вы могли лучше представить себе картину в своей голове. Касательный вектор T «сплющивается» по оси X.
Комментарии:
1. Привет, Ханнаш, спасибо за ваш комментарий и пример кода. Предполагая
tangent
, что в вашем примере вектор ВВЕРХ, я реконструировал то, что вы передалиVector3.Up
вместо касательной, но значения planeY — это всеNaN
, поэтому не уверен, что здесь происходит. Возможно, причина в том, что моя нормальная0,1,0
, потому что я хочу, чтобы эта конкретная плоскость была обращена вверх. И поэтому он вызывается как `Vector3.Cross(«0, 1, 0», «0, 1, 0»)’ что, я уверен, неправильно.2. Именно по этой причине :), выберите любое другое значение для up, и оно будет работать нормально. Вы не можете определить плоскость с той же осью X, что и направление, в котором она обращена к себе.
3. Я подумал, поэтому я предоставил вектор вверх (1,1,1). Учитывая начало координат
0, 0, 0
, нормаль0, 1, 0
и размер10000, 10000
, я получаю очень странные результаты. [0] ={X:0.0002441406 Y:0 Z:7071.068}
. [1] ={X:7071.068 Y:0 Z:0.0002441406}
, [2] ={X:-7071.068 Y:0 Z:-0.0002441406}
и [3] ={X:-0.0002441406 Y:0 Z:-7071.068}
. Пытаюсь выяснить, что не так. Я действительно ценю вашу помощь в этом.4. Я только что обновил свой пост текущим кодом, который у меня есть. Когда дело доходит до математики и меня, колесо вращается, но хомяк мертв.
5. Это выглядит правильно. Чего вы ожидали? Плоскость лежит на оси X и Z (компоненты X и Z равны ~ 0). Вы касаете точки по диагонали, поэтому ваша плоскость поворачивается на 45 градусов. Попробуйте Vector3.Left для «нормальной» плоскости.
Ответ №2:
Это прекрасно подходит для определения плоскости: у вас есть точка и вектор нормали. Вам нужно получить два вектора (A amp; B) на плоскости и добавить один (A * одно из значений размера) к началу координат, чтобы получить второй угол. Добавьте второй вектор (B * другое значение размера), чтобы получить третий угол, и добавьте оба вектора * их соответствующие значения размера к началу координат, чтобы получить четвертый угол.
Чтобы получить первый вектор, вычислите перекрестное произведение вектора нормали (направления) с произвольным вектором (не равным направлению). Это даст вам вектор A. Чтобы получить вектор B, вычислите перекрестное произведение A и направления.
Комментарии:
1. Спасибо вам за это. Я не совсем уверен, что вы подразумеваете под «произвольным вектором (не равным направлению)». Я пытаюсь представить, как это будет выглядеть, но не очень далеко. Спасибо за ваш быстрый ответ.
2. Ну, направление — это трехмерный вектор, поэтому создайте новый вектор с любыми 3 значениями, которые не равны значениям вектора направления. Перекрестное произведение этого даст вам нормализованный вектор, ортогональный направлению. Вы можете умножить этот новый вектор на одно из свойств размера, чтобы получить второй угол.