Example #1
0
        /// <inheritdoc />
        protected override bool Calculate(ReadOnlyArrayView <Body> bodies, ReadOnlyArrayView <int> indices, ArrayView <Vector3d> deltas)
        {
            int n = indices.Count;

            // check if sufficient number of bodies
            if (n < 3)
            {
                deltas.Clear();
                return(false);
            }

            var sum = new Vector3d();

            for (int i = 1; i < n; i++)
            {
                sum += bodies[indices[i]].Position.Current;
            }

            var t = 1.0 / (n - 1);
            var d = (sum * t - bodies[indices[0]].Position.Current) * 0.5;

            // apply projection to center
            deltas[0] = d;
            d        *= -t;

            // distribute reverse among 1 ring
            for (int i = 1; i < n; i++)
            {
                deltas[i] = d;
            }

            return(true);
        }
Example #2
0
        /// <inheritdoc />
        protected override bool Calculate(ReadOnlyArrayView <Body> bodies, ReadOnlyArrayView <int> indices, ArrayView <Vector3d> deltas)
        {
            int n = indices.Count;

            if (n < 4 || !Geometry.FitPlaneToPoints(Indices.Select(i => bodies[i].Position.Current), out Vector3d p, out Vector3d z))
            {
                deltas.Clear();
                return(false);
            }

            for (int i = 0; i < n; i++)
            {
                deltas[i] = Vector3d.Project(p - bodies[indices[i]].Position.Current, z);
            }

            return(true);
        }
Example #3
0
        /// <inheritdoc />
        protected override bool Calculate(ReadOnlyArrayView <Body> bodies, ReadOnlyArrayView <int> indices, ArrayView <Vector3d> deltas)
        {
            int n = indices.Count;

            if (n < 4 || !Geometry.FitSphereToPoints(Indices.Select(i => bodies[i].Position.Current), out Vector3d p, out double r))
            {
                deltas.Clear();
                return(false);
            }

            for (int i = 0; i < n; i++)
            {
                var d = p - bodies[indices[i]].Position.Current;
                deltas[i] = d * (1.0 - r / d.Length);
            }

            return(true);
        }
Example #4
0
        /// <inheritdoc />
        protected override bool Calculate(ReadOnlyArrayView <Body> bodies, ReadOnlyArrayView <int> indices, ArrayView <Vector3d> deltas)
        {
            int n = indices.Count;

            if (n < 2)
            {
                deltas.Clear();
                return(false);
            }

            var p = Indices.Select(i => bodies[i].Position.Current).Mean();

            for (int i = 0; i < n; i++)
            {
                deltas[i] = p - bodies[indices[i]].Position.Current;
            }

            return(true);
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bodies"></param>
        /// <param name="indices"></param>
        /// <param name="deltas"></param>
        /// <returns></returns>
        protected override bool Calculate(ReadOnlyArrayView <Body> bodies, ReadOnlyArrayView <int> indices, ArrayView <Vector3d> deltas)
        {
            int n = indices.Count;

            // check if sufficient number of bodies
            if (n < 4)
            {
                deltas.Clear();
                return(false);
            }

            var target = 0.0;

            // calculate target as mean length
            for (int i = 0; i < n; i += 2)
            {
                var d = bodies[indices[i + 1]].Position.Current - bodies[indices[i]].Position.Current;
                var m = d.Length;
                target += m;

                // cache to avoid redundant calcs
                deltas[i]       = d;
                deltas[i + 1].X = m;
            }

            target /= n >> 1;

            // calculate deltas
            for (int i = 0; i < n; i += 2)
            {
                var d = deltas[i];
                var m = deltas[i + 1].X;

                d            *= (1.0 - target / m) * 0.5;
                deltas[i]     = d;
                deltas[i + 1] = -d;
            }

            return(true);
        }