我有一个沿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页面我理解:
[Ignacio Vazquez-Abrams编辑]
phi =&gt;绕Z轴的角度
theta =&gt; x / y平面之间的角度
但是如何找到Y?或者我需要吗?
真正的问题是,我如何用glRotatef(...)
?
答案 0 :(得分:1)
θ是XY平面上方的角度。 Phi是围绕Z轴的角度。通常,n维中的极坐标具有n-1个角度分量和1个半径分量。
答案 1 :(得分:0)
我在这个问题上花了 3 天多的时间,然后我来到了这个: 如果你有 vector3 f.e.比你能找到的粒子速度 角度 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;
}