private void AddCollisionForce() { _points.Clear(); _nodes.Clear(); for (int i = 0; i < cells.Count; i++) { var p = cells[i]; _points.Add(new double[] { p.position.x, p.position.y, p.position.z }); _nodes.Add(i); } KDTree <double, int> tree = new KDTree <double, int>(3, _points.ToArray(), _nodes.ToArray(), L2Norm); double radiusSquared = parameters.radius * parameters.radius; for (int i = 0; i < cells.Count; i++) { GParticle p = cells[i]; p.collisions = 0; var rsquared = parameters.radius * parameters.radius; Tuple <double[], int>[] neighbors = tree.NearestNeighbors(new double[] { p.position.x, p.position.y, p.position.z }, (int)parameters.maxNeighbors); foreach (var neighbor in neighbors) { GParticle q = cells[neighbor.Item2]; Vector3 displacement = p.position - q.position; float distanceSquared = displacement.x * displacement.x + displacement.y * displacement.y + displacement.z * displacement.z; if ((i != neighbor.Item2) && (!p.connectedTo(neighbor.Item2))) { displacement.Normalize(); displacement *= (rsquared - distanceSquared) / rsquared; // TODO sqrt here? NGS what is this even ???? p.delta += displacement * parameters.collisionFactor; p.collisions++; } } } }
private void AddCollisionBruteForce() { var tree = new KdTree <float, int>(3, new FloatMath()); for (int i = 0; i < cells.Count; i++) { tree.Add(new[] { cells[i].position.x, cells[i].position.y, cells[i].position.z }, i); } double radiusSquared = parameters.radius * parameters.radius; for (int i = 0; i < cells.Count; i++) { GParticle p = cells[i]; p.collisions = 0; var rsquared = parameters.radius * parameters.radius; var neighbors = tree.GetNearestNeighbours(new[] { cells[i].position.x, cells[i].position.y, cells[i].position.z }, (int)parameters.maxNeighbors); for (int j = 0; j < neighbors.Length; j++) { GParticle q = cells[neighbors[j].Value]; Vector3 displacement = p.position - q.position; if (displacement.magnitude < parameters.radius) { float distanceSquared = displacement.x * displacement.x + displacement.y * displacement.y + displacement.z * displacement.z; if ((i != j) && (!p.connectedTo(j))) { displacement.Normalize(); displacement *= (rsquared - distanceSquared) / rsquared; // TODO sqrt here? NGS what is this even ???? p.delta += displacement * parameters.collisionFactor; p.collisions++; } } } } }