2
\$\begingroup\$

The two angles from the polar coordinate system are defined as hRotation and vRotation

This is how they are converted from polar to cartesian:

    // Get the distance between the object and the camera
    float distance = cam.getLocation().distance(RotationTarget);

    Vector3f pos = new Vector3f(distance * FastMath.sin(vRotation) * FastMath.cos(hRotation),
                                distance * FastMath.cos(vRotation),
                                distance * FastMath.sin(vRotation) * FastMath.sin(hRotation));

    // Add in the objects position to make the new relative position of the camera
    pos = pos.add(RotationTarget);
    cam.setLocation(pos);

Now the problem is when I try to get hRotation and vRotation from cartesian coordinates for the to initialize hRotation and vRotation, rather than setting them to an arbitrary value and having the camera jump each time. The camera is generally free roaming "a fly cam" but when an object is selected, the user can hold shift to rotate the camera around the object. So I need to base hRotation and vRotation off of the coordinates of camera and object, here is my code so far, but the issue is that the Camera will mirror its rotation rather than allowing me to fully rotate. For instance I can rotate to the left but it snaps to opposite angle from the right. I know I probably need to invert the angle when something is less than something, but I can't figure out what it is...

    float distance = cam.getLocation().distance(RotationTarget);

    Vector3f diff = cam.getLocation().subtract(RotationTarget);

    vRotation = FastMath.acos(diff.y / distance);
    hRotation = FastMath.asin(diff.z / FastMath.sqrt((diff.x * diff.x) + (diff.z * diff.z)));

Thanks, -Tim

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

By using acos you are limiting vRotation to the range [0,pi], and by using asin you are limiting hRotation to the range [-pi/2, pi/2]. In other words, you are only able to get half the period of the trig functions in each case. To fix this you need to check some cases (CAST rule).

\$\endgroup\$
0
\$\begingroup\$

Thanks for the help! I finally got it to work the way I wanted. Here is the code:

    float distance = cam.getLocation().distance(RotationTarget);
    Vector3f diff = cam.getLocation().subtract(RotationTarget);

    vRotation = FastMath.acos(diff.y / distance);
    hRotation = FastMath.acos(diff.x / FastMath.sqrt((diff.x * diff.x) + (diff.z * diff.z)));
    if (diff.z < 0)
        hRotation = -hRotation;
\$\endgroup\$

You must log in to answer this question.