How do you find the [weighted] average direction of many unit direction vectors?

I don’t think it can just be (sum weight[i]*vec[i])/(sum weight[i]) because the results may be non-normalized: e.g, if you have <1,0,0> and <0,1,0> and you average them with weights both 1, you get <.5,.5,0> which is non-unit

If it isn’t that though, would it perhaps be finding the yaw and pitch and averaging the angles and then converting back to a vector?

Couldn’t you just normalize the averaged vector?

2 Likes

I’m not sure if that’s right; though right now the only way I can think of seeing its correctness is if its results match with the converting to angles idea–but that assumes it is correct
Or could you explain why it is right? Normalizing the end result just seems like a hack to me…like lerping and normalizing vs slerping

You could separate vectors into their units and magnitudes and take their averages separately:

local Vectors = -- array of Vector3s

local unitAvg = Vector3.new()
local magAvg = 0
for _,v3 in ipairs(Vectors) do
	unitAvg = unitAvg + v3
	magAvg = magAvg + v3.Magnitude
end

unitAvg = unitAvg.Unit
magAvg = magAvg/#Vectors

local Average = unitAvg * magAvg

notice how you still have to do
unitAvg = unitAvg.Unit
because of cases such as my example in the OP

An example would be the unit circle, if you had 2 vectors <1, 0> and <0, 1>, the average would be <0.5, 0.5>, which isn’t unit. But then we can convert it by the following:

Get the length: 0.5^2 + 0.5^2 = 0.5
Compute the normal: <0.5/sqrt(0.5), 0.5/sqrt(0.5)> = <0.707, 0.707>

If you know the unit circle, you know that’s correct.

you can’t prove something with one example : /

1 Like

My point still stands because the formula returns it to .Unit regardless of what vectors you put in, and still accounts for the average magnitude.

I didn’t do this:

unitAvg = (unitAvg/#Vectors).Unit -- it would be useless anyway...

because I never took the average of that at all, .Unit just serves a completely different purpose of accounting only for the angle itself and never worrying about magnitude.

1 Like

Googling brings up this article:

Note that it describes converting angles to unit vectors (“points on the unit circle”), taking a regular (arithmetic) mean, and converting back to angles.

Which suggests that when you’re starting with unit direction vectors, just taking the unit of their mean is indeed the way to go.

5 Likes

Sorry, I did not read the code properly
I still want to understand why it would be correct though
edit: its still the same solution because multiplying by any constant before taking the magnitude (1/n to find the arithmetic mean) will not change the vector’s direction (or unit)

@sncplay42 It says it is a “reasonable” mean of the input angles, and there can sometimes be “no circular mean”
E.g: if you have <-1,0,0> and <1,0,0> then their mean is undefined but shouldn’t it be <0,1,0> or any vector orthogonal to both? Shouldn’t the average of direction unit vectors a and b be the same as a:slerp(b,weight[b]/(weight[a]+weight[b]))

What’s the angle between 0 degrees and 180 degrees? It could be either 90 degrees or 270 degrees. There’s multiple answers to this. In the case of two vectors facing opposite directions, there’s infinitely many.

You can’t slerp two vectors which face opposite directions! The result would also be undefined.

1 Like

I think “reasonable” might be being used here in a rigorous manner to mean “satisfies the expected properties”.

Intuitively that doesn’t really make sense to me that the average of “left” and “right” would be “up”. I think you’re going to have to deal with the situation where the sum is zero and it doesn’t really make sense for there to be an average.

1 Like

If there are multiple answers to one equation in math, that usually means it’s undefined. For example, 1/0 is undefined not because it is literally impossible to add up enough 0s to equal 1, that’s what infinity is for, but because there are multiple ways to answer it, that being that there are both the positive and negative ends of infinity to choose from, since 0 is the only non-positive and non-negative number in the real number set.
Similarly, the average of those two vectors would be undefined because there are an infinite amount of orthogonal vectors to choose from between the Y and Z axes, like <0,1,0>, <0,0.707, 0.707>, etc. On a 2D plane, there are just two, but it’s still multiple answers.

1 Like

From this site: https://brilliant.org/wiki/what-is-0-0/

Remember that a/b means “the number which when multiplied by b gives a.” For example, the reason 1/0 is undefined is because there is no number x such that 0⋅x=1

Infinite zeroes is still zero. 1/0 is undefined exactly because it is literally impossible to add up enough zeroes. A better example would be 0/0, since any number multiplied by zero is zero and it is also undefined.

edit: the site had weird formatting that turned 1/0 to 0/1

4 Likes