Advertisement

Seperating Axis 2D Projection Issue

Started by January 31, 2018 08:02 PM
7 comments, last by Rutin 7 years ago

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);

 

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.

Programmer and 3D Artist

Advertisement
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! :) 

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.

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? :) 

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

Advertisement

Ok I understand. Thank you! :) 

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.

Programmer and 3D Artist

This topic is closed to new replies.

Advertisement