/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }