scaevity
scaevity

Reputation: 4091

represent 2d pile of ball in java

I'm creating an application where I need to model (and display) a large number of 2-dimensional 'balls' (circles) using java. I've started by creating an ArrayList of Circle objects (a class that I defined, which has x/y pixel coordinates of the center of the circle, radius, color, and velocity in the x & y directions). I use a java.util.Timer object with a repeated TimerTask to control the motion of the circles. The circles vary in size from around 10-50 pixel radii.

What I want to happen is have balls fall from the top of the screen (randomly distributed across the x-axis) until they reach the bottom of the screen, which acts like a floor -- ball that reach it stop moving, and balls that reach stopped balls roll downhill on the other balls until they rest at a low/flat point. In the future I might want to make their behaviour a bit more complicated, so I want to create flexible code so I can easily expand. How it works right now is that every time period each circle check to see how close they are to every other circle. If there are no other circles nearby they continue falling normally. If two (or more) circles are close to each other there is code to determine how they will interact.

I have it working perfectly for small numbers of circles (< 200), but when I get larger numbers of circles (> 400) it starts slowing down significantly. I'm sure I can optimize some of the logic to make the comparisons a bit faster, but I was wondering if there are any ways of storing the circle in some structure besides an unorganized ArrayList that would let me easily find circles that are close to each other, so I don't have to do the N^2 operation of comparing each circle to every other one and, instead, just compare a circle to the 5-10 circles closest to it. For instance, I've considered using a 2D array to represent every pixel (or maybe square of 5x5 pixels) and store a circle where its center lies (so I could check if there are circles in any of the nearby cells, and ignore the rest). However, this still seems pretty inefficient as if I'm using a 800x1000 pixel canvas with 500 circles there would be a TON of empty spaces in the 2d array that I'd waste time checking. I've also considered some sort of hashmap, but I haven't thought of a great way to use that either.

So, can anyone think of an efficient way to store these circles that corresponds to it's location in 2d space and makes it easy to find nearby circles? Thanks in advance!

Upvotes: 1

Views: 377

Answers (2)

Carl
Carl

Reputation: 915

Perhaps your idea of a 2D array is not so crazy. What I think you want is one List of all your circles, and a 2D array that would reference the circles also. So at each time, you can iterate over your List<Circle> to check each one. Each Circle has x,y coords and you only have to loop on your array for (x,y +/- 5). There is no need to check the whole possible space for Circles, because you already are keeping track of each Circle's center. Just grab the center, and check around it for other circles.

Upvotes: 1

MvG
MvG

Reputation: 60918

You can use a QuadTree to find close neighbours. Or you can simply sort by one direction, which would be far easier to implement and should still allow you to reduce the number of candidate neighbours to a small window.

Upvotes: 1

Related Questions