/// <summary> /// Gets the set of floating objects within a reaction radius from a given position. /// Only objects unused in this simulation step are considered. /// Only objects with no obstacle between them and the given position are considered. /// </summary> /// <param name="position">Position whose neighborhood is searched</param> /// <param name="targetMultiset">OPTIMIZATION: Objects are collected only until this multiset is reached</param> private FloatingObjectsSet GetNearObjects(Point3D position, NamedMultiset targetMultiset) { var missingObjects = new NamedMultiset(targetMultiset.ToDictionary()); var nearObjectsSet = new FloatingObjectsSet(); if (!missingObjects.Any()) { return(nearObjectsSet); } Vector3D radiusVector = new Vector3D(v_MSystem.Mobility, v_MSystem.Mobility, v_MSystem.Mobility); var gridKeys = KeysInBox(new Box3D(position - radiusVector, position + radiusVector)).ToList(); gridKeys.Shuffle(); // Random order of grid boxes where objects are sought for foreach (var key in gridKeys) { foreach (var fltObject in v_Grid[key].OldSet) { if (missingObjects.Contains(fltObject.Name) && fltObject.Position.DistanceTo(position) < fltObject.Type.Mobility && !v_tilesWorld.IntersectsWith(fltObject.Position, position, false)) { nearObjectsSet.Add(fltObject); missingObjects.Remove(fltObject.Name); if (!missingObjects.Any()) { return(nearObjectsSet); } } } } return(nearObjectsSet); }
/// <summary> /// Removes the multiset of names of floating objects from a given set of floating objects in space /// </summary> /// <param name="multiset">Multiset of floating object names to be removed</param> /// <param name="targetSet">Set of floating objects from which the multiset is removed - all must be of type "FloatingObjectsInWorld"</param> /// <exception cref="ArgumentNullException">If the set contains object which is not "FloatingObjectsInWorld"</exception> /// <exception cref="ArgumentException">If the multiset could not be removed</exception> public void RemoveFrom(NamedMultiset multiset, FloatingObjectsSet targetSet) { // Deep copy of the original multiset NamedMultiset myMultiset = new NamedMultiset(multiset.ToDictionary()); foreach (var fltObject in targetSet) { if (myMultiset.Remove(fltObject.Name)) { Remove(fltObject as FloatingObjectInWorld); } } if (myMultiset.Count > 0) { throw new ArgumentException($"{myMultiset} could not be removed from the world!"); } }