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. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Get average rotation from surrounding objects.

Discussion in 'Scripting' started by unity_BD1000D08C18D3028A82, Nov 23, 2022.

  1. unity_BD1000D08C18D3028A82

    unity_BD1000D08C18D3028A82

    Joined:
    Nov 16, 2022
    Posts:
    5
    I need to run through a list of objects, get the rotation of each one so I can calculate the average rotation of the group and then set that average to the main object, but I'm having a really hard time finding this value because I'm trying to convert the rotation to an Euler value and converting it back to Quaternion (which I think is impossible).

    Can someone help me find the average?

    here is a little piece of my code that is trying to set the rotation to the main object
    Code (CSharp):
    1.  
    2. foreach (GameObject boid in boidsHit)
    3.         {
    4.             avarage += boid.transform.rotation.z;
    5.         }
    6.  
    7.  avarage = avarage / boidsHit.Count;
    8.  transform.rotation = Quaternion.Euler(0,0,avarage);
    9.  
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    8,629
    The 2D forum isn't for solving general scripting issues whereas the Scripting forum is so I'll move your post there for you.

    Thanks.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    29,825
    The
    .z
    property of a Quaternion is not for you, unless you have a math degree and know what it is.

    It is NOT degrees, it is not anything useful to the average gamedev.

    Do you perhaps want the
    .eulerAngles.z
    property?

    Keep this in mind too:

    All about Euler angles and rotations, by StarManta:

    https://starmanta.gitbooks.io/unitytipsredux/content/second-question.html
     
    Bunny83 likes this.
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    2,435
    Correct. Though using euler angles for this also doesn't make much sense as you can not really get a proper average from angles like this. Imagine having several angles around the wrap-around point (either 0° and 360° or -180° and 180°). Say you have 178 + 176 + (-179), you would get a sum of 175. Divide it by 3 and you get 58.3 which is not even close to the actual average direction which is actually 178.33°. (2°+4° -1° == 5° divide by 3 and you get 1.666 off of 180°).

    Euler angles are not really good for such things as they wrap around and any angle has several representations. You can get the average by making sure they are all on the same side. So adding 360° to "-179" would give you 181°. Now the average would give you 178.33

    It's usually better to get the average of direction vectors. In 2d just using "right" or "forward" (depending on the layout) would be enough. Yes, adding vectors can also result in a degenerate case where the different directions perfectly cancel each other and you get 0. Though that's actually quite rare. For that 3 directions would need to be exactly 120° apart or 4 directions need to be 90° apart. So just sum the different direction vectors and normalize the vector. No need to divide by 3 (or the boid count) as the normalization is necessary anyways.
     
  5. AnimalMan

    AnimalMan

    Joined:
    Apr 1, 2018
    Posts:
    1,051
    Depends if you are working with 2D angle on one axis or not.
    Because if you already have measured your object rotation in 0-360 degrees wrap then you can do your average sum and divide by the count. But asking for the z is not always the same especially if it is at -180. You would probably want to deal with 360 limited facings for every object on your z axis.
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    2,435
    No, not really. Just imagine two angles 10° and 350°. Those two angles are 20° apart and the actual average is 0° or 360° However adding them gives you 360 dividing by 2 gives you 180°. It is technically between the two, but on the other side. Even worse with 3 angles. Imagine 355°, 359° and 7°. Those are all pointing in roughly the same direction. Though adding them and dividing by 3 gives you 240° instead of the actual average of 0.33°. So no, it does not work

    Note that any angle is a "2d" measurement, no matter if it's in 2d, 3d, 4d or 10d. That's because simple rotations always happen in a 2d plane. That's why 3d has 3x 2d planes while 4d space has 6x 2d planes (xy, xz, xw, yz, yw, zw)
     
    orionsyndrome likes this.
  7. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    2,173
    Exactly. And the situation where the directions would sum up to zero vector simply indicate that the average orientation/rotation was truly undefined. In that case it makes sense to forcefully apply a default value or to keep an identity.

    I mean what the average between two mirrors that face each other could ever be? It hurts my brain.

    There could be an artificial continuity, though, given some context. For example, if all objects must be rotated around the same axis, we can agree that the average rotation between two such mirrors should be something orthogonal to both of them, but that's just a convention.
     
    Last edited: Nov 24, 2022
    Bunny83 likes this.
  8. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    2,435
    Yes, with a usual boids / flocking simulation you usually take also other things into account like your current movement direction which you also should align with the average movement direction of the surrounding boids.
     
  9. AnimalMan

    AnimalMan

    Joined:
    Apr 1, 2018
    Posts:
    1,051
    PROTRACT.png

    45 + 180 + 270 = 495

    / 3 = 165
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    2,435
    First of all, why on earth do you use a GRAD (Gradian) scale? Almost nobody is using that besides surveyors. Apart from that, take your example. If you add the same amount to each angle, the average should offset by the exact same amount since the average should stay exactly at the same relative number. However, when one of the angles goes over "0", it jumps from 0 to 360 (or 400 in GRAD).

    So take your example, lets just subtract 20 from each angle, so we rotate all the angles by the same amount so we get:

    45 => 25
    180 => 160
    270 => 250

    We add them together: 25+160+250 == 435. We divide by 3 and get 435/3 == 145

    Of course 145 is exactly 165 - 20. As I said we just rotated the whole structure you had by 20° and we still get the same relative angle. Great. Now rotate by 55°

    45 => 490
    180 => 125
    270 => 215

    So again, add them up: 490 + 125 + 215 == 830. Divide by 3 and you get 276.666

    Of course 276.666 is not the expected 165 - 55 == 110, is it?

    It just doesn't work because of the wrap around nature of angles.
     
  11. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    2,173
    I also like to measure my angles in Furmans and strecks, I just find gradians too simplistic.
     
    Bunny83 likes this.
  12. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    2,435
    In the context of computer science that would even make a bit of sense :) For example when transmitting an angle over the network with just 16 bit. Though for most usecases a single byte is often enough :D
     
    orionsyndrome likes this.
  13. AnimalMan

    AnimalMan

    Joined:
    Apr 1, 2018
    Posts:
    1,051
    It really boils down to whether or not you need angle 45.9477f as an object facing. The last thing you want is two computers resulting different values from the same calculation.

    the trick with Euler is keeping the vector separate from the angle. And adding 1 to its x and y before making the Euler = that value. If you go about adding to your floating Euler then you will have floating variation.

    136FF346-DC38-42D1-B989-F82EFFFDA944.jpeg
     
    Last edited: Nov 24, 2022