I have a set of rooms and passages that I can convert into Rectangles (x,y,width,height) or a list of Points (x,y). Room and Passage both extend the Pointable interface. The getPoints() method is implemented for the Room class as
public Set<Point> getPoints() {
Set<Point> array = new HashSet<Point>();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
array.add(new Point(x + i, y + j));
}
}
return array;
}
The Problem:
I must identify the Pointable that a given Point belongs to. No rooms intersect. I originally used a HashMap<Point,Pointable> to correlate each Point to a Pointable, which was able to quickly able to access the answer in O(n) time. However, it is now necessary to recalculate the HashMap multiple times in the generation of a level.
At this point, is it still more efficient to use the HashMap (in consideration of generation and access) or should another method be used, such as a set of 2-D interval trees?
Nobody can tell except the one who did a measurement. It all depends on how often you need to update the data, how often they change, and how often they get queried.
And also on the size of a
Room. With a few points, theHashMapwins in a typical scenario, with thousands of them, the overhead of updating the points dominates.Can't you use an array for all
Points? If so, then it'll be surely way faster then theHashMap, especially for updating (unless it gets really huge).This may or may not be useful.
Actually, not only each
Roomhas somePoints, but also eachPointmay have oneRoom(n:1). How it gets implemented, it's a different question.Given this, we have a standard problem: If you link bidirectionally, then you have to keep both links in sync. The simplest solution is to make the setters ("adders"/"removers") as private as possible and only called them from a method
Your linking from
PointtoRoomis external, but this hardly changes anything (except for keepingPointsmaller and possibly cleaner and adding the tiny overhead of a HashMap to each access).It's usually also the fastest as usually there are much more queries than updates. Your problem is that the update cost gets scaled up by the
Roomsize. Without you telling us some figures, no estimate is possible.With too many points and rooms of not too widely varying size, you could round the point coordinates to a multiple of some
nand keep an array holding the set of all rooms intersecting the grid. You could proceed as before, but the update overhead would be lower by nearly a factor given by the room area(*) and the search overhead higher, as you'd have to select the really matching room (if any) from the set.(*) For rooms not aligned to grid, the number of intersecting rectangles is obviously higher.