Why does this work? - camera rotation from screen space

I do not understand the math behind the linked function or why it works. I would like to know this.

https://sidvind.com/wiki/Yaw,_pitch,_roll_camera

void Camera::motion(int x,int y){
theta+= x / 200;        /* Adjust this to control the sensitivity */
phi+= y / 200;

target.x = cos(theta) * sin(phi);
target.y = cos(phi);
target.z = sin(theta) * sin(phi);
}

• what parts don't you understand? – ratchet freak Apr 19 '18 at 14:07
• @ratchetfreak I understand the passed arguments are the change in x and y. I understand the sensitivity. I understand the target is a forward vector. I dont understand the cos/sin calculations – tester Apr 19 '18 at 14:41

This is simply converting the input angles theta & phi in spherical coordinates to a vector in Cartesian coordinates.

Think back to high school math & studying the unit circle. From that we know that:

$$\vec p = \left(cos(\theta), sin(\theta)\right)$$

Gives us a vector on a circle with radius 1, an angle of $\theta$ counter-clockwise from the positive x-axis.

That explains the first term of the x and z formulas. If sin(phi) == 1 then these formulas would just trace out a circle with radius 1 about the origin in the xz (horizontal) plane, giving us our yaw behaviour, so our camera can look 360 degrees side to side.

Now we need to handle looking up or down off that horizontal plane. That's where phi comes in. It measures how far we've pitched down from the positive y-axis (this is a slightly unusual parametrization - usually I see pitch measured plus/minus from the horizontal plane, but the math is similar either way)

When phi is 90 degrees, we're looking at a right angle to the vertical axis, ie. we're facing out directly along the horizontal plane. So it makes sense then that at this point sin(phi) == 1 so we get the full unit circle of movement from x & z, and cos(phi) == 0 so the y component of our unit vector is zero.

As we pitch up or down, the y component of the vector changes, from cos(0°) == 1 when we're looking straight up, to cos(180°) == -1 when we're looking straight down.

The x & z components have to change too though. As we slide the xz plane up & down the unit sphere, the radius of the circle intersecting that plane shrinks and shrinks until it becomes a point at either pole. That's the job the * sin(phi) term is doing: scaling back the xz extent of our vector as the y extent grows, so that it remains a unit vector throughout.