예제 #1
0
        private static Quat SimpleAverage(Quat[] ndata)
        {
            Vector3F mean = new Vector3F(0, 0, 1);
            // using the directed normal ensures that the mean is
            // continually added to and never subtracted from
            Vector3F v = ndata[0].GetNormal();

            mean.Add(v);
            for (int i = ndata.Length; --i >= 0;)
            {
                mean.Add(ndata[i].GetNormalDirected(mean));
            }
            mean.Subtract(v);
            mean.Normalize();
            float f = 0;

            // the 3D projection of the quaternion is [sin(theta/2)]*n
            // so dotted with the normalized mean gets us an approximate average for sin(theta/2)
            for (int i = ndata.Length; --i >= 0;)
            {
                f += Math.Abs(ndata[i].Get3DProjection(v).Dot(mean));
            }
            if (f != 0)
            {
                mean.Scale(f / ndata.Length);
            }
            // now convert f to the corresponding cosine instead of sine
            f = (float)Math.Sqrt(1 - mean.NormSquared());
            if (float.IsNaN(f))
            {
                f = 0;
            }
            return(new Quat(new Vector4F(mean.x, mean.y, mean.z, f)));
        }
예제 #2
0
        private static Quat NewMean(Quat[] data, Quat mean)
        {
            Vector3F sum = new Vector3F();

            for (int i = data.Length; --i >= 0;)
            {
                Quat     q  = data[i];
                Quat     dq = q.Divide(mean);
                Vector3F v  = dq.GetNormal();
                v.Scale(dq.GetTheta());
                sum.Add(v);
            }
            sum.Scale(1f / data.Length);
            Quat dqMean = new Quat(sum, sum.Norm());

            return(dqMean.Multiply(mean));
        }