Java / JavaME:更快的几何向量添加

时间:2013-01-01 01:32:33

标签: java vector geometry addition

我正在制作一个简单用法的简单Vector类,因此我不想导入整个库(如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 个答案:

答案 0 :(得分:2)

首先,一些术语101:

:无空间的实体,空间由。

组成

空间:一组积分。

欧几里德空间:一组点,连同一组线和近似概念(拓扑)。这组线由欧几里德的公理约束。它的维度是唯一定义的。

向量:欧几里德空间中两点之间的平移不变关系。

坐标系:从实数元组到某些空间中的点或向量的映射。

笛卡尔坐标系:一个特定的映射,其属性(在欧几里德2D空间的情况下)点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]

另一个好处是虽然极坐标严格地是2D(没有唯一的扩展 - 但球面坐标系是候选的),笛卡尔坐标自然地延伸到任意数量的维度。

出于这个原因,总是以矢量坐标形式存储矢量是有益的 - 通常 -

如果你需要极性形式的矢量,那么(并且只有这样)才能一劳永逸地转换。

极坐标不那么有用。它们可用于输入和输出,但它们很少用于计算。


你一直以极坐标形式存储你的矢量。您将它们转换为笛卡尔形式进行计算,然后转换回极点 - 仅将它们转换为笛卡尔坐标。

您应该以笛卡尔形式存储您的矢量。如果删除冗余转换,应该清楚地看到性能改进。

即使您想要旋转矢量,转换为极地和背面也没有好处。按有角度a旋转就像[x*cos(a)+y*sin(a), y*cos(a)-x*sin(a)]一样简单。那是两个三角函数(最多 - 你可以缓存这些值)来旋转整个矢量数组。