private List <T4_occupant> get_nearest_occupants(double x, double y) { double max_squared_dist = _rect.H * _rect.H + _rect.W * _rect.W; List <T4_occupant> occupants = get_internal_occupants(x, y, ref max_squared_dist); // shouldn't happen for non-empty regions and pickpoint inside if (occupants.Count == 0) { return(occupants); } // purge outdated candidates (collected before dist refinement) // find nearest occupant. all chances nearest occupant would be the last added // because it trims the max dist most // remove all occupants starting after the end of the nearest T4_occupant nearest = occupants[occupants.Count - 1]; double nearest_end = nearest.Rect.Max_squared_distance_to_pt(x, y); for (int i = occupants.Count - 2; i >= 0; i--) { if (occupants[i].Rect.Min_squared_outside_distance_to_pt(x, y) > nearest_end) { occupants.RemoveAt(i); } } return(occupants); }
private void add(T4_occupant occupant) { if (_rooms != null) { int idx = choose_room(occupant); // choosed a room for occupant successfully if (idx != -1) { _rooms[idx].add(occupant); return; } } _occupants.Add(occupant); if (_occupants.Count > MAX_OCCUPANTS) { relocate(); } }
private void relocate() { if (_rooms == null) { split(); } // try to relocate occupants to the smaller rooms for (int i = _occupants.Count - 1; i >= 0; i--) { T4_occupant occupant = _occupants[i]; int idx = choose_room(occupant); if (idx < 0) { continue; // occupant is too large } _occupants.RemoveAt(i); _rooms[idx].add(occupant); } }
private int choose_room(T4_occupant occupant) { bool is_bottom_quads = occupant.Rect.Ymin > _rect.Ymin && occupant.Rect.Ymax < _rect.Yc; bool is_top_quads = occupant.Rect.Ymin > _rect.Yc && occupant.Rect.Ymax < _rect.Ymax; bool is_left_quads = occupant.Rect.Xmin > _rect.Xmin && occupant.Rect.Xmax < _rect.Xc; bool is_right_quads = occupant.Rect.Xmin > _rect.Xc && occupant.Rect.Xmax < _rect.Xmax; if (!(is_top_quads ^ is_bottom_quads)) { return(-1); } if (!(is_left_quads ^ is_right_quads)) { return(-1); } if (is_bottom_quads) { return(is_left_quads ? 0 : 1); } return(is_right_quads ? 2 : 3); }