Search code examples
vector3dgml

Convert a 3D vector into 2 angles


This is the exact thing I want: 3D Vector defined by 2 angles except reverse.

I want to go from 6 points (a 3D vector) to 2 angles (yaw and pitch. roll isn't necessary.)

Can anyone help? I'm not using a programming language anyone would know. It's GML, in GameMaker: Studio (yoyogames.com). I have a script that converts the mouse coordinates into a 3D vector from the camera position, and to convert that into directions, I started working it out.

I have the perfect code for yaw, but I can't figure out how to find the pitch. This is the code if you can understand it:

{
var mm,dX,dY,dZ,uX,uY,uZ,vX,vY,vZ,mX,mY,mZ, width, height, tFOV;
dX = argument3-argument0;
dY = argument4-argument1;
dZ = argument5-argument2;
mm = sqrt(dX*dX+dY*dY+dZ*dZ);
dX /= mm;
dY /= mm;
dZ /= mm;
uX = argument6;
uY = argument7;
uZ = argument8;
mm = uX*dX+uY*dY+uZ*dZ;
uX -= mm*dX;
uY -= mm*dY;
uZ -= mm*dZ
mm = sqrt(uX*uX+uY*uY+uZ*uZ);
uX /= mm;
uY /= mm;
uZ /= mm;
// v = u x d
vX = uY*dZ-dY*uZ;
vY = uZ*dX-dZ*uX;
vZ = uX*dY-dX*uY;
tFOV = tan(argument9*pi/360);
uX *= tFOV;
uY *= tFOV;
uZ *= tFOV;
vX *= tFOV*argument10;
vY *= tFOV*argument10;
vZ *= tFOV*argument10;
width = window_get_width();
height = window_get_height();
mX = dX+uX*(1-2*mouse_y/height)+vX*(2*mouse_x/width-1);
mY = dY+uY*(1-2*mouse_y/height)+vY*(2*mouse_x/width-1);
mZ = dZ+uZ*(1-2*mouse_y/height)+vZ*(2*mouse_x/width-1);
mm = sqrt(mX*mX+mY*mY+mZ*mZ);
global.mouse_dx = mX/mm;
global.mouse_dy = mY/mm;
global.mouse_dz = mZ/mm;
global.mouse_yaw = point_direction(0,0,global.mouse_dx,global.mouse_dy);
global.mouse_pitch = point_direction(0,0,dcos(global.mouse_dy),global.mouse_dz);
}

The only thing wrong with this is the

global.mouse_pitch = point_direction(0,0,dcos(global.mouse_dy),global.mouse_dz);

is wrong.

Some GML background: -dcos is used instead of cos, because dcos uses degrees while cos uses radians. -point_direction returns the direction between 2 coordinates (x1,y1,x2,y2) -sqrt returns the square root of a value -This is a script that uses 11 arguments. The arguments, in order, are:

xfrom, yfrom, zfrom, xto, yto, zto, xup, yup, zup, angle, aspect

from values are camera coordinates. to values are the coordinates of where the camera is looking. up values represent the 3D vector of "up" in 3D space. In my case, I use 0,0,1, so that positive z values are up. angle is the Field of View. aspect is the Aspect Ratio of the window.

I worked in paint for a while. I'll post what I did in paint: 2 perfect angle spheres and a sphere of the other 2 combined


Solution

  • yaw = atan(y/x)
    pitch = atan(z/sqrt(x^2+y^2))
    

    That is using one convention for the definition of x, y, z, pitch and yaw, and sure enough it turns 3 coordinates into two angles. If it doesn't work for you -- and it probably won't -- then you must put some more effort into understanding the mathematics involved and defining what you're trying to do.

    EDIT: To use the convention of the other question you cite,

    alpha = atan(z/x)
    beta = atan(y/z)