Search Unity

Trying to obtain angle to object via trigonometry

Discussion in 'Scripting' started by Deleted User, Sep 22, 2017.

  1. Deleted User

    Deleted User

    Guest

    Yes I'm trying some simple trig calculations to find the angle to an object but at some angles the object that is pointing at the target points slightly off center.

    Code (CSharp):
    1.  public GameObject target;
    2.     Vector3 i;
    3.  
    4.     void Update()
    5.     {
    6.         i = target.transform.position;
    7.         float elevation = Mathf.Atan(i.y / i.x) * Mathf.Rad2Deg;
    8.         print("x=\t" + elevation);
    9.         float rotation = Mathf.Acos(i.z / i.magnitude) * Mathf.Rad2Deg;
    10.         rotation *= Mathf.Sign(i.x);
    11.         print("y=\t" + rotation);
    12.         transform.eulerAngles = new Vector3(-elevation, rotation, 0f);
    13.     }
    I am not sure why this is. Maybe you have an idea??
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Try:

    Code (csharp):
    1.  
    2. i = target.transform.position;
    3.  
    4. float angle = Mathf.Atan2(i.y - transform.position.y, i.x - transform.position.x);
    5.  
    6. transform.eulerAngles = new Vector3(Mathf.Cos(angle) * Mathf.Rad2Deg, Mathf.Sin(angle) * Mathf.Rad2Deg, 0f);
    7.  
     
  3. Deleted User

    Deleted User

    Guest

    I appreciate the attempt at helping but I don't think you understand trigonometry.

    [edit] @GroZZleR Apologies. I was a confused. Did not mean to minimize your knowledge. You definitely understand trig. I'm not sure my problem was Gimbal lock either. I only just realized this morning that Quaternion.LookRotation() takes two direction vectors, not angular vectors.

    Rather misleading to call it LookRotation, because one would assume with the word "Rotation" means it deals with angles.
     
    Last edited by a moderator: Oct 1, 2017
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    Could you describe more plainly which two vectors you're trying to find the angle between? What kind of game is this, and what is the desired result?

    I can't do the math on paper, but there is more than likely a convenience function or two to handle the math, with simple inputs.

    Angle between forward axis and a target:
    Code (CSharp):
    1. Vector3 towardsTarget = target.position - transform.position;
    2.  
    3. float angle = Vector3.Angle(transform.forward, towardsTarget);
    maybe
    Code (CSharp):
    1. transform.LookAt(target.position);
    or
    Code (CSharp):
    1. transform.rotation = Quaternion.LookRotation(towardsTarget, Vector3.up);
     
  5. Deleted User

    Deleted User

    Guest

    I'm trying to write a simple turret aiming script that doesn't use Transform.LookAt(), because the objects don't behave the way I want them to with that method. The problem I've run in to with this code:

    Code (CSharp):
    1.         k = target.transform.position - transform.position;
    2.         rotation = Vector3.Angle(transform.forward, k);
    3.         transform.Rotate(0f, rotation, 0f);
    Is that it does find the proper angle but once its been set that angle is then zero (because the turret is pointing directly at it), so on next Update() it gets set to zero, causing some spastic repetitive behavior. I'm working to fix this, I know the problem but a solution eludes me.
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Code (csharp):
    1.  
    2. Vector3 k = target.transform.position - transform.position;
    3. k.y = 0f; //because it appears you only want horizontal rotation
    4. if (k.sqrMagnitude > 0.0001f)
    5. {
    6.     var targetRot = transform.rotation * Quaternion.FromToRotation(transform.forward, k);
    7.     transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRot, SpeedInDegreesPerSecond * Time.deltaTime);
    8. }
    9. else
    10. {
    11.     //target is above/below us... don't rotate
    12. }
    13.  
    Alternatively you can replace:
    Code (csharp):
    1. var targetRot = transform.rotation * Quaternion.FromToRotation(transform.forward, k);
    With:
    Code (csharp):
    1. var targetRot = Quaternion.LookRotation(k);
    They're effectively the same thing, considering that we're operating in a horizontal rotation. If you wanted free range rotation... i'd go with the former (hence why I showed that one in the initial example).
     
    JoeStrout likes this.
  7. Deleted User

    Deleted User

    Guest

    Thank you helping there lordofduct, and I found an equivalent solution to my trig formula one from the first post. The problem is with the eulerAngles I think. In both cases I set them to the rotation that should point the turret at the target object's transform, but when somewhere around 45 degrees on the X and 45 degrees on the Y, the aiming falls apart. The turret no longer looks directly at the transform.

    Such is the essence of the problem. I don't need a solution to aim the turret, I need to know why eulerAngles don't give me an exact aim.

    [edit] Let me explain a bit better. Near the horizontal plane (relative to the turret's perspective) the rotation works flawlessly. When combining vertical and horizontal euler angles, aiming falls off center. I need to know why this happens.
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I think it's because euler angles don't mean what you think they mean. You should almost never use them, except in restricted cases (such as keeping 2 of them at zero and assigning only the third, for rotation in one of the axis planes).
     
    lordofduct and LMan like this.
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    I don't know what exactly you mean... try giving us a visual of it? Maybe record it and post a video here.

    Furthermore, I'm with @JoeStrout, you may be confusing how euler angles works. And furthermore, in 3d, it's best to not use euler angles. I personally prefer Quaternions as they make more sense to me (they're essentially vectors, a quat represents direction and magnitude of rotation... which correlates nicely with my vector translation knowledge).
     
    JoeStrout likes this.
  10. Deleted User

    Deleted User

    Guest

    Yes I am aware of these things @JoeStrout in fact that's exactly what I'm doing (setting only two axes).

    Here's video:


    There is a very small red dot at center of screen and the sphere is slightly off center at a certain angle, around 0:08.
     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Can you share this stripped down project?

    Cause to me that red dot doesn't look to be in the center... but neither does the sphere (using a ruler held up to my monitor). The sphere is closer to center, but not perfect, the dot is way off center.
     
  12. Deleted User

    Deleted User

    Guest

    I've figured it out! The problem is gimbal lock. As my object approaches 90* on any axis, gimbal lock sets in causing them to be less and less accurate.
     
  13. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, that makes sense. (This is one of the reasons we advise never to use Euler angles, unless you're using only one of them for 2D rotation.)