medihack
medihack

Reputation: 16627

Bring point to nearest camera position by camera rotation

I have a scene in Three.js (r67) with a camera that is controlled by OrbitControls.

If I now select an arbitrary point (Vector3) in the scene, what would be the best way to bring this point (programmatically) to the nearest camera position just by rotating the camera?


Example Scenario

In the below picture the left side is the starting point. The camera rotates around the green sphere (like OrbitControls) where the center of the camera is the center of the sphere. I now like to automatically rotate the camera around the sphere (doing the minimum amount of moves) so that the red box is nearest to the camera (like on the right side). enter image description here

Upvotes: 1

Views: 870

Answers (3)

Diwakar upadhyay
Diwakar upadhyay

Reputation: 434

Hi Dear please follow this Independntly to the method of selecting the point in the scene, there's several understanding to what you mean by "bringing camera just by rotating". I suppose, You want to rotate the camera in the way, to make the selected point in the center of the screen. This is simple:

camera.lookAt(your_point_in_scene);

You could do this more complicated. Firstly, find the current pointing vector. By default camera looks in direction Vector(0,0,1). When we rotate it in the same rotation as a camera, we will have camera direction:

var vec = new THREE.Vector3(0,0,1);
vec.applyQuaternion(camera.rotation._quaternion);

Now we must determine angle to rotate our camera, and axis, around which we would rotate. Axis of rotation could be found as a cross product of camera direction and vector from camera to object. Angle could be extracted from dot product:

var object_dir = object_world_point.clone().sub(camera.position);
var axis = vec.clone().crossProduct(object_dir);
var angle = Math.acos( vec.clone().dot(object_dir) / vec.length() / object_dir.length());

Upvotes: 0

Vasiliy Stavenko
Vasiliy Stavenko

Reputation: 1214

Independntly to the method of selecting the point in the scene, there's several understanding to what you mean by "bringing camera just by rotating".

I suppose, You want to rotate the camera in the way, to make the selected point in the center of the screen.

This is simple:

camera.lookAt(your_point_in_scene);

You could do this more complicated. Firstly, find the current pointing vector. By default camera looks in direction Vector(0,0,1). When we rotate it in the same rotation as a camera, we will have camera direction:

var vec = new THREE.Vector3(0,0,1);
vec.applyQuaternion(camera.rotation._quaternion);

Now we must determine angle to rotate our camera, and axis, around which we would rotate. Axis of rotation could be found as a cross product of camera direction and vector from camera to object. Angel could be extracted from dot product:

var object_dir = object_world_point.clone().sub(camera.position);
var axis = vec.clone().crossProduct(object_dir);
var angle = Math.acos( vec.clone().dot(object_dir) / vec.length() / object_dir.length());

Having angle and axis, we could rotate camera:

camera.rotateOnAxis(axis, angle);

Or, if you want to make it smooth:

// before animation started
var total_rotation = 0, 
    rotateon,
    avel = 0.01; // 0.01 radian per second    


if(total_rotation < angle){
  rotateon = avel * time_delta;
  camera.rotateOnAxis(axis, angle);
  total_rotation += rotateon;
}

Upvotes: 2

Doidel
Doidel

Reputation: 1779

Well that's not hard Oo You have a center/target point for the camera. You calculate the difference from the target position to the point position and normalize that vector to the length of the camera-centerpoint-distance (i.e. something like pointdistance.multiplyScalar(cameradistance.length() / pointdistance.length()) ).

And that's it. If I understood your question correctly. All you do is "extend" the point's positioni onto your "camera movement dome" and then you have the ideal new camera position. The camera's rotation is done automatic since you always target the center point.

Aaand if you want to smoothen the camera movement a bit you can just interpolate the angle (not the positions directly) with e.g. an exponential function, whatever you prefer.

Upvotes: 1

Related Questions