Java / JavaME: более быстрое геометрическое векторное сложение


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

В настоящее время я сделал этот код до сих пор:

public void add(Vector2D v){
    double ang = this.angle*Math.PI/180;
    double mag = this.magnitude;
    double ang0 = v.angle*Math.PI/180;
    double mag0 = v.magnitude;
    //vector to coordinates
    double x1 = mag*Math.cos(ang);
    double y1 =-mag*Math.sin(ang);
    //adding the other vector's coordinates
    double x2 =x1+mag*Math.cos(ang0);
    double y2 =y1-mag*Math.sin(ang0);
    //back to vector form
    double newMagnitude = Math.sqrt(x2*x2+y2*y2);
    double newAngle = Math.atan2(y2,x2);
    this.magnitude = newMagnitude;
    this.angle = newAngle;

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

Есть ли лучший способ?
1 2

1 ответ:

Во-первых, некоторые термины 101:

Точка: безразмерная сущность, из которой состоит пространство.

Пространство: множество точек.

Евклидово пространство: множество точек вместе с множеством прямых и с понятием близости (топология). Множество прямых связано аксиомами Евклида. Она однозначно определяется своим измерением.

Вектор: инвариантное к переводу отношение между двумя точками в евклидовом пространстве. пространство.

Система координат: отображение из кортежей вещественных чисел в точки или векторы в некотором пространстве.

Декартова система координат: конкретное отображение со свойствами (в случае евклидова двумерного пространства), что множество точек ax+by+c=0 является линией, если только a,b не равно нулю, что векторы [0,1] и [1,0] перпендикулярны и единичны, и что точки в пространстве близки друг к другу, если они близки друг к другу во всех координатах. Это то, что вы см. также "координаты".

Полярная система координат: другое конкретное отображение, которое может быть определено из декартовых координат: [arg,mag] в полярной системе координат до [cos(arg)*mag, sin(arg)*mag] в декартовых координатах. Это то, что вы называете "векторной формой".


Декартова система координат имеет множество преимуществ перед полярной системой координат. Одним из них является более простое сложение: [x1,y1]+[x2,y2]=[x1+x2,y1+y2] и скалярное умножение: [x1,y1].[x2,y2]=x1*x2+y1*y2. Аддитивная инверсия также немного проще: -[x,y]=[-x,-y] Еще одно преимущество состоит в том, что, хотя полярные координаты строго ДВУМЕРНЫ (нет однозначного расширения - хотя сферическая система координат является кандидатом), декартовы координаты естественным образом распространяются на любое число измерений. По этой причине полезно - и обычно-всегда хранить векторы в их декартовой координатной форме. Если вам когда-нибудь понадобятся векторы в их полярной форме, то (и только тогда) преобразуйте, раз и навсегда.

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


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

Вы должны хранить ваши векторы в декартовой форме. Улучшение производительности должно быть четко видно, если вы отбросите избыточное преобразование.

Даже если вы хотите повернуть вектор, его не выгодно преобразовывать в Полярный и обратно. Поворот на знаковый угол a так же прост, как и [x*cos(a)+y*sin(a), y*cos(a)-x*sin(a)]. Это две тригонометрические функции (самое большее - вы можете кэшировать эти значения), чтобы повернуть весь массив векторов.