• Advertisement

Seperating Axis 2D Projection Issue

Recommended Posts

Hello everyone! I’m trying to learn SAT, and I almost have everything figured out. The biggest struggle for me what to understand projection. I’m noticing my collision between two rectangles works fine, but once I rotate, on certain angles it isn’t checking min and max properly as you can see a gap in the image, but it still shows collision.

 

I’ve pasted my code, it’s not much. I cannot seem to fiquire out why it’s not projecting properly. My dot formula and project should be correct, unless I’m something is wrong with the rects updating.

 

I’m using two SFML Rectangles, and when they move or rotate I have to call getTransform().transformPoint(rectB.getPoint(1)) (points are zero based, so this would be top right), and the points are correct when I debug. Also, I use width / 2, because the origin is in the center of the rect.

 

Any idea what I’m doing wrong here?

 

Based on the images showing red when they’re so far apart *red means collision = true*

 

GetFileAttachment?id=AQMkADAwATNiZmYAZC0wZGQAYy1iMTVkLTAwAi0wMAoARgAAA%2F4uJGSyTbFApa0Dt5VFT0oHAJpTodLas8VDok%2BkJRJriUcAAAIBDAAAAJpTodLas8VDok%2BkJRJriUcAAAIFWAAAAAESABAAAADK4ji5SN1Bnmls7qetA0o%3D&X-OWA-CANARY=4B293vzFokefvSrS7aXw9KDzudHkaNUYq5_sp5Vfkvwdkm5pz9128ekulY8RfgS6tt9jLy7XJkk.&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImVuaDlCSnJWUFU1aWpWMXFqWmpWLWZMMmJjbyJ9.eyJ2ZXIiOiJFeGNoYW5nZS5DYWxsYmFjay5WMSIsImFwcGN0eHNlbmRlciI6Ik93YURvd25sb2FkQDg0ZGY5ZTdmLWU5ZjYtNDBhZi1iNDM1LWFhYWFhYWFhYWFhYSIsImFwcGN0eCI6IntcIm1zZXhjaHByb3RcIjpcIm93YVwiLFwicHJpbWFyeXNpZFwiOlwiUy0xLTI4MjctMjQ1NzU3LTIzMjU2NzEzM1wiLFwicHVpZFwiOlwiMTA1NTUxODUxMDMzMDIwNVwiLFwib2lkXCI6XCIwMDAzYmZmZC0wZGRjLWIxNWQtMDAwMC0wMDAwMDAwMDAwMDBcIixcInNjb3BlXCI6XCJPd2FEb3dubG9hZFwifSIsImlzcyI6IjAwMDAwMDAyLTAwMDAtMGZmMS1jZTAwLTAwMDAwMDAwMDAwMEA4NGRmOWU3Zi1lOWY2LTQwYWYtYjQzNS1hYWFhYWFhYWFhYWEiLCJhdWQiOiIwMDAwMDAwMi0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvYXR0YWNobWVudC5vdXRsb29rLm9mZmljZS5uZXRAODRkZjllN2YtZTlmNi00MGFmLWI0MzUtYWFhYWFhYWFhYWFhIiwiZXhwIjoxNTE3NDI5MjE5LCJuYmYiOjE1MTc0Mjg2MTl9.jtFwC_SbopvK9ZzagT7AEWyks_8bS7tZ2xN9Bkd2Z8KjNXERZManWXfXwbqrZXWzpiR9rgaBTdwJfGHGcUdOutAbMav9etsTVLFck7hNEU76Erq5PhIunflfS_oWn1IRoXLa8RaF4XjmDfKjjgS_kLEcgCbslY0AycMZF3kScmECgJBDDvbWsjkyBdm792hGuLnp7G2y-BbR5XgWLmdKH7OSIVZugcQTvuFillw7dWZ4L6MkCIREl3WKHWCFlzvvRN7aV9xJ38XForAS7G1XdSXLpX05Dx0pZUcNyr1IyASHaj7ohIg1sFrHHIbTR0z9kDIlinTHABxiQUiGkom9Ug&owa=outlook.live.com&isc=1&isImagePreview=True

GetFileAttachment?id=AQMkADAwATNiZmYAZC0wZGQAYy1iMTVkLTAwAi0wMAoARgAAA%2F4uJGSyTbFApa0Dt5VFT0oHAJpTodLas8VDok%2BkJRJriUcAAAIBDAAAAJpTodLas8VDok%2BkJRJriUcAAAIFWAAAAAESABAAywJoVeOF40ugC%2BNdYv1Ekg%3D%3D&X-OWA-CANARY=4B293vzFokefvSrS7aXw9KDzudHkaNUYq5_sp5Vfkvwdkm5pz9128ekulY8RfgS6tt9jLy7XJkk.&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImVuaDlCSnJWUFU1aWpWMXFqWmpWLWZMMmJjbyJ9.eyJ2ZXIiOiJFeGNoYW5nZS5DYWxsYmFjay5WMSIsImFwcGN0eHNlbmRlciI6Ik93YURvd25sb2FkQDg0ZGY5ZTdmLWU5ZjYtNDBhZi1iNDM1LWFhYWFhYWFhYWFhYSIsImFwcGN0eCI6IntcIm1zZXhjaHByb3RcIjpcIm93YVwiLFwicHJpbWFyeXNpZFwiOlwiUy0xLTI4MjctMjQ1NzU3LTIzMjU2NzEzM1wiLFwicHVpZFwiOlwiMTA1NTUxODUxMDMzMDIwNVwiLFwib2lkXCI6XCIwMDAzYmZmZC0wZGRjLWIxNWQtMDAwMC0wMDAwMDAwMDAwMDBcIixcInNjb3BlXCI6XCJPd2FEb3dubG9hZFwifSIsImlzcyI6IjAwMDAwMDAyLTAwMDAtMGZmMS1jZTAwLTAwMDAwMDAwMDAwMEA4NGRmOWU3Zi1lOWY2LTQwYWYtYjQzNS1hYWFhYWFhYWFhYWEiLCJhdWQiOiIwMDAwMDAwMi0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvYXR0YWNobWVudC5vdXRsb29rLm9mZmljZS5uZXRAODRkZjllN2YtZTlmNi00MGFmLWI0MzUtYWFhYWFhYWFhYWFhIiwiZXhwIjoxNTE3NDI5MjE5LCJuYmYiOjE1MTc0Mjg2MTl9.jtFwC_SbopvK9ZzagT7AEWyks_8bS7tZ2xN9Bkd2Z8KjNXERZManWXfXwbqrZXWzpiR9rgaBTdwJfGHGcUdOutAbMav9etsTVLFck7hNEU76Erq5PhIunflfS_oWn1IRoXLa8RaF4XjmDfKjjgS_kLEcgCbslY0AycMZF3kScmECgJBDDvbWsjkyBdm792hGuLnp7G2y-BbR5XgWLmdKH7OSIVZugcQTvuFillw7dWZ4L6MkCIREl3WKHWCFlzvvRN7aV9xJ38XForAS7G1XdSXLpX05Dx0pZUcNyr1IyASHaj7ohIg1sFrHHIbTR0z9kDIlinTHABxiQUiGkom9Ug&owa=outlook.live.com&isc=1&isImagePreview=True

GetFileAttachment?id=AQMkADAwATNiZmYAZC0wZGQAYy1iMTVkLTAwAi0wMAoARgAAA%2F4uJGSyTbFApa0Dt5VFT0oHAJpTodLas8VDok%2BkJRJriUcAAAIBDAAAAJpTodLas8VDok%2BkJRJriUcAAAIFWAAAAAESABAAcgfeGV9AhUehxS8ZfJEtCQ%3D%3D&X-OWA-CANARY=4B293vzFokefvSrS7aXw9KDzudHkaNUYq5_sp5Vfkvwdkm5pz9128ekulY8RfgS6tt9jLy7XJkk.&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImVuaDlCSnJWUFU1aWpWMXFqWmpWLWZMMmJjbyJ9.eyJ2ZXIiOiJFeGNoYW5nZS5DYWxsYmFjay5WMSIsImFwcGN0eHNlbmRlciI6Ik93YURvd25sb2FkQDg0ZGY5ZTdmLWU5ZjYtNDBhZi1iNDM1LWFhYWFhYWFhYWFhYSIsImFwcGN0eCI6IntcIm1zZXhjaHByb3RcIjpcIm93YVwiLFwicHJpbWFyeXNpZFwiOlwiUy0xLTI4MjctMjQ1NzU3LTIzMjU2NzEzM1wiLFwicHVpZFwiOlwiMTA1NTUxODUxMDMzMDIwNVwiLFwib2lkXCI6XCIwMDAzYmZmZC0wZGRjLWIxNWQtMDAwMC0wMDAwMDAwMDAwMDBcIixcInNjb3BlXCI6XCJPd2FEb3dubG9hZFwifSIsImlzcyI6IjAwMDAwMDAyLTAwMDAtMGZmMS1jZTAwLTAwMDAwMDAwMDAwMEA4NGRmOWU3Zi1lOWY2LTQwYWYtYjQzNS1hYWFhYWFhYWFhYWEiLCJhdWQiOiIwMDAwMDAwMi0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvYXR0YWNobWVudC5vdXRsb29rLm9mZmljZS5uZXRAODRkZjllN2YtZTlmNi00MGFmLWI0MzUtYWFhYWFhYWFhYWFhIiwiZXhwIjoxNTE3NDI5MjE5LCJuYmYiOjE1MTc0Mjg2MTl9.jtFwC_SbopvK9ZzagT7AEWyks_8bS7tZ2xN9Bkd2Z8KjNXERZManWXfXwbqrZXWzpiR9rgaBTdwJfGHGcUdOutAbMav9etsTVLFck7hNEU76Erq5PhIunflfS_oWn1IRoXLa8RaF4XjmDfKjjgS_kLEcgCbslY0AycMZF3kScmECgJBDDvbWsjkyBdm792hGuLnp7G2y-BbR5XgWLmdKH7OSIVZugcQTvuFillw7dWZ4L6MkCIREl3WKHWCFlzvvRN7aV9xJ38XForAS7G1XdSXLpX05Dx0pZUcNyr1IyASHaj7ohIg1sFrHHIbTR0z9kDIlinTHABxiQUiGkom9Ug&owa=outlook.live.com&isc=1&isImagePreview=True

 

I’m assuming my projection is wrong because the min and max for both rects would have a gap.

       // Get Faces
axesEdge[0] = sf::Vector2f(rectA.getTransform().transformPoint(rectA.getPoint(1)).x + rectA.getLocalBounds().width / 2 - rectA.getTransform().transformPoint(rectA.getPoint(0)).x + rectA.getLocalBounds().width / 2,
         rectA.getTransform().transformPoint(rectA.getPoint(1)).y + rectA.getLocalBounds().height / 2 - rectA.getTransform().transformPoint(rectA.getPoint(0)).y + rectA.getLocalBounds().height / 2);
        
axesEdge[1] = sf::Vector2f(rectA.getTransform().transformPoint(rectA.getPoint(1)).x + rectA.getLocalBounds().width / 2 - rectA.getTransform().transformPoint(rectA.getPoint(2)).x + rectA.getLocalBounds().width / 2,
         rectA.getTransform().transformPoint(rectA.getPoint(1)).y + rectA.getLocalBounds().height / 2 - rectA.getTransform().transformPoint(rectA.getPoint(2)).y + rectA.getLocalBounds().height / 2);
axesEdge[2] = sf::Vector2f(rectB.getTransform().transformPoint(rectB.getPoint(0)).x + rectB.getLocalBounds().width / 2 - rectB.getTransform().transformPoint(rectB.getPoint(3)).x + rectB.getLocalBounds().width / 2,
         rectB.getTransform().transformPoint(rectB.getPoint(0)).y + rectB.getLocalBounds().height / 2 - rectB.getTransform().transformPoint(rectB.getPoint(3)).y + rectB.getLocalBounds().height / 2);
axesEdge[3] = sf::Vector2f(rectB.getTransform().transformPoint(rectB.getPoint(0)).x + rectB.getLocalBounds().width / 2 - rectB.getTransform().transformPoint(rectB.getPoint(1)).x + rectB.getLocalBounds().width / 2,
         rectB.getTransform().transformPoint(rectB.getPoint(0)).y + rectB.getLocalBounds().height / 2 - rectB.getTransform().transformPoint(rectB.getPoint(1)).y + rectB.getLocalBounds().height / 2);

 

Edited by ProgrammingLua

Share this post


Link to post
Share on other sites
Advertisement

I took a quick look at your code, and you're doing everything right accept for one mistake.

Do not use (width / 2) or (height / 2) when setting up your axes edges, it's throwing off your calculation. You can still keep rotation on the center origin, but remove that and try your code to see if it works and let me know.

Edited by Rutin
Spelling error - expect -> accept

Share this post


Link to post
Share on other sites
6 minutes ago, Rutin said:

I took a quick look at your code, and you're doing everything right expect for one mistake.

Do not use (width / 2) or (height / 2) when setting up your axes edges, it's throwing off your calculation. You can still keep rotation on the center origin, but remove that and try your code to see if it works and let me know.

Wow!! Thank you! Everything works now. I spent a few days not able to fix it now its good! I can rotate 2 objects with detection! :) 

Share this post


Link to post
Share on other sites

Nice work, I'm surprised someone found your mistake! A little tidbit of advice: make sure to start debug rendering some of your inner calculations next time you write this kind of code. You can render transforms, planes, normals, points, projected points, etc. to make sure you are understanding the linear algebra.

Share this post


Link to post
Share on other sites
2 minutes ago, Randy Gaul said:

Nice work, I'm surprised someone found your mistake! A little tidbit of advice: make sure to start debug rendering some of your inner calculations next time you write this kind of code. You can render transforms, planes, normals, points, projected points, etc. to make sure you are understanding the linear algebra.

Thank you! I’m new to this so it was very hard to visualize axes to project on. Do you recommend I print to console as things happen? :) 

Share this post


Link to post
Share on other sites

Oh no do not bother printing to console. Debug render with lines and points on the screen, just like you are rendering your boxes!

Share this post


Link to post
Share on other sites
20 minutes ago, ProgrammingLua said:

Wow!! Thank you! Everything works now. I spent a few days not able to fix it now its good! I can rotate 2 objects with detection! :) 

No problem. We've all been in this situation where one miscalculation throws everything off the rails. Great job on implementing rotating convex collision.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement