Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Feedback Quaternion * operator docs misleading for edge cases

Discussion in 'Scripting' started by the80srobot, Sep 5, 2020.

  1. the80srobot

    the80srobot

    Joined:
    Apr 5, 2020
    Posts:
    47
    Maybe I'm reading this differently from most people, but this sentence in the Quaternion docs strikes me as wrong:

    "Rotating by the product lhs * rhs is the same as applying the two rotations in sequence: lhs first and then rhs, relative to the reference frame resulting from lhs rotation."

    This isn't true for all values of lhs and rhs. At least if either side is {0,0,0,0}, then the product will also be {0,0,0,0}.

    I also wonder if it's true when the values aren't normalized between multiplications - it seems like precision errors would add up, resulting in a different final rotation.

    Should the docs instead say "For non-zero values, rotating by the product of lhs * rhs..." ?

    I am not just being pedantic here, the quaternions being {0,0,0,0} is a common error - uninitialized quaternions look fine in the editor and can be used without warnings in many contexts where you should be using the identity. It is not immediately obvious that the default value of a quaternion is not identity. Adding those three words would have saved me about 30 minutes of debugging.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    I take it you voiced your concerns in the link at the bottom of the documentation page? Posting it here is basically a no-operation... post it instead where Unity might see it and could consider it.
     
  3. the80srobot

    the80srobot

    Joined:
    Apr 5, 2020
    Posts:
    47
    Ah, I didn’t see that link. Thanks.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    There's some messiness originating from the fact that quaternions are this general mathematical object that's like a special 4-vector, but the only reason that Unity is interested in them is that a specific subset of quaternions are a convenient way of representing 3D orientations. So lots of stuff assumes that you are only using that subset of quaternions, and tells you things that are true in that context but not necessarily true of quaternions in general.

    I can kind of understand how making that caveat explicit in the documentation for (basically) every page that involves quaternions could get pretty tiresome.

    If Quaternion were a class, I would say it was irresponsible for the default constructor to return a value that is not part of that special subset. But since Quaternion is a C# struct, there's no choice: the language doesn't allow a default constructor that returns anything other than zeroes.

    As a general rule, I suggest that you explicitly initialize all your variables except where you can prove that doing otherwise is both safe and more efficient.
     
    Last edited: Sep 6, 2020
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Amen, brother Stone. Keep your bytes defined.
     
  6. the80srobot

    the80srobot

    Joined:
    Apr 5, 2020
    Posts:
    47
    If we're talking about this, I wish C# were less schizophrenic about initialization. Either make zero values idiomatic, like Go does, or go to greater lengths to stop people using uninitialized memory, like Rust or (in its weird, messed up way) C++.

    In particular, a common way I've seen a zero quaternion introduced is by having a public member variable that looks like identity when seen from the Editor, but is in fact {0,0,0,0}. If the language made a coherent decision about this stuff, it wouldn't be a problem, because either the Editor code would be forced to make a decision about the default value, or the zero value wouldn't be unexpected.
     
  7. the80srobot

    the80srobot

    Joined:
    Apr 5, 2020
    Posts:
    47
    Maybe to be explicit, I of course see what you mean and 100% agree. I just like pontificating about language design/
     
  8. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    That kinda sounds to me like a problem with the editor rather than the language (displaying something as identity when it's not).
     
    PraetorBlue and lordofduct like this.
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Agreed.

    OP's issue with the quaternion * operation is the same as if you divided by 0 and got a wacky result. Yeah... the documentation may not explicitly tell you to not multiply by a 0 quaternion, but they wouldn't expect you to have a zero quaternion.

    The fact the editor defaults to a zero quaternion is the primary issue here. And honestly I bet it's because they probably don't expect people to have a quat as a public field showing up in the inspector. They don't even draw the inspector as a sensible rotation value but as the x,y,z,w values... which aren't exactly human readable (unless your'e VERY hip to maths, in which case, you would have seen this issue from 100 miles away).

    I get the feels that Unity expects people to use Vector3's in the inspector for euler angles, and then call Quaternion.Euler to convert those euler angles from the inspector into an actual quat for multiplication. At which point the euler <0,0,0> would result in the quat <0,0,0,1>, because that's the equivalent quat.

    Unity could easily resolve this issue by having a propertydrawer for Quaternion that drew it as an euler rotation. Which is what I do with my own attribute/propertydrawer.

    But yeah, sounds more like an inspector issue.
     
  10. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,004
    Using the link at the bottom of the documentation will reliably get nothing done at all, other than waste your time.
     
  11. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    I don't see any issue with the documentation. Unity is not responsible to explain how quaternions work. Quaternions are just an extension of complex numbers. However pure rotations are represented by unit quaternions. (0,0,0,0) is not a unit quaternion and therefore not a valid rotation. Though that doesn't mean it's an invalid quaternion. Like lordofduct said the issue is mainly a misuse of the quaternion. Just like it should be obvious that when a direction vector is expected, passing (0,0,0) as direction is not valid as it's not a valid direction. Unity uses quaternions only for rotations, so any other usages are kinda irrelevant.

    Many people often say that you don't have to understand "X" in order to use "X" and I do partially agree with this statement. However not understanding the technology you're using just leads to misunderstandings like this. Also understanding the underlying logic makes it much simpler to remember the basics. Some people really try to remember how to multiply two complex numbers or two quaternions or how to rotate a point using a quaternion. However just knowing the rules is enough to derive the actual formula at any time. So just by remembering the basic rules that are explained here, I can derive how to rotate a point by a quaternion just by following those rules. I actually did this over here some time ago. When you actually understand the concept, you have to remember a lot less in the long run.

    Like lordofduct said, no one will explicitly tell you that multiplying a number by zero makes the result zero. That should be obvious. In the end a quaternion is just a number, a four dimensional number and it's actually an extension of the normal real numbers. So while it's not necessary to fully understand them in all details, a bit of background information helps a lot to avoid confusions like that.
     
    Kurt-Dekker likes this.