# Get average rotation from surrounding objects.

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

1. ### 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.

### 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

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

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

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

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

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

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

Joined:
Apr 1, 2018
Posts:
1,051

45 + 180 + 270 = 495

/ 3 = 165

10. ### 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

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

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

orionsyndrome likes this.
13. ### 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.

Last edited: Nov 24, 2022