Averaging Quaternions in a List

ok , so this seems to be non trivial from my brief research.
There is a proposed solution here which in turn links to a wiki listing which links to a NASA paper!

In the following code I am averaging both position and rotation in my Update method
The position averaging is working
The rotation averaging is not

        List<Vector3> posList = new List<Vector3>();
        private Vector3 posAverage;
        private Vector3 newPos;

        List<Quaternion> rotList= new List<Quaternion>();
        private Quaternion rotAverage;

        private Quaternion newRot;

        //Global variable which holds the amount of rotations which
        //need to be averaged.
        int addAmount = 0;

        //Global variable which represents the additive quaternion
        Quaternion addedRotation = Quaternion.identity;

        //The averaged rotational value
        Quaternion averageRotation;

 void Update()
        {
        //target is a reference to another GameObject I am following
         //newRot is a global Vector3
        //newRot is a global Quaternion
        //posList is a global List of Vector3 objects
            Vector3 targetPosition = target.TransformPoint(new Vector3(0, 0, 0));
            newPos = targetPosition;

           newRot= target.transform.rotation;

            if (posList.Count >= 10)
            {
       
                posAverage = new Vector3(posList.Average(x => x.x), posList.Average(x => x.y), posList.Average(x => x.z));

                //Loop through all the rotational values.
                foreach (Quaternion singleRotation in rotList)
                {

                    //Temporary values
                    float w;
                    float x;
                    float y;
                    float z;

                    //Amount of separate rotational values so far
                    addAmount++;

                    float addDet = 1.0f / (float)addAmount;
                    addedRotation.w += singleRotation.w;
                    w = addedRotation.w * addDet;
                    addedRotation.x += singleRotation.x;
                    x = addedRotation.x * addDet;
                    addedRotation.y += singleRotation.y;
                    y = addedRotation.y * addDet;
                    addedRotation.z += singleRotation.z;
                    z = addedRotation.z * addDet;

                    //Normalize. Note: experiment to see whether you
                    //can skip this step.
           
                    float D = 1.0f / (w * w + x * x + y * y + z * z);
                    w *= D;
                    x *= D;
                    y *= D;
                    z *= D;
                    //The result is valid right away, without
                    //first going through the entire array.
                    averageRotation = new Quaternion(x, y, z, w);
                }


                posList.RemoveAt(0);
                rotList.RemoveAt(0);
            }

   

                posList.Add(newPos);
                rotList.Add(newRot);

                transform.position = posAverage;

                transform.rotation = averageRotation;
        
 
        }

With every loop (line 38) you write over the value of average rotation, without using it for anything
You never reset the value of addAmount between frames

What does average rotation actually mean? Averaging out the components of a quarternion won’t give you anything useful.

Not 100% sure what an average of rotations should mean, but I think your best case is to average the eulerAngles of your rotations. So if object1 is rotated 90 about the y-axis, object 2 is rotated -30 about y-Axis and object 3 has 0 y-rotation your average will be +40 rotation around Y. The quaternions themselves are weird beasties and the x,y,z,w are probably not what you think they are. As @Kiwasi pointed out they won’t give you anything useful averaging them.

You could do it with this code:

void Update()
{
    //target is a reference to another GameObject I am following
    //newRot is a global Vector3
    //newRot is a global Quaternion
    //posList is a global List of Vector3 objects
    Vector3 targetPosition = target.TransformPoint(new Vector3(0, 0, 0));
    newPos = targetPosition;

    newRot = target.transform.rotation;

    if (posList.Count >= 10)
    {

        posAverage = new Vector3(posList.Average(x => x.x), posList.Average(x => x.y), posList.Average(x => x.z));


        //Temporary values
        //declare these outside the loop so we can use them after

        float x = 0;
        float y = 0;
        float z = 0;

        //Loop through all the rotational values.
        foreach (Quaternion singleRotation in rotList)
        {
            x += singleRotation.eulerAngles.x;
            y += singleRotation.eulerAngles.y;
            z += singleRotation.eulerAngles.z;
        }

        x /= (float)(rotList.Count);
        y /= (float)(rotList.Count);
        z /= (float)(rotList.Count);
        Vector3 averageEuler = new Vector3(x, y, z);
        averageRotation = Quaternion.Euler(averageEuler);
       
        // not sure what this code was for leaving it alone
        posList.RemoveAt(0);
        rotList.RemoveAt(0);
    }


    // or this code
    posList.Add(newPos);
    rotList.Add(newRot);

    // Also these 2 lines seem ok IF you calculated them in if statement
    // what happens when posList.Count < 10 ???
    transform.position = posAverage;
    transform.rotation = averageRotation;


}

I point it out in the comment in the code… but both the posAverage, and averageRotation are only calculated if PosList.Count > 10. What happens if its < 10? Your still assigning your transform to those variables without them being set to anything.