/** * Given a pointer to an entity and a std container of pointers to nearby entities, this function * checks to see if there is an overlap between entities. If there is, then the entities are moved * away from each other */ public static <T extends BaseGameEntity, conT extends List<? extends BaseGameEntity>> void EnforceNonPenetrationContraint(T entity, final conT others) { ListIterator<? extends BaseGameEntity> it = others.listIterator(); // iterate through all entities checking for any overlap of bounding // radii while (it.hasNext()) { BaseGameEntity curOb = it.next(); // make sure we don't check against this entity if (curOb == entity) { continue; } // calculate the distance between the positions of the entities Vector2D ToEntity = sub(entity.Pos(), curOb.Pos()); double DistFromEachOther = ToEntity.Length(); // if this distance is smaller than the sum of their radii then this // entity must be moved away in the direction parallel to the // ToEntity vector double AmountOfOverLap = curOb.BRadius() + entity.BRadius() - DistFromEachOther; if (AmountOfOverLap >= 0) { // move the entity a distance away equivalent to the amount of overlap. entity.SetPos(add(entity.Pos(), mul(div(ToEntity, DistFromEachOther), AmountOfOverLap))); } } // next entity }
public static <T extends BaseGameEntity, conT extends List<? extends BaseGameEntity>> boolean Overlapped(final T ob, final conT conOb, double MinDistBetweenObstacles) { ListIterator<? extends BaseGameEntity> it = conOb.listIterator(); while (it.hasNext()) { BaseGameEntity curOb = it.next(); if (TwoCirclesOverlapped( ob.Pos(), ob.BRadius() + MinDistBetweenObstacles, curOb.Pos(), curOb.BRadius())) { return true; } } return false; }
/** * tags any entities contained in a std container that are within the radius of the single entity * parameter */ public static <T extends BaseGameEntity, conT extends List<? extends T>> void TagNeighbors( T entity, conT others, final double radius) { ListIterator<? extends T> it = others.listIterator(); // iterate through all entities checking for range while (it.hasNext()) { T curOb = it.next(); // first clear any current tag curOb.UnTag(); // work in distance squared to avoid sqrts Vector2D to = sub(curOb.Pos(), entity.Pos()); // the bounding radius of the other is taken into account by adding it // to the range double range = radius + curOb.BRadius(); // if entity within range, tag for further consideration if ((curOb != entity) && (to.LengthSq() < range * range)) { curOb.Tag(); } } // next entity }