WPF3D Как манипулировать объектами в плоскости, параллельной камере - PullRequest
2 голосов
/ 30 ноября 2011

Я делаю заявку в WPF.Я часто использую 3DTools .У меня есть тетраэдр и внутри него куб.Я хочу переместить куб в трехмерном направлении.

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

Пользователи приложения считают, что более естественный способ перемещения куба внутри него - это перемещение его всегда в 2D-плоскости (параллельно экрану).Поэтому, если я хочу переместить его глубже на экране, я просто поверну тетраэдр и переместу его, например, по оси Y.Я думаю, что это может быть хорошим решением.

У меня проблемы, и я хотел бы помочь решить их: во-первых, когда я перемещаю свой тетраэдр (внутри трекбола), трекбол выглядит как перемещение всех системных координат,Я говорю это потому, что рисую ось для целей отладки, и эти оси также вращаются.Но это не так - они движутся только потому, что внутри трекбола находятся объекты (верно?). РЕДАКТИРОВАТЬ На самом деле, я думаю, что система координат внутри трекбола действительно меняется.Когда я перемещаю куб по оси YX, я веду себя хорошо.Но если я немного повернусь и попытаюсь двигаться по оси Z, я вижу, что она становится больше (ближе к камере) и меньше (далеко от камеры).= (

Итак, мои вопросы как определить плоскость, которая не будет вращаться при помощи трекбола? Для меня ответ выглядит примерно так: «Хорошо, просто определите его вне трекбола», но, как я сказал (и в документации 3DTools сказано), у меня есть граница над моим окном просмотра ... Так что я не знаю, как с этим справиться.

Мой тетраэдр в наборе ScreenSpaceLines3D. Мне придется сохранитькуб внутри него. Мой второй вопрос как отследить положение вершины тетраэдра, в котором он вращается ? Я очень разочаровался, когда свойство Position дало мне исходные позиции и ничего больше. Должен ли ясохранить преобразования матриц и применить их тогда к моим точкам, когда мне нужно тогда?

Извините за длинный текст, но я действительно застрял в этом не так много вопросов программирования. Я знаю в WPF, у меня все еще есть некоторые недостаткипонятия.

Заранее спасибо,

Педро

Ответы [ 2 ]

5 голосов
/ 05 января 2012

Затем я попытался бы создать свои собственные манипуляторы (создать новые классы, которые заменят TrackBall Manipulator из 3DTools), чтобы сделать это.Например, в прошлом я выполнял масштабирование / панорамирование, вращение вокруг цели, свободное вращение, свободное перемещение, вращение объекта, преобразование объекта и т. Д., Выполняя простые манипуляции с матрицами / векторами.

Для вашегоНапример, вам нужно вычислить нормаль, которая ортогональна плоскости между Camera-> Target и вектором мира вверх.это даст вам вектор, который «параллелен» сверху камеры, как локальная ось X, если вы смотрите на экран.Используя этот вектор, вы можете ограничить движение куба в этом направлении.

Для этого вычисляем вектор V от камеры к цели.Это достигается вычитанием местоположения объекта из местоположения камеры.Затем вычислите вектор для перевода в сторону следующим образом:

Для заданного вектора вашей камеры: v = xi, yj, zk
Нормализовать вектор, v '= xi, yj, zk / sqrt (xi ^ 2 + yj ^ 2 + zk ^ 2)
Пусть U = глобальный мир вверх вектор u = 0, 0, 1

Тогда мы можем вычислить R = ГоризонтальныйВектор, параллельный направлению обзора камеры

R = v' ^ U, where ^ is the cross product, given by   
 a ^ b = (a2b3 - a3b2)i + (a3b1 - a1b3)j + (a1b2 - a2b1)k 

Это даст вам вектор, который выглядит следующим образом.

Cross Product to find vector parallel to camera direction

Теперь вы знаете этот вектор R, когда вы перемещаете мышь влево / вправо, вы можете использовать его для перемещения объекта.Например, в псевдокоде:

// Pseudocode
onMouseMove()
{
    // Using calculation for R vector above
    Vector r = calulateVector();

    // Assuming passed in the number of points to translate 
    // (or some derivative of mousemove)
    let int pts = mousePointsMovedLeftOrRight;

    // Perform a translate in direction of R
    Vector targetPosition = TargetObject.PositionVector;
    targetPosition.X += r.X * pts;
    targetPosition.Y += r.Y * pts;
    targetPosition.Z += r.Z * pts;
}

У меня дома на ноутбуке есть код, который может это сделать (это OpenGL, но тот же принцип - обеспечивает различные манипуляции с объектами и камерой в трехмерном пространстве).Пожалуйста, не стесняйтесь связаться со мной / комментарий, если вы хотите узнать больше.

С уважением,

1 голос
/ 05 января 2012

Я сделал нечто подобное без трекбола. Я просто использовал событие MouseMove для перемещения и ориентации камеры, но это было бы также применимо для перемещения объекта. У меня все еще есть код, если вы хотите его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...