【问题标题】:OpenGL direction of a vector in degrees (X, Y, Z)以度为单位的向量的 OpenGL 方向(X、Y、Z)
【发布时间】:2021-03-19 04:30:30
【问题描述】:

我有一个对象沿 X、Y、Z 方向的 3D 向量行进...我需要根据每个轴(x 轴、y 轴和 z 轴)旋转对象。

我如何获得这些度数?

(我正在使用 OpenGL,只知道 glRotatef(...))[glRotatef(...) 文档 here] this的问题,答案给了

viewvector =<x, y, z>

r = sqrt(x² + y² + z²)

phi = arctan2(y, x)

theta = arccos(z / r)

但从this wiki 页面我了解到:

[伊格纳西奥·巴斯克斯-艾布拉姆斯编辑]

phi => 围绕 Z 轴的角度

theta => x/y 平面之间的角度

但是我如何找到 Y?还是我需要?

真正的问题是,我如何用glRotatef(...) 来表示它?

【问题讨论】:

  • 第三个角度是任意的,因为它不影响行进方向。如果你想强制一个特定的值,你将需要另一个约束。
  • 所以如果我理解正确的话,glRotatef(theta, 1.0, 1.0, 0.0)glRotatef(phi, 0.0, 0.0, 1.0) 会起作用吗?
  • glRotatef(phi,0,0,1); glRotatef(theta,1,0,0);

标签: opengl vector trigonometry angle


【解决方案1】:

Theta 是 XY 平面上方的角度。 Phi 是围绕 Z 轴的角度。一般来说,n维极坐标有n-1个角度分量和1个半径分量。

【讨论】:

  • 感谢您的澄清 - 现在我如何让它用 glRotatef(...) 旋转它?
  • 首先,您不必担心 theta 和 phi,因为 glRotate*() 采用向量,而不是角度。至于卷,那是你需要自己决定的事情。
【解决方案2】:

我已经为这个问题花了 3 天多的时间,我得出了这个结论: 如果你有vector3 f.e.比你能找到的particle_velocity 角度 phi 和 theta,为什么需要这个角度 - 因为您可以沿速度矢量旋转顶点:

    float gaPhi(vec3 v1) {
       float r = length(v1);
       float phi = atan(v1.y / v1.x);
       return phi;
    }
    float gaTheta(vec3 v1) {
       float r = length(v1);
       float theta = acos(v1.z / r);
       return theta;
    }

    float rot_x = 0.0;
    float rot_y = gaTheta(vel) - pi/2;
    if (vel.x >= 0 && vel.y >= 0 && vel.z >= 0) {
       //ok
       rot_y = -rot_y;
    }
    if (vel.x < 0 && vel.y >= 0 && vel.z >= 0) {
       //ok
       rot_y = rot_y + pi;
    }
    if (vel.x >= 0 && vel.y < 0 && vel.z >= 0) {
       //ok
       rot_y = -rot_y;
    }
    if (vel.x >= 0 && vel.y >= 0 && vel.z < 0) {
       //ok
       rot_y = -rot_y; 
    }
    if (vel.x < 0 && vel.y < 0 && vel.z >= 0) {
       //ok
       rot_y = rot_y + pi;
    }
    if (vel.x >= 0 && vel.y < 0 && vel.z < 0) {
       //ok
       rot_y = -rot_y;
    }
    if (vel.x < 0 && vel.y >= 0 && vel.z < 0) {
       //ok
       rot_y = rot_y + pi;
    }
    if (vel.x < 0 && vel.y < 0 && vel.z < 0) {
       //ok
       rot_y = rot_y + pi;
    }
    
    float rot_z = -gaPhi(vel)  ;

glsl 顶点着色器:

layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texCoord;

uniform mat4 view; // camera view matrix
uniform mat4 proj; // camera projection matrix
uniform float time; // camera projection matrix

in float particle_radius; // particle radius
in float particle_mass; // particle mass
in vec3 particle_position; // particle position
in vec3 particle_velocity; // particle velocity

out vec2 frag_uv; // pass UV to fragment shader
out float frag_mass; // pass mass to fragment shader
out vec3 frag_velocity; // pass velocity to fragment shader
out vec4 texCoords; 


float gaPhi(vec3 v1) {
    float r = length(v1);
    float phi = atan(v1.y / v1.x);
    return phi;
}
float gaTheta(vec3 v1) {
    float r = length(v1);
    float theta = acos(v1.z / r);
    return theta;
}

void main() {
    frag_uv = texCoord; //sprite_uv;
    texCoords = vec4(texCoord, 0.0, 0.0);
    frag_mass = particle_mass;
    frag_velocity = particle_velocity;

    vec3 vert = vertex * max(10,min(100,particle_radius));
    vec3 vertn = normalize(vertex);
    float vertl = length(vert);
    vec3 vel =  particle_velocity;
    vec3 vel_dir =  normalize(particle_velocity);
    float pi = 3.14159265359;
    vec4 posnew = vec4(vert, 1.0);    

    float rot_x = 0.0;
    float rot_y = gaTheta(vel) - pi/2;
    if (vel.x >= 0 && vel.y >= 0 && vel.z >= 0) {
       //ok
       rot_y = -rot_y;
    }
    if (vel.x < 0 && vel.y >= 0 && vel.z >= 0) {
       //ok
       rot_y = rot_y + pi;
    }
    if (vel.x >= 0 && vel.y < 0 && vel.z >= 0) {
       //ok
       rot_y = -rot_y;
    }
    if (vel.x >= 0 && vel.y >= 0 && vel.z < 0) {
       //ok
       rot_y = -rot_y; 
    }
    if (vel.x < 0 && vel.y < 0 && vel.z >= 0) {
       //ok
       rot_y = rot_y + pi;
    }
    if (vel.x >= 0 && vel.y < 0 && vel.z < 0) {
       //ok
       rot_y = -rot_y;
    }
    if (vel.x < 0 && vel.y >= 0 && vel.z < 0) {
       //ok
       rot_y = rot_y + pi;
    }
    if (vel.x < 0 && vel.y < 0 && vel.z < 0) {
       //ok
       rot_y = rot_y + pi;
    }
    
    float rot_z = -gaPhi(vel)  ;

    mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0,
                    0.0,cos(rot_x),sin(rot_x), 0.0,
                    0.0,-sin(rot_x),cos(rot_x), 0.0,
                    0.0, 0.0, 0.0, 1.0);

    mat4 ry = mat4( cos(rot_y),0.0, -sin(rot_y), 0.0,
                    0.0, 1.0, 0.0, 0.0,
                    sin(rot_y), 0.0, cos(rot_y), 0.0,
                    0.0,0.0,0.0,1.0);
                   
    mat4 rz = mat4( cos(rot_z), sin(rot_z), 0.0, 0.0,
                   -sin(rot_z), cos(rot_z), 0.0, 0.0,
                   0.0        , 0.0       ,1.0 ,0.0,
                   0.0        , 0.0       ,0.0 ,1.0);  
                    
    posnew = posnew * rx * ry * rz;     
    vec4 pos = proj * view * vec4(posnew.xyz + particle_position, 1.0);

    gl_Position = pos;
}    

【讨论】:

    猜你喜欢
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 2021-07-20
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多