iOS OpenGL ES 2.0 旋转 1 点笛卡尔 X 弧度关于原点

Posted

技术标签:

【中文标题】iOS OpenGL ES 2.0 旋转 1 点笛卡尔 X 弧度关于原点【英文标题】:iOS OpenGL ES 2.0 Rotate 1 Point Cartesian X Radians about Origin 【发布时间】:2014-02-16 18:35:48 【问题描述】:

我需要围绕 Z 轴旋转以笛卡尔 XYZ 坐标表示的单个点。以下 2 次尝试无法正常工作 - 我相信第一次更正确..

我尝试使用此网站上的数学来旋转点:http://farside.ph.utexas.edu/teaching/336k/newton/node153.html

// Rotate the XYZ coordinate for the pin image
if ( [satName isEqualToString:@"pin"] ) 
    double x = xyz.x;
    double y = xyz.y;
    double radians = self.timeSinceOpenGlStarted;
    x = x * cos(radians) + y * sin(radians);
    y = -x * sin(radians) + y * cos(radians);
    xyz.x = x;
    xyz.z = y;

我也试过这个函数,提取GLKMatrix4Rotate之后的点:

// This function rotates XYZ a certain of radians about the origin and gives back XYZ
- (GLKVector4)rotateXYZCoordinates:(XYZ*)coords 

    // Get the current modelview matrix
    GLKMatrix4 currMat = self.effect.transform.modelviewMatrix;

    // Print the coords before
    NSLog(@"Before: %f %f %f",coords->x,coords->y,coords->z);
    NSLog(@"Rotation Before: %f %f %f",currMat.m00,currMat.m10,currMat.m20);

    // Construct the rows in the new matrix
    float d = sqrt( pow(currMat.m00,2) + pow(currMat.m10,2) + pow(currMat.m20,2) );
    GLKVector4 columnToInsert0 = GLKVector4Make(d, 0, 0, coords->x);
    GLKVector4 columnToInsert1 = GLKVector4Make(0, d, 0, coords->y);
    GLKVector4 columnToInsert2 = GLKVector4Make(0, 0, d, coords->z);
    GLKVector4 columnToInsert3 = GLKVector4Make(0, 0, 0, 1);

    // Build the new Matrix
    GLKMatrix4 noTranslationInfo = GLKMatrix4SetRow(currMat, 0, columnToInsert0);
    noTranslationInfo = GLKMatrix4SetRow(noTranslationInfo, 1, columnToInsert1);
    noTranslationInfo = GLKMatrix4SetRow(noTranslationInfo, 2, columnToInsert2);
    noTranslationInfo = GLKMatrix4SetRow(noTranslationInfo, 3, columnToInsert3);

    // Throw the world translation coordinates in the matrix
    noTranslationInfo.m30 = ( noTranslationInfo.m30 );
    noTranslationInfo.m31 = ( noTranslationInfo.m31 );
    noTranslationInfo.m32 = ( noTranslationInfo.m32 );

    // Now rotate the matrix so many angles
    noTranslationInfo = GLKMatrix4Rotate(noTranslationInfo, self.timeSinceOpenGlStarted, 0, 0, 1);

    // Latch the output
    coords->x = noTranslationInfo.m30;
    coords->y = noTranslationInfo.m31;
    coords->z = noTranslationInfo.m32;

    // Print the coords After
    NSLog(@"AFter: %f %f %f",coords->x,coords->y,coords->z);
    NSLog(@"Rotation After: %f %f %f",noTranslationInfo.m00,noTranslationInfo.m10,noTranslationInfo.m20);


我有一个沿 Z 轴旋转的地球仪和一个指定在特定球坐标(表示纬度/经度位置)的广告牌精灵,并且需要能够使该点随地球旋转或不随地球旋转。

我做错了什么?当我知道要旋转的弧度数时,如何计算新的 X 和 Y 坐标( Z 是常数)以围绕 Z 轴旋转 XYZ 点?谢谢!

更新:现在我已经尝试过了:

// Rotate the XYZ coordinate for the pin image
/* http://www.blitzbasic.com/Community/posts.php?topic=70536
 ;rotate offset around Z axis
 newx# = x# * Cos#(zr#) - y# * Sin#(zr#)
 newy# = x# * Sin#(zr#) + y# * Cos#(zr#)
 x# = newx#
 y# = newy#

 ;rotate offset around X axis
 newy# = y# * Cos#(xr#) - z# * Sin#(xr#)
 newz# = y# * Sin#(xr#) + z# * Cos#(xr#)
 y# = newy#
 z# = newz#


 ;rotate offset around Y axis
 newx# = z# * Sin#(-yr#) + x# * Cos#(-yr#)
 newz# = z# * Cos#(-yr#) - x# * Sin#(-yr#)
 x# = newx#
 z# = newz#
 */
if ( [satName isEqualToString:@"pin"] && self.shouldAnimate == YES ) 

    //NSLog(@"ONE %f %f %f %f",xyz.x,xyz.y,xyz.z,sqrt(pow(xyz.x, 2)+pow(xyz.y,2)+pow(xyz.z,2)));

    double x = xyz.x;
    double y = xyz.y;
    double z = xyz.z;

    NSLog(@"%f",self.timeSinceOpenGlStarted); // Values like: 32521.473728

    double zr = self.timeSinceOpenGlStarted;
    double yr = 0.0f;
    double xr = 0.0f;

    // Rotations must be in this order: Z then X then Y

    // Rotate around Z
    x = x * cos(zr) - y * sin(zr);
    y = x * sin(zr) + y * cos(zr);

    // Rotate around X
    y = y * cos(xr) - z * sin(xr);
    z = y * sin(xr) + z * cos(xr);

    // Rotate around Y
    x = z * sin(-yr) + x * cos(-yr);
    z = z * cos(-yr) + x * sin(-yr);

    // Get the coordinates back
    xyz.x = x;
    xyz.y = y;
    xyz.z = z;

    //NSLog(@"TWO %f %f %f %f",xyz.x,xyz.y,xyz.z,sqrt(pow(xyz.x, 2)+pow(xyz.y,2)+pow(xyz.z,2)));


问题是我的图像在它应该在的纬度/经度周围跳舞 - 它几乎是数字 8。

【问题讨论】:

案例1的结果是什么? 它给了我一个非恒定的旋转加速度——我旋转的弧度是一个恒定的速率。 【参考方案1】:

我要么不明白你想要达到什么目的,要么你的这些方法有点奇怪。如果您需要围绕 Z 轴(在 XY 平面上)围绕中心 (0,0,0) 旋转一个点,那么您应该使用这样的东西:

float x, y;
float currentAngle;
float radius = sqrt(x*x + y*y);
x = radius*cos(currentAngle);
y = radius*sin(currentAngle);

为了更容易,您可以简单地使用半径(在您的情况下应该是恒定的)和以弧度为单位的角度。在这种情况下,您只需要此 sn-p 的最后 2 行。

【讨论】:

感谢您的回答。这解决了它。【参考方案2】:

看起来您正在将每一帧添加到您的角度。您可以计算“增量角度”,只是从前一帧旋转的角度,或者使用现在的角度,但将旋转应用于初始方向,而不是最后一帧的结果。

【讨论】:

以上是关于iOS OpenGL ES 2.0 旋转 1 点笛卡尔 X 弧度关于原点的主要内容,如果未能解决你的问题,请参考以下文章

iOS OpenGL ES 2.0 VBO 混淆

缩放、旋转、平移 w。 openGl ES 2.0 中的矩阵

IOS OpenGL ES GPUImage 图像旋转 GPUImageTransformFilter

OpenGL ES 2.0 - iOS - 使用 FBO 渲染到纹理

OpenGL ES 2.0 (iOS) 中的 2D 绘图

在 iOS 上使用 OpenGL-ES 2.0 设置横向正交投影的正确方法是啥?