Finding all objects within a radius (circle) of a point

Official forum for the Chipmunk2D Physics Library.
Post Reply
drey08
Posts: 15
Joined: Mon Oct 28, 2013 10:55 pm
Contact:

Finding all objects within a radius (circle) of a point

Post by drey08 »

There's cpSpaceBBQuery which I can use to find all objects in an area inside a bounding-box. But I need to find objects within a circular area (just a radius). There's cpSpaceNearestPointQueryNearest but that only gives me the first nearest object. There's also cpSpaceShapeQuery, but I need to pass in a cpShape, so that requires allocating a cpBody in order to construct a cpCircle via cpCircleShapeNew. This seems expensive to do if all I want to do is check for objects within a radius.

Is there any other function I can use?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by slembcke »

http://chipmunk-physics.net/release/Chi ... intQueries

You are looking for cpSpaceNearestPointQuery(). It uses a callback to iterate all objects near a point. cpSpaceNearestPointQueryNearest() is the convenience function for when you want just the nearest one.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
drey08
Posts: 15
Joined: Mon Oct 28, 2013 10:55 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by drey08 »

slembcke wrote:http://chipmunk-physics.net/release/Chi ... intQueries

You are looking for cpSpaceNearestPointQuery(). It uses a callback to iterate all objects near a point. cpSpaceNearestPointQueryNearest() is the convenience function for when you want just the nearest one.
Thanks, that's perfect.

Btw, I've run into an interesting problem where cpSpaceNearestPointQueryNearest will return the closest object to a point, but sometimes I'm looking for the nearest target object to another source object. If I use the source object's position then the query function will simply return that object rather than any object nearest to it.

The way I'm working around this is to temporarily save the layers of a shape, then set the layers to zero, and re-set the layers after the query function is called. That way the source object is not picked up. Know of a better way to do this?
Zamaster
Posts: 37
Joined: Tue Feb 12, 2013 8:09 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by Zamaster »

That's a fine solution but if you don't want to play with the layers, you should use cpSpaceNearestPointQuery() and with the *data argument, pass in a structure containing info about the "source" shape and a "shortest_distance" value and a "shortest_distance_shape" pointer. Then, in the iterator function, exit early if the query in question is about your source object, and for every other object, if distance is smaller than the current "shortest_distance," set shortest_distance = distance and shortest_distance_shape = shape.

Then at the end of the initial call of cpSpaceNearestPointQuery(), the structure you passed in should have the shortest distance / shape, or whatever else you wanted to track (also ignoring the "source" of course).
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by slembcke »

What I've used in the past is to use the group filter. Normally I don't bother giving objects a group filter, but it's useful in this case to give every object a group filter. The cpGroup type is an intptr by default. So I assign the "game object" or parent object's pointer to the group of all it's shapes. That way it's always unique per object. (By "object" I mean something like an entire character or vehicle that may consist of several physics objects)

Then when you want to do a raycast or other query that you don't want to include the object itself, you always have something to filter on.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
drey08
Posts: 15
Joined: Mon Oct 28, 2013 10:55 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by drey08 »

slembcke wrote: Then when you want to do a raycast or other query that you don't want to include the object itself, you always have something to filter on.
But how do you call the cpSpaceNearestPointQuery function if you want to exclude a group rather than look only for that group? E.g. if I want to look for all shapes closest to a point which do not have a GROUP_FRIENDLY group?
drey08
Posts: 15
Joined: Mon Oct 28, 2013 10:55 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by drey08 »

Zamaster wrote:That's a fine solution but if you don't want to play with the layers, you should use cpSpaceNearestPointQuery() and with the *data argument, pass in a structure containing info about the "source" shape and a "shortest_distance" value and a "shortest_distance_shape" pointer. Then, in the iterator function, exit early if the query in question is about your source object, and for every other object, if distance is smaller than the current "shortest_distance," set shortest_distance = distance and shortest_distance_shape = shape.

Then at the end of the initial call of cpSpaceNearestPointQuery(), the structure you passed in should have the shortest distance / shape, or whatever else you wanted to track (also ignoring the "source" of course).
That's a nice solution, thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Finding all objects within a radius (circle) of a point

Post by slembcke »

Groups are only exclusive. Query filtering works exactly like shape filtering. Two shapes (or a shape and a query) with the same group identifier are excluded before it even performs more expensive collision checks.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: No registered users and 16 guests