2

我特别需要手动将存储的 openGL 矩阵应用于顶点。我承认在矩阵数学方面有一个弱点,但我已经阅读了我能找到的所有文档,并且我有理由确定我这样做是正确的,但我得到了一个意想不到的结果。我错过了什么?

(请注意,这可能是一个数学问题,但我怀疑我实际上误解了如何应用翻译矩阵,所以我想我会在这里尝试)

在下面的代码片段中,#1 工作正常,#2 失败......

float x=1;
float y=1;
float z=1;
float w=1;

float x2=0;
float y2=0;
float z2=0;
float w2=1;

// 1 THIS WORKS: 
glLoadIdentity();

// Convert from NSArray to C float
float modelMatrix[16];
for(int x=0;x<16;x++){modelMatrix[x]=[[cs.modelView objectAtIndex:x] floatValue];}

// Load the matrix the openGL way
glLoadMatrixf(modelMatrix);

// Custom function takes two coordinates and draws a box
[self drawBoxFromX:x FromY:y FromZ:z ToX:x2 ToY:y2 ToZ:z2];

//2 THIS DOES NOT WORK: Apply the matrix by hand 
glLoadIdentity();
float new_x = (x*modelMatrix[0])+(y*modelMatrix[4])+(z*modelMatrix[8])+(w*modelMatrix[12]);
float new_y = (x*modelMatrix[1])+(y*modelMatrix[5])+(z*modelMatrix[9])+(w*modelMatrix[13]);
float new_z = (x*modelMatrix[2])+(y*modelMatrix[6])+(z*modelMatrix[10])+(w*modelMatrix[14]);
float new_x2 = (x2*modelMatrix[0])+(y2*modelMatrix[4])+(z2*modelMatrix[8])+(w2*modelMatrix[12]);
float new_y2 = (x2*modelMatrix[1])+(y2*modelMatrix[5])+(z2*modelMatrix[9])+(w2*modelMatrix[13]);
float new_z2 = (x2*modelMatrix[2])+(y2*modelMatrix[6])+(z2*modelMatrix[10])+(w2*modelMatrix[14]);

// Should draw a box identical to above, but gives strange result)
[self drawBoxFromX:new_x FromY:new_y FromZ:new_z ToX:new_x2 ToY:new_y2 ToZ:new_z2];

更新:

根据下面的有用评论,我意识到我只旋转了两个顶点,而不是立方体的全部 8 个。以下代码按预期工作,在这里发布给遇到类似问题的任何人,他们围绕 3d/opengl 的东西。(注意:如果不明显,这不是生产代码。有许多更有效且更少手动的方法乘以矩阵和描述立方体(见注释)。这段代码的目的只是为了明确地说明一种行为。)

struct Cube myCube;
myCube.a1.x=-1;
myCube.a1.y=-1;
myCube.a1.z=-1;

myCube.b1.x=-1;
myCube.b1.y=-1;
myCube.b1.z=1;

myCube.c1.x=1;
myCube.c1.y=-1;
myCube.c1.z=1;

myCube.d1.x=1;
myCube.d1.y=-1;
myCube.d1.z=-1;

myCube.a2.x=-1;
myCube.a2.y=1;
myCube.a2.z=-1;

myCube.b2.x=-1;
myCube.b2.y=1;
myCube.b2.z=1;

myCube.c2.x=1;
myCube.c2.y=1;
myCube.c2.z=1;

myCube.d2.x=1;
myCube.d2.y=1;
myCube.d2.z=-1;


//1 Load modelview and draw a box (this works fine)
glLoadIdentity();
float modelMatrix[16];
for(int x=0;x<16;x++){modelMatrix[x]=[[cs.modelView objectAtIndex:x] floatValue];}

glLoadMatrixf(modelMatrix);
[self drawCube:myCube];


//2 Load the matrix by hand (identical to above)
glLoadIdentity();
float w=1;

float new_Ax = (myCube.a1.x*modelMatrix[0])+(myCube.a1.y*modelMatrix[4])+(myCube.a1.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_Ay = (myCube.a1.x*modelMatrix[1])+(myCube.a1.y*modelMatrix[5])+(myCube.a1.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_Az = (myCube.a1.x*modelMatrix[2])+(myCube.a1.y*modelMatrix[6])+(myCube.a1.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_Bx = (myCube.b1.x*modelMatrix[0])+(myCube.b1.y*modelMatrix[4])+(myCube.b1.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_By = (myCube.b1.x*modelMatrix[1])+(myCube.b1.y*modelMatrix[5])+(myCube.b1.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_Bz = (myCube.b1.x*modelMatrix[2])+(myCube.b1.y*modelMatrix[6])+(myCube.b1.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_Cx = (myCube.c1.x*modelMatrix[0])+(myCube.c1.y*modelMatrix[4])+(myCube.c1.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_Cy = (myCube.c1.x*modelMatrix[1])+(myCube.c1.y*modelMatrix[5])+(myCube.c1.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_Cz = (myCube.c1.x*modelMatrix[2])+(myCube.c1.y*modelMatrix[6])+(myCube.c1.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_Dx = (myCube.d1.x*modelMatrix[0])+(myCube.d1.y*modelMatrix[4])+(myCube.d1.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_Dy = (myCube.d1.x*modelMatrix[1])+(myCube.d1.y*modelMatrix[5])+(myCube.d1.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_Dz = (myCube.d1.x*modelMatrix[2])+(myCube.d1.y*modelMatrix[6])+(myCube.d1.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_A2x = (myCube.a2.x*modelMatrix[0])+(myCube.a2.y*modelMatrix[4])+(myCube.a2.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_A2y = (myCube.a2.x*modelMatrix[1])+(myCube.a2.y*modelMatrix[5])+(myCube.a2.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_A2z = (myCube.a2.x*modelMatrix[2])+(myCube.a2.y*modelMatrix[6])+(myCube.a2.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_B2x = (myCube.b2.x*modelMatrix[0])+(myCube.b2.y*modelMatrix[4])+(myCube.b2.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_B2y = (myCube.b2.x*modelMatrix[1])+(myCube.b2.y*modelMatrix[5])+(myCube.b2.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_B2z = (myCube.b2.x*modelMatrix[2])+(myCube.b2.y*modelMatrix[6])+(myCube.b2.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_C2x = (myCube.c2.x*modelMatrix[0])+(myCube.c2.y*modelMatrix[4])+(myCube.c2.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_C2y = (myCube.c2.x*modelMatrix[1])+(myCube.c2.y*modelMatrix[5])+(myCube.c2.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_C2z = (myCube.c2.x*modelMatrix[2])+(myCube.c2.y*modelMatrix[6])+(myCube.c2.z*modelMatrix[10])+(w*modelMatrix[14]);

float new_D2x = (myCube.d2.x*modelMatrix[0])+(myCube.d2.y*modelMatrix[4])+(myCube.d2.z*modelMatrix[8])+(w*modelMatrix[12]);
float new_D2y = (myCube.d2.x*modelMatrix[1])+(myCube.d2.y*modelMatrix[5])+(myCube.d2.z*modelMatrix[9])+(w*modelMatrix[13]);
float new_D2z = (myCube.d2.x*modelMatrix[2])+(myCube.d2.y*modelMatrix[6])+(myCube.d2.z*modelMatrix[10])+(w*modelMatrix[14]);



myCube.a1.x=new_Ax;
myCube.a1.y=new_Ay;
myCube.a1.z=new_Az;

myCube.b1.x=new_Bx;
myCube.b1.y=new_By;
myCube.b1.z=new_Bz;

myCube.c1.x=new_Cx;
myCube.c1.y=new_Cy;
myCube.c1.z=new_Cz;

myCube.d1.x=new_Dx;
myCube.d1.y=new_Dy;
myCube.d1.z=new_Dz;

myCube.a2.x=new_A2x;
myCube.a2.y=new_A2y;
myCube.a2.z=new_A2z;

myCube.b2.x=new_B2x;
myCube.b2.y=new_B2y;
myCube.b2.z=new_B2z;

myCube.c2.x=new_C2x;
myCube.c2.y=new_C2y;
myCube.c2.z=new_C2z;

myCube.d2.x=new_D2x;
myCube.d2.y=new_D2y;
myCube.d2.z=new_D2z;



[self drawCube:myCube];
4

1 回答 1

0

绘制一个旋转的盒子与旋转盒子的两个角然后绘制一个轴平行的盒子是不同的。绘制一个变换的 3D 盒子最简单的方法是变换所有 8 个顶点。

于 2013-05-30T13:35:59.277 回答