- Home /
Make my camera perpendicular to two objects
I'm trying to move my camera (A) in the middle and perpendicular to two objects (at C and D). I can find the midpoint in (B), but I can't get my mind around the math that is needed to rotate my camera to be facing the mid point (B) too.
Moving it to the middle is no problem, I can use this:
public static Vector3 GetMidPointBetweenTwoObjects(Vector3 sourceObject, Vector3 targetObject)
{
Vector3 result = new Vector3(0, 0, 0);
result.x = sourceObject.x + ((targetObject.x - sourceObject.x) / 2);
result.y = sourceObject.y + ((targetObject.y - sourceObject.y) / 2);
result.z = sourceObject.z + ((targetObject.z - sourceObject.z) / 2);
return result;
}
But how can I find the rotation for my camera at A, that is perpendicular to these two objects, for point B?
One problem with this problem as stated is that there are an infinite number of 'A' positions. That is, given an arbitrary vectors in 3D space, 'A' could wrap around the CD vector 360 degrees for any number of solutions. So you need some way of defining the plane where ABCD live. It may be this is really a 2D problem and therefore you know the plane, or you might define the plane by the camera and points C and D. Once you know the plane, take the normal of the plane and use Vector3.Cross() with the Vector BC or BD. The result will be the 90 degree vector you seek.
Answer by Tomer-Barkan · Oct 10, 2013 at 10:44 PM
To calculate the location in the middle, you can use Vector mathematics instead of doing it manually:
Vector3 result = sourceObject + (targetObject - sourceObject) / 2;
If you want to move it along the line towards A, simply rotate the vector between D and C left by 90 degrees, then add it to B.
Vector3 midCD = sourceObject + (targetObject - sourceObject) / 2;
Quaternion ninetyLeft = Quaternion.AngleAxis(90, Vector3.up); // to rotate 90 degrees left, rotate 90 degrees around the Y axis
Vector3 towardsA = (ninetyLeft * (targetObject - sourceObject)).normalized; // rotate the vector that points from C to D by 90 degrees left, then you get the vector that points from B to A. Normalize to make it of size 1.
Vector3 result = midCD + towardsA * distanceTowardsA;
Then to put the camera and make it face point B, you can use transform.position and
transform.LookAt()`:
transform.position = result;
transform.LookAt(midCD);
it's close, but there is something funky about the ninetyLeft rotation, it doesn't seem to appear 90 degrees all the time.
That doesn't make senses, must be something else... can you share your code and maybe screenshots of whats happening?
Oh, and I assumed that Y should always be 0 (ie I made the problem 2d). If it's not, then the answer might differ a bit, but then you have to explain how you want it to behave, because you didn't mention a 3rd dimension at all in your problem.
I guess that is it. It is 3d space. Here is my sandbox level.
You can see my two characters. The red dot is the mid point. The green dot, way in the distance in the spotlight is supposed to be A.
locations:
C: (0, 0.5, 10)
D: (0, 0.5, 5)
B: (0, 0.6, 7.5) [B Note: Interesting that B adds that 0.1 to Y...]
A: (-1, 0, 0) [A Note: I would have expected something at about (-1, 0.5, 7.5)
And here is my code:
public IEnumerator $$anonymous$$oveCameraInIsometricViewOverBetweenTwoObjects(Vector3 sourceLocation, Vector3 targetLocation)
{
//Get the midpoint
Vector3 midCD = sourceLocation + (targetLocation - sourceLocation) / 2;
//Create a red cube at the midCD point
CreateGameObjectAtLocation(midCD, Color.red);
// to rotate 90 degrees left, rotate 90 degrees around the Y axis
Quaternion ninetyLeft = Quaternion.AngleAxis(90, Vector3.up);
// rotate the vector that points from C to D by 90 degrees left, then you get the vector that points from B to A. Normalize to make it of size 1.
Vector3 towardsA = (ninetyLeft * (targetLocation - sourceLocation)).normalized;
//Create a green cube at the towardsA point
CreateGameObjectAtLocation(towardsA, Color.green);
}
lol, you used towardsA as the position for the new object. towardsA is the vector that points from B to A. So to get the position, you need to add it to B.
Notice that in my example, the result is not towardsA
, but midCD + towardsA
To fix, change line 15 to:
CreateGameObjectAtLocation(midCD + towardsA, Color.green);
And you should get exactly what you expect, (-1, 0.5, 7.5).
Answer by DaveA · Oct 10, 2013 at 10:22 PM
If you have B, and your camera is at A, then use transform.LookAt(B); in a script on the camera object.
Unfortunately this isn't quite what I'm looking for, as my camera isn't at A. If it was, you're right, it would be easy to just look.
Your answer
Follow this Question
Related Questions
Rotate camera 90 degrees from target, and follow ... demo not working properly 1 Answer
Solved | Rotating Object in Single Axis while staying Perpendicular to a Rotating Plane 1 Answer
Flip over an object (smooth transition) 3 Answers
Rotate object to lookAt point and be perpendicular to the ground 1 Answer
Changing the forward rotation for LookAt 2 Answers