球坐标系和旋转变换.在c

q3qa4bjr  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(100)

我尝试将法线贴图应用到我的纹理上。我想找到法线贴图中每个向量的旋转Angular theta和phi(球面坐标)。我计划将现有对象的法线向量相应地旋转这些Angular 。
我已经创建了一个函数来旋转矢量的θ和φ角,但是,它并没有像预期的那样工作。”
下面的函数接受要旋转的向量的参数,旋转Angular (theta和phi),并返回旋转后的向量。

#include <stdio.h>
#include <math.h>

typedef struct {
    double x;
    double y;
    double z;
} t_p3;

void print_p3(const char *prefix, const t_p3 *p) {
    printf("%s [%lf, %lf, %lf]\n", prefix, p->x, p->y, p->z);
}

t_p3 rotate_vector(const t_p3 *vector, double theta, double phi) {

    t_p3 result;

    double r = sqrt(vector->x * vector->x + vector->y * vector->y + vector->z * vector->z);
    double current_theta = atan2(vector->y, vector->x);
    double current_phi = acos(vector->z / r);
    double new_theta = current_theta + theta;

    double new_phi = current_phi + phi;

    result.x = r * sin(new_theta) * cos(new_phi);
    result.y = r * sin(new_theta) * sin(new_phi);
    result.z = r * cos(new_theta);
    
    return result;
}


int main() {
    t_p3 original_vector = {1, 1, 0};
    
  
    double theta = 0.0;
    double phi = 0.0;

    t_p3 rotated_vector = rotate_vector(&original_vector, theta, phi);

    print_p3("Original Vector: ",&original_vector);
    print_p3("Rotated Vector: ", &rotated_vector);
    
    return 0;
}

字符串
原始向量:[1.000000,1.000000,0.000000]
旋转向量:[0.000000,1.000000,1.000000]
即使theta和phi都设置为0,我也希望结果与原始矢量相同,但事实并非如此。此外,在其他Angular 旋转不会产生预期的结果。
请帮助我确定我可能错过了什么。
祝所有读到这篇文章的人新年快乐!”

2fjabf4q

2fjabf4q1#

在函数rotate_vector()中,new_phinew_theta的用法颠倒了。
current_theta是与x轴的Angular ,current_phi是与z轴的Angular 。
交换一下应该是

result.x = r * sin(new_phi) * cos(new_theta);
result.y = r * sin(new_phi) * sin(new_theta);
result.z = r * cos(new_phi);

字符串
程序输出为

Original Vector:  [1.000000, 1.000000, 0.000000]
Rotated Vector:  [1.000000, 1.000000, 0.000000]

gwo2fgha

gwo2fgha2#

注意acos(vector->z / r);有风险。

  • r可以是0。如果所有矢量分量幅度都小于sqrt(DBL_TRUE_MIN),则容易发生这种情况。
  • fabs(vector->z / r)可能略高于1.0,这是由于与预期数学不同的计算问题,并导致从acos(slightly more than 1)变为NAN

一些缓解措施:

//double current_phi = acos(vector->z / r);
double current_phi;
if (r == 0.0) {
  current_phi = 0.0;
} else {
  double ratio = vector->z / r;
  if (fabs(ratio > 1.0)) {
    ratio = copysign(1.0, vector->z);
  }
  current_phi = acos(ratio);
}

字符串

相关问题