1

I am developing a javascript application in which it is possible to design your own closet. I want it to be possible to rotate the closet smoothly (without changing the distance from the camera to the closet). Normally it would be easiest to rotate the object itself, but that's not an option considering the different meshes have different origins (their relative (0,0) points are different from the global (0,0)). Instead, I figured I have to rotate the camera around the closet as if on a sphere. So what I want to do is calculate the exact position the camera needs to have based on any longitude and latitude (user input). As a result, the rotation is really odd. The application in its current state is here (important: doesn't work with IE, there will be a plugin in the future though). The relevant code is below. Note: I found these formulas online. I did the math myself several times and was able to confirm the formula's every time. The only thing I am pretty sure of is that the distance (radius) to the offset point (xOffset, yOffset, zOffset) is constant but the whole thing just rotates very oddly. I found another question like this here. I tried replacing my formula's with theirs (even though they don't make sense, although they seem to work for them) but that didn't help at all (rotations were still odd and the radius didn't even seem constant anymore).

Pseudo:

x = xOffset + radius * cos(longitude) * cos(latitude)
y = yOffset + radius * cos(longitude) * sin(latitude)
z = zOffset + radius * sin(longitude)
camera.lookAt(xOffset, yOffset, zOffset)

Relevant code (note: degrees are converted to radians):

var lon = 30;
var lat = -90;
var cameraRadius = 400;

function cameraReposition() {   
var lon = dimensions.lon;
var lat = dimensions.lat;
camera.position.x = cameraX + cameraRadius * Math.cos(Math.PI * lon / 180) * Math.cos(Math.PI * lat / 180);
camera.position.y = cameraY + cameraRadius * Math.cos(Math.PI * lon / 180) * Math.sin(Math.PI * lat / 180);
camera.position.z = cameraZ + cameraRadius * Math.sin(Math.PI * lon / 180); 
camera.lookAt(new THREE.Vector3(cameraX, cameraY, cameraZ));
}


$('#visiblecanvas').mousemove(function(e){
    if(mousedown || rightMousedown) {
        var clickX = e.pageX - this.offsetLeft;    
        var clickY = e.pageY - this.offsetLeft;
        lon += (clickY - lastY) / 10;
        lat -= (clickX - lastX) / 10;
        lastY = clickY;
        lastX = clickX;
        if (lon > 360)
            lon -= 360;
        if (lon < -360)
            lon += 360;
        if (lat > 360)
            lat -= 180;
        if (lat < -360)
            lat += 360;
    }
});

Another note: the way lon and lat are changed when they go past 360 is not very relevant right now as both lon and lat are controlled through the gui for now (for debugging purposes).

EDIT: Wrong link to the application! fixed.

Community
  • 1
  • 1
Zypp
  • 47
  • 2
  • 8

2 Answers2

4
    latLongToVector3: function(lat, lon, radius, heigth) {
      var phi = (lat)*Math.PI/180;
      var theta = (lon-180)*Math.PI/180;

      var x = -(radius+heigth) * Math.cos(phi) * Math.cos(theta);
      var y = (radius+heigth) * Math.sin(phi);
      var z = (radius+heigth) * Math.cos(phi) * Math.sin(theta);

      return new THREE.Vector3(x,y,z);
    }
1

The camera positioning looks OK to me, at least it follows the proper trajectories when either latitude or longitude is varied, while the other one is kept constant. What does look odd is the orientation of the camera -- lookAt doesn't specify where "up" is, so it can choose any orientation, e.g. you might end up looking at the right point, but upside down.

I haven't tried Three.js myself, but in the documentation I do not see the way to give that additional info to the camera. You might have to set the projectionMatrix and its inverse manually.

Qnan
  • 3,714
  • 18
  • 15
  • I simply added `camera.rotation.z = 0;`. This fixed the issue you mentioned but I'm still pretty sure the positioning is also broken.. – Zypp Jul 02 '12 at 10:06
  • Woops.. turns out that after all the experimenting I didn't have the correct formula's in there anymore, so it turns out your solution did work, I just didn't know it yet. Thanks! – Zypp Jul 02 '12 at 10:21