- Home /
Too subjective and argumentative
Get angle between a vector and horizon (x,z plane)
So, I have a Vector3 vector v and I need to get the angle phi (in degrees) between it and the horizon (x,z plane). Obviously the correct way to do it would be to get v projection in x,z plane (Vector2(v.x , v.z)) and then calculate the angle between those 2 vectors.
However, the way I do it right now is:
float phi = Mathf.Asin(v.y / v.magnitude) * Mathf.Rad2Deg;
Height of a right-angle triangle divided by its hypotenuse equals sin of angle at its base. So, the angle at its base equals arcsin of height divided by hypotenuse.
Of course it gives an error when v.magnitude = 0.
So, I am asking, is there any better method of doing this?
So you are looking to get the angle between a vector and a surfaces tangent.
So first you need to define your plane?
How are you defining it? Is it a mesh? Is it a collection of Vector3s ($$anonymous$$imum of 3)?
I don't know how else would you call it than horizon. It is the world's x,z plane, so there is no use in defining it as all Vector3s (in world space) are alligned (grid wise) with it. If it helps you understand than those 3 points (for defining a plane) in world space would be (1,0,0), (1,0,1), (0,0,1) (notice that y=const).
:) So you are going on the worlds horizontal plane you aren't needing to compensate for a variable horizon ok thats pretty straight forward then.
Im just cooking dinner but if it hasnet been answered by the time I get back I will.
Not sure but: your post is a bit contradicting.... you want the angle between a vector and a plane. But this angle will never be more or less then 90° since a plane only has a normal but no orientation. If you need 360° of angles then you need the angle between v and a vector, not a plane.
try to clear this up.
I guess it really doesn't matter if it has a range from -90 to 90 rather than -180 to 180. At least not for what I need it for (or so I think). The method of using 2 vectors would make more sense (as I have already mentioned in the question), but Vector3.Angle only returns positive values (but I also need negative ones).
Ins$$anonymous$$d of v.y / v.magnitude
, you could use v.normalized.y
, which avoids the hassle of try-catching yourself the error of a division by 0.
Answer by sacredgeometry · Aug 18, 2019 at 07:47 PM
This will get you the angle off level with the horizontal. with perfectly upright being 0 and upside down being 180. Does this meet your requirements?
void Update()
{
Debug.Log(GetHorizonAngle());
}
float GetHorizonAngle()
{
return Math.Abs(Vector3.SignedAngle(Vector3.up, transform.up, transform.forward));
}
Note:
If you want it to start at 90 at the poles are reduce to 0 as you rotate closer to the horizon you can do this instead:
Math.Abs(Vector3.SignedAngle(Vector3.up, transform.up, transform.forward) - 90.0f);
Unfortunately can't accept your answer since you use transform ins$$anonymous$$d of a given Vector3 (in my case I am doing physics calculations, so there is no transform, but only one Vector3).
And if I try to make it work with what I have:
// v - previously precalculated Vector3
phi = Vector3.SignedAngle(v, new Vector3(v.x, 0, v.z), Quaternion.AxisAngle(90, Vector3.up) * new Vector3(v.x, 0, v.z))
I don't think it is any better way of doing it than what I am already doing.
Another thing is that I don't understand why you use Vector3.SignedAngle ins$$anonymous$$d of Vector3.Angle if you are ignoring negative values anyway.
To make myself clear, you can only use one Vector3, the value (angle) should be 0 when parallel to the horizon, positive when looking upwards from horizon and negative when looking downwards to horizon. Also the method should be more efficient or equivalent to the one I am currently using (arcsin of v.y / v.magnitude).
transform.up and transform.forward are vectors. i.e they are the forward and up vectors of the thing you are testing against the horizon.
Imagine that all you have is one Vector3 (forget about any gameobjects!!!). There is no such thing as Vector3.transform, so, where would you get the transform from? YOU DON'T! As I already explained, I am using this for physics, meaning THERE IS NO transform or it is not relevant (it has nothing to do with) to the vector.