如何将数组传递给Objective-C中的函数

如何将数组传递给Objective-C中的函数,objective-c,arrays,function,Objective C,Arrays,Function,我通常传递在C中有数组的函数,因为Objective-C是C的超集,这使得在两者之间进行更改变得很容易。我想用Objective-C编写一个特定的函数,它会将一个glfloat数组(是的,我正在使用OpenGL)传递给函数以进行矩阵计算。我试着这样做: - (void)setIdentity:(GLfloat *)target { target[0] = 1; target[1] = 0; target[2] = 0; target[3] = 0; tar

我通常传递在C中有数组的函数,因为Objective-C是C的超集,这使得在两者之间进行更改变得很容易。我想用Objective-C编写一个特定的函数,它会将一个glfloat数组(是的,我正在使用OpenGL)传递给函数以进行矩阵计算。我试着这样做:

- (void)setIdentity:(GLfloat *)target
{
    target[0] = 1;
    target[1] = 0;
    target[2] = 0;
    target[3] = 0;
    target[4] = 0;
    target[5] = 1;
    target[6] = 0;
    target[7] = 0;
    target[8] = 0;
    target[9] = 0;
    target[10] = 1;
    target[11] = 0;
    target[12] = 0;
    target[13] = 0;
    target[14] = 0;
    target[15] = 1;
}
然后尝试使用以下方法将矩阵作为16个条目的长GLfloat数组传递给函数:

[matrix setIdentity:ModelMat];
//Log the result
NSLog(@"ModelMat:\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f", 
      ModelMat[0], ModelMat[1], ModelMat[2], ModelMat[3], ModelMat[4], ModelMat[5], 
      ModelMat[6], ModelMat[7], ModelMat[8], ModelMat[9], ModelMat[10], ModelMat[11],
      ModelMat[12], ModelMat[13], ModelMat[14], ModelMat[15]);
只是为了确保返回正确的值,但输出只是一个0的矩阵。我做错了什么

  • 编辑
为了更好地帮助其他人理解我的问题,我添加了场景类的源代码,我试图在其中设置标识,以及矩阵类(我有标识),以及其中更多与矩阵相关的项

矩阵h

@interface Matrix : NSObject

- (void)copyMatrix:(GLfloat *)from to:(GLfloat *)to;
- (void)setIdentity:(GLfloat *)target;
- (void)multiplyMatrix:(GLfloat *)second by:(GLfloat *)first giving:(GLfloat *)newMatrix;
- (void)applyTranslation:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
- (void)applyScale:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z;
- (void)applyRotation:(GLfloat *)source pitch:(GLfloat)pitch yaw:(GLfloat)yaw roll:(GLfloat)roll;
- (void)applyRotationWithMag:(GLfloat *)source angle:(GLfloat)angle magX:(GLfloat)magX magY:(GLfloat)magY magZ:(GLfloat)magZ
- (void)setProjection:(GLfloat *)source fov:(GLfloat)fov aspect:(GLfloat)aspect near:(GLfloat)near far:(GLfloat)far;

@end
Matrix.m

#import "Matrix.h"

#define PI 3.1415926535897932384626433832795f

@implementation Matrix

- (void)copyMatrix:(GLfloat *)from to:(GLfloat *)to
{
    for(int i = 0; i < 16; i++)
        from[i] = to[i];
}

- (void)setIdentity:(GLfloat *)target
{
    target[0] = 1;
    target[1] = 0;
    target[2] = 0;
    target[3] = 0;
    target[4] = 0;
    target[5] = 1;
    target[6] = 0;
    target[7] = 0;
    target[8] = 0;
    target[9] = 0;
    target[10] = 1;
    target[11] = 0;
    target[12] = 0;
    target[13] = 0;
    target[14] = 0;
    target[15] = 1;
}

- (void)multiplyMatrix:(GLfloat *)second by:(GLfloat *)first giving:(GLfloat *)newMatrix
{
    GLfloat tempMatrix[16];

    //Column 1
    tempMatrix[0] = (second[0] * first[0]) +
                            (second[4] * first[1]) +
                            (second[8] * first[2]) +
                            (second[12] * first[3]);

    tempMatrix[1] = (second[1] * first[0]) +
                            (second[5] * first[1]) +
                            (second[9] * first[2]) +
                            (second[13] * first[3]);

    tempMatrix[2] = (second[2] * first[0]) +
                            (second[6] * first[1]) +
                            (second[10] * first[2]) +
                            (second[14] * first[3]);

    tempMatrix[3] = (second[3] * first[0]) +
                            (second[7] * first[1]) +
                            (second[11] * first[2]) +
                            (second[15] * first[3]);

    //Column 2
    tempMatrix[4] = (second[0] * first[4]) +
                            (second[4] * first[5]) +
                            (second[8] * first[6]) +
                            (second[12] * first[7]);

    tempMatrix[5] = (second[1] * first[4]) +
                            (second[5] * first[5]) +
                            (second[9] * first[6]) +
                            (second[13] * first[7]);

    tempMatrix[6] = (second[2] * first[4]) +
                            (second[6] * first[5]) +
                            (second[10] * first[6]) +
                            (second[14] * first[7]);

    tempMatrix[7] = (second[3] * first[4]) +
                            (second[7] * first[5]) +
                            (second[11] * first[6]) +
                            (second[15] * first[7]);

    //Column 3
    tempMatrix[8] = (second[0] * first[8]) +
                            (second[4] * first[9]) +
                            (second[8] * first[10]) +
                            (second[12] * first[11]);

    tempMatrix[9] = (second[1] * first[8]) +
                            (second[5] * first[9]) +
                            (second[9] * first[10]) +
                            (second[13] * first[11]);

    tempMatrix[10] = (second[2] * first[8]) +
                             (second[6] * first[9]) +
                             (second[10] * first[10]) +
                             (second[14] * first[11]);

    tempMatrix[11] = (second[3] * first[8]) +
                             (second[7] * first[9]) +
                             (second[11] * first[10]) +
                             (second[15] * first[11]);

    //Column 4
    tempMatrix[12] = (second[0] * first[12]) +
                             (second[4] * first[13]) +
                             (second[8] * first[14]) +
                             (second[12] * first[15]);

    tempMatrix[13] = (second[1] * first[12]) +
                             (second[5] * first[13]) +
                             (second[9] * first[14]) +
                             (second[13] * first[15]);

    tempMatrix[14] = (second[2] * first[12]) +
                             (second[6] * first[13]) +
                             (second[10] * first[14]) +
                             (second[14] * first[15]);

    tempMatrix[15] = (second[3] * first[12]) +
                             (second[7] * first[13]) +
                             (second[11] * first[14]) +
                             (second[15] * first[15]);

    [self copyMatrix:tempMatrix to:newMatrix];
}

- (void)applyTranslation:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z
{
    GLfloat tempMatrix[16];

    [self setIdentity:tempMatrix];

    tempMatrix[12] = x;
    tempMatrix[13] = y;
    tempMatrix[14] = z;

    [self multiplyMatrix:tempMatrix by:source giving:source];

}

- (void)applyScale:(GLfloat *)source x:(GLfloat)x y:(GLfloat)y z:(GLfloat)z
{
    GLfloat tempMatrix[16];

    [self setIdentity:tempMatrix];

    tempMatrix[0] = x;
    tempMatrix[5] = y;
    tempMatrix[10] = z;

    [self multiplyMatrix:tempMatrix by:source giving:source];
}

- (void)applyRotation:(GLfloat *)source pitch:(GLfloat)pitch yaw:(GLfloat)yaw roll:(GLfloat)roll
{
    GLfloat tempMatrix[16];

    if (pitch != 0) {
        GLfloat c = cosf(pitch);
        GLfloat s = sinf(pitch);

        [self setIdentity:tempMatrix];

        tempMatrix[5] = c;
        tempMatrix[6] = -s;
        tempMatrix[9] = s;
        tempMatrix[10] = c;

        [self multiplyMatrix:tempMatrix by:source giving:source];
    }

    if (yaw != 0) {
        GLfloat c = cosf(yaw);
        GLfloat s = sinf(yaw);

        [self setIdentity:tempMatrix];

        tempMatrix[0] = c;
        tempMatrix[2] = s;
        tempMatrix[8] = -s;
        tempMatrix[10] = c;

        [self multiplyMatrix:tempMatrix by:source giving:source];
    }

    if (roll != 0) {
        GLfloat c = cosf(roll);
        GLfloat s = sinf(roll);

        [self setIdentity:tempMatrix];

        tempMatrix[0] = c;
        tempMatrix[1] = -s;
        tempMatrix[4] = s;
        tempMatrix[5] = c;

        [self multiplyMatrix:tempMatrix by:source giving:source];
    }
}

- (void)applyRotationWithMag:(GLfloat *)source angle:(GLfloat)angle magX:(GLfloat)magX magY:(GLfloat)magY magZ:(GLfloat)magZ
{
    GLfloat tempMatrix[16];

    GLfloat sinAngle, cosAngle;
    GLfloat magnitude;

    magnitude = sqrtf((magX * magX) + (magY * magY) + (magZ * magZ));

    sinAngle = sinf(angle * PI / 180.0f);
    cosAngle = cosf(angle * PI / 180.0f);

    if (magnitude > 0) {
        GLfloat xx, yy, zz, xy, xz, yz, xs, ys, zs;
        GLfloat oneMinusCos;

        magX /= magnitude;
        magY /= magnitude;
        magZ /= magnitude;

        xx = magX * magX;
        yy = magY * magY;
        zz = magZ * magZ;
        xy = magX * magY;
        xz = magX * magZ;
        yz = magY * magZ;
        xs = magX * sinAngle;
        ys = magY * sinAngle;
        zs = magZ * sinAngle;

        oneMinusCos = 1 - cosAngle;

        tempMatrix[0] = (oneMinusCos * xx) + cosAngle;
        tempMatrix[1] = (oneMinusCos * xy) - zs;
        tempMatrix[2] = (oneMinusCos * xz) + ys;
        tempMatrix[3] = 0;

        tempMatrix[4] = (oneMinusCos * xy) + zs;
        tempMatrix[5] = (oneMinusCos * yy) + cosAngle;
        tempMatrix[6] = (oneMinusCos * yz) - xs;
        tempMatrix[7] = 0;

        tempMatrix[8] = (oneMinusCos * xz) - ys;
        tempMatrix[9] = (oneMinusCos * yz) + xs;
        tempMatrix[10] = (oneMinusCos * zz) + cosAngle;
        tempMatrix[11] = 0;

        tempMatrix[12] = 0;
        tempMatrix[13] = 0;
        tempMatrix[14] = 0;
        tempMatrix[15] = 1;

        [self multiplyMatrix:tempMatrix by:source giving:source];

    }
}

- (void)setProjection:(GLfloat *)source fov:(GLfloat)fov aspect:(GLfloat)aspect near:(GLfloat)near far:(GLfloat)far
{
    GLfloat tempMatrix[16];

    [self setIdentity:tempMatrix];

    GLfloat r = fov * M_PI / 180.0f;
    GLfloat f = 1.0f / tanf(r / 2.0f);

    tempMatrix[0] = f;
    tempMatrix[5] = f / aspect;
    tempMatrix[10] = -(far + near) / (far - near);
    tempMatrix[11] = -1;
    tempMatrix[14] = -(2 * far * near) / (far - near);
    tempMatrix[15] = 0;

    [self multiplyMatrix:tempMatrix by:source giving:source];
}

@end
Scene.m(使用苹果全屏演示中的一些代码)


您没有在任何地方创建
矩阵的实例。在
-[Scene init]
中,需要添加一行来创建
矩阵的实例,如下所示:

    ...
    GLfloat indices[6] =
    {
        0, 1, 2,
        0, 2, 3
    };

    // Add the following line
    matrix = [[Matrix alloc] init];

    [matrix setIdentity:ModelMat];
    [matrix setIdentity:ViewMat];
    ...

这将解决它,尽管坦率地说,您的
矩阵
实例方法都可以转换为类方法。您的
Matrix
类没有任何实例变量,而且这些方法更像是独立函数。这样您就不必跟踪矩阵对象了。

在您写的注释中:

让我澄清一下。ModelMat在其调用的文件头中创建。它只是这样创建的:GLfloat ModelMat[16]

这确实创建了一个数组
ModelMat
,因为
GLFloat
是一种值类型,所以可以直接使用它。无论您如何继续:

矩阵部分只是一个指向我的矩阵类的指针,该类包含恒等式函数。我也在标题中创建了它。矩阵*矩阵;它们都是在header接口中创建的

虽然这会创建变量
矩阵
,与上面类似,它的类型
矩阵*
是一个引用类型。创建引用类型的变量不会同时创建对象并将对该对象的引用存储在变量中。在使用
matrix
之前,必须使用以下语句创建对象:

matrix = [Matrix new];

至于传递数组,您可以完全像在C中一样进行传递-记住它们是通过引用传递给函数/方法的。HTH.

向我们展示
ModelMat
的声明。您确定
matrix
是一个实例吗?由于您可以在Objective-C中将消息发送到
nil
,因此您的调用可能尚未执行。请使用调试器逐步检查您的代码,查看数组是否与矩阵对象一样实例化。这是编程的基本部分,与您的问题没有直接关系。你不应该叫它set。。。因为前缀集仅用于setter。setter setAbc设置名为Abc的属性的值。为了避免误解甚至命名冲突,您应该遵守约定。ModelMat也是如此。如果它是一个实例,而不是一个类,那么它应该被命名为modelMat。但是现在我遇到的问题与我将矩阵函数作为全局函数时遇到的问题相同。我得到一个链接器错误,上面写着“\u OBJC\u CLASS\u$\u Matrix”,引用自:Nevermind,我清理了项目,它成功了。谢谢你的帮助
    ...
    GLfloat indices[6] =
    {
        0, 1, 2,
        0, 2, 3
    };

    // Add the following line
    matrix = [[Matrix alloc] init];

    [matrix setIdentity:ModelMat];
    [matrix setIdentity:ViewMat];
    ...
matrix = [Matrix new];