2016-06-10 5 views
0

Как я могу залезть между двумя 3D-векторами? Я использую этот метод для 2d векторов:3D-векторная линейная интерполяция

public Vector2d lerp(Vector2d other, double speed, double error) { 
    if (equals(other) || getDistanceSquared(other) <= error * error) 
     return other; 
    double dx = other.getX() - this.x, dy = other.getY() - this.y; 
    double direction = Math.atan2(dy, dx); 
    double x = this.x + (speed * Math.cos(direction)); 
    double y = this.y + (speed * Math.sin(direction)); 
    return new Vector2d(x, y); 
} 

Примечание: это не совсем «линейная интерполяция»; этот метод будет интерполировать с постоянной скоростью, чего я хочу.

Я хочу сделать именно это, но с добавленным компонентом z для третьего измерения. Как я могу это сделать?

ответ

0

Самый простой способ - преобразовать ваши два вектора таким образом, чтобы они лежали в плоскости (u, v); затем примените свой метод выше; затем преобразуйте обратно в исходное координатное пространство.

Для этого необходимо построить матрицу вращения:

  1. Возьмите векторное произведение двух векторов ваших, чтобы получить взаимный вектор нормали; назовите это cross_1;
  2. Определить, что this точек вдоль оси u;
  3. Возьмите крест продукта this и cross_1, чтобы получить вектор cross_2, который является направлением вашей оси v.
  4. Нормализовать каждый из этих трех векторов; назовите их this_norm, cross_2_norm и cross_1_norm.

Эти три вектора могут быть записаны в виде матрицы 3х3 ортонормированному (каждый из векторов является вектор а 3-элементный столбец):

R = [ this_norm cross_2_norm cross_1_norm ] 

Теперь вы можете умножить ваши 3d векторы this и other по эта матрица, и вы получите векторы, которые имеют вид

[ u ] 
[ v ] 
[ 0 ] 

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

Таким образом, вы можете, очевидно, отказаться от третьего элемента и иметь двухэлементные векторы столбцов: вы можете сохранить их в Vector2d. И поэтому вы можете применить свой метод выше, чтобы сделать интерполяцию.

Это дает вам Vector2d, который интерполируется в самолете (u, v). Вы можете преобразовать это обратно в пространство (x, y, z), присоединив к нему нулевой третий элемент и предварительно умножив на R' (который является обратным R, так как он является ортонормированным).

Конечно, вам необходимо обрабатывать вырожденные случаи, например, нулевые и (анти-) параллельные векторы. В этих случаях один или оба кросс-произведения равны нулю, то есть вы не можете их нормализовать; вместо этого просто выберите произвольные направления.

0

Если я правильно понимаю ваш код, когда вы вычисляете смещения dx и dy, затем вычисляйте угол от него и, наконец, пару sin/cos - вы в основном нормализуете вектор dx, dy, чтобы вы могли написать его так :

Vector2d delta = other - this;   // I'm not sure about your API here, 
delta.normalize();      // you may need to fix those lines 
double x = this.x + (speed * delta.x); 
double y = this.y + (speed * delta.y); 

Теперь необходимо добавить элемент Z прямо.

Смежные вопросы