如何用2D矢量优化数学?

时间:2014-03-02 18:34:38

标签: ios math vector

我正在使用iOS应用程序,它使用一千个对象的数组执行一些计算。对象具有x和y坐标属性,x和y轴的速度以及其他x-y属性。有一些数学计算数组中对象所代表的物理对象之间的交互。数学是非常直接的,基本上它是计算应用于对象的力,速度和每个对象的位置(x,y)的变化。我在Objective C中使用常规标量数学编写了一个代码,它在iPhone 5s上运行良好,但在iPhone 4,4s,5和iPad mini等其他设备上运行速度太慢。我发现最耗时的操作是计算2点之间的距离和计算矢量长度,如下所示,其中包括取平方根:

float speed = sqrtf(self.dynamic.speed_x,2)+pow(self.dynamic.speed_y,2));

所以,我必须做点什么才能让计算更快。我重新编写代码,使用对象坐标生成属性,并将由X和Y分量表示的诸如velocity之类的属性作为GLKVector2类型的向量。我希望通过使用像GLKVector2Distance,GLKVector2Normalize,GLKVector2Add等特殊的矢量函数来计算变量,如2个矢量(或点,根据我的理解)之间的距离,矢量的加法和减法明显更快。但是,它在性能方面没有太大帮助,因为我认为,将具有GLKVector2类型属性的对象放入数组我必须使用NSValue,以及从对象中解码GLKVector2值。用于执行向量计算的数组。下面是对象实现中计算方法的代码:

GLKVector2 currentPosition;
[self.currentPosition getValue:&currentPosition];
GLKVector2 newPosition;


// calculations with vectors. Result is in newPosition.

self.currentPosition = [NSValue value:&newPosition withObjCType:@encode(GLKVector2)];

此外,当我重写代码以使用GLKVector2时,我收到了内存警告,经过一段时间运行后,应用程序有时会崩溃。

我花了几天时间试图找到更好的方法来更快地进行计算,我看了vecLib,openGL,但还没有找到一个对我来说可以理解的解决方案。我有一种感觉,我可能不得不考虑在C中编写代码并将其以某种方式集成到目标C中,但我不明白如何在不使用NSValue数千次的情况下将其与对象数组集成。

如果有人能帮忙建议我应该看哪个方向,我将不胜感激?也许有一些库可以在Objective C中轻松使用,并且对象组存储在数组中?

3 个答案:

答案 0 :(得分:1)

  1. 了解如何使用乐器。除非您在更改之前和之后测量速度,否则任何性能优化都是毫无意义的。 1000个对象的数组是什么都没有,所以你可能不用担心什么。或者减速是完全不同的地方。使用仪器。

  2. x * x是乘法。 powf(x,2.0)是一个昂贵的函数调用,可能需要20到100倍的时间。

  3. GLKVector2是一个原语(它是一个联合)。试图将其存入NSValue是完全没有意义的,浪费的时间可能比直接存储它多100倍。

答案 1 :(得分:0)

听起来你遇到了几个常见的问题:1)高级语言的快速数学,2)元问题:是否能从别人的工作中获益(OpenGL,{{3作为开发人员,以交换陡峭的学习曲线。

特别是对于这个主题,我认为交易非常有利于使用库。对于许多人来说(例如and several ideas listed here),大部分学习曲线都是关于Objective C和C ++的集成,你可以快速地将它们放在后面。

(顺便说一句,通常情况下,计算对象之间距离的平方就足以进行比较。如果在您的应用中有效,则可以通过替换distance(a,b)来节省周期与distnaceSquared(a,b)

答案 2 :(得分:0)

这里有一个关于将C中的物理计算与当前Objective-C类集成的问题的答案。如果您的.m文件中有一段C代码,可能看起来像

static CGPoint point[MAX_OBJ];
static int n_points = 0;

在普通C中使用相应的函数,如您所建议的那样,模拟作用于point以更新对象位置的物理交互,如

void tick_world() {
    for (int k = 0; k < n_points; k ++) {
        float speed = sqrtf((point[k].x*point[k].x) + (point[k].y*point[k].y));
        ...
    }
}

然后,移动对象的Objective-C类Moving可以包含指向您将在接口中定义的CGPoint中的特定point的指针(可能是相应的{{ 1}}文件):

*.h

处理@interface Moving : NSObject { ... CGPoint *pos; } 消息时,您可以抓取并初始化init中的下一个可用元素。如果您的对象在整个运行时间内持续存在,则可以通过

简单地完成
point

如果您的@implementation ... -(id)initAtX:(float)x0 Y:(float)y0 { self = [super init]; if (self) { if (n_points == MAX_OBJ) { [self release]; return nil; } pos = point + n_points ++; pos->x = x0; pos->y = y0; } return self; } 个对象仍然存在,您可能需要考虑一种在销毁后回收插槽的智能方法。例如,您可以使用Moving初始化x的所有point,并将其用作查找空闲广告位的方法。在NAN中,您将dealloc