Polygon collision detection

[quote]I am recreating the bounds cause what I need each frame is a translated and rotated version of the original area I created. I don’t know of another way to do this so its not applying the rotation/translation to the already rotated/translated Area. Heres an example of my problem: The ship needs to be rotated at 45 degrees, and I have this value stored in a variable, but I can’t just tell it to rotate 45 degrees each frame or it will just spin. I am probably going about this wrong. maybe instead of changing the value of some theta variable, I could actualy rotate the ship on keypress… I was just trying to use it in the same way I do with a Graphics context in Java2D, g.rotate(theta, width/2, height/2) each time the screen is rendered.
[/quote]
In GoSub, each of my bounds are transformed back to original rotation each frame using

            try
            {// resetting shape to its normal state, so next transform is not added to the current...
                  ((java.awt.geom.Area)collisionShape).transform( transform.createInverse() );
            }
            catch ( java.awt.geom.NoninvertibleTransformException e )
            {
                  e.printStackTrace();
            }

It also creates an object, but it is immediatly collectable and never gets out of first generation, so is cheap. Your duplicate objects survive for too long to be interesting for Generational GC, which might be your problem, imho.

(in the code, ‘transform’ is the AffineTransform that is applied to that bound)

Another optimisation you can try:
Generate a check-circle (sphere in 3D), by simply taking the distance of the furthest poly point from the centre of rotation. On each frame, test if any circles overlap (very simple - just take the distance squared between the centre points, and compare against the sum of the radii squared (this avoids the square root):

float dist = (obj1.x - obj2.x)*(obj1.x - obj2.x) + (obj1.y - obj2.y)*(obj1.y - obj2.y);
float minDist = (obj1.radius + obj2.radius) * (obj1.radius + obj2.radius);
if( dist <= minDist )
{
// Potential collision - rotate the poly bounds and do the full test...
}

Doing this means you only ever rotate the bounds when they might be needed.

  • Dom

with alot of the shapes I’m using, a circle would not be very good for colllision bounds. Some of the shaps could have 3:1 length to width ratio so this would drop accuracy a bit more than I would like to.

pepe: I’ll give that a try although performance is good now :wink:

I only use one AffineTransform object for my whole game. When I want to use it I use:

trans.setToTransform(scaleX, scaleY, 0, 0, x, y);
trans.rotate(radians, centerX, centerY);

then use it. Is this bad?

[quote]with alot of the shapes I’m using, a circle would not be very good for colllision bounds. Some of the shaps could have 3:1 length to width ratio so this would drop accuracy a bit more than I would like to.
[/quote]
You don’t need to use it for the actual test - its a 1st pass rejection test that can very quickly eliminate 99% of cases. If the circle test passes, you then do the full test to see if a collision really occurs.

This is integrated with the rotating bounds like so:
Store the frame count that the rotated bound was calculated.
Use circle tests - if a circle test says a collision may have occured and the last update to the area was >5 frames, then rotate the area. Then do the full collision test as normal.

This sort of technique is well used in professional games - a nested hierarchy of succesively better collision areas. The first one to check is always the sphere/circle test because it is by far the fastest test to do.

  • Dom

Thanks for clarifying that, it is now much more useful for to me :slight_smile: I see what you mean when you said: "Doing this means you only ever rotate the bounds when they might be needed. ", I never thought about it that way, but it makes sense, just rotate the collision bounds once you have found that there is a possible collision. There is still so much that I have to learn :slight_smile: