Looking for alternative approach

I have a class that draws an ellips on the canvas. In the class I store the X and Y coordinates, the color and some other stuff. It holds a single method that draws the ellips (itself). In a loop I create some 50 of these objects with a random X and Y. I store the objects in an array of type class. In the paint event of the canvas I loop through the array and draw the objects again with different X and Y thus mimicking movement. To detect collisions I have to loop through the array and match the first object against all other objects using Pythagoras’ Theorem to detect collisions. Then I test the second object etc. So every Paint event the array is traversed 2500 times (50*50)-1
The Paint event gets fired by a Timer. With 50 objects it is ok, but with more objects it gets really slow. Suggestions appreciated!

if object A has a collision with object B
then you don’t have to test object B again with object A as you now they do.
only the other objects
A-B
A-C
A…Z
B-C
B-D
B…Z
C-D
C-E
c…Z

1 Like

Most of the times the objects will not be close enough to consider collision so checking just one coordinate first then if required the other one (instead of the distance between centers, which involves a more complex calculation) can be enough to know there is no collision:

If X1>X2+2R Or X1<X2-2R Then No Collision

Else If Y1>Y2+2R Or Y1<Y2-2R Then No Collision

Else Check Pythagoras

I have never tried that, but I would expect it to be faster.

Julen

How about you store the co-ordinates of each object in a table in an in-memory SQLite database. You could then use a query to get a list of collided objects by using a left outer join to the same table.

I wonder if this might be of use:

2 Likes

my little attempt to draw some pixmapshapes in a canvas that fall down
the elements are thrown upwards when they come into contact with others and can be caught with the mouse
example:

https://www.dropbox.com/s/le3mwcel4vs1z5g/test-shapespeed.xojo_binary_project?dl=1

Thanks all. I will look over your solutions. The pain is in the object array imho. I wonder if I can store X,Y as a Pair to speed things up?

This Project may give you some ideas.

Hi Wayne,

that was exactly what I needed!

Thanks a million.

Hi there Wayne,

still a question. I see that the actual collision detection is done by means of SQL statement:

SELECT l.id i, r.id j
FROM objects l, objects r
WHERE ABS((l.x - r.x)) < ? AND ABS((l.y - r.y)) < ? AND l.id <> r.id;

Could you elaborate (i.e. the question marks) some more?

Thanks

In the MoveTimer Action Event Handler you’ll see the line below. The 2 question marks are replaced with SizeField.Text.ToInteger * 2. This is an example of using a SQL prepared statement.

// Get Collisions
Var Rows As RowSet = db.SelectSQL(kCollisionStatement, SizeField.Text.ToInteger * 2, SizeField.Text.ToInteger * 2)