AABB to AABB collision time function
BlitzMax Forums/BlitzMax Programming/AABB to AABB collision time function
| ||
I think my terminology is correct with the AABBs. I suppose I really mean 2D rectangles. Has anyone got or know of a function that given two rectangles and their respective velocities (in x and y components) will return the time of collision and the position of both rectangles at this time? It would also return false or true depending on whether the objects actually collide as well. I've been looking around the net and I keep getting close but not finding the banana yet Thanks - Rico |
| ||
I presume you'd trace lines from the corners of the boxes and see if they overlap? |
| ||
It would probably be easier to use spheres, then I think you would just need to check to find the closest point along their vectors and check the distance between to see if it was under their combined radii. Checking via spheres would allow for a very fast check which could then be supplemented with 'AABB rectangle collision checking'. Here is an example of this approach... Hope this helps, let me know how you get on as I will probably need the BlitzMax solution for this shortly? ;0) |
| ||
Thanks Merx and Human. I'll get to it. I have now managed to find an AABB to AABB collision function in a book (that coincidentally just arrived from Amazon today!). I haven't had much time to look throught it yet. All the example code is in C but I should be able to convert it to BlitzMax (though my knowlede of C isn't great). It looks like a really good book for polygonal collision detection and determining collision time. Its called Real Time Collision Detection by Christer Ericson. Everyone loves it on the net - which is why I ordered it (though I wasn't really sure exactly what was in it until now). Before I can do much though I need to know how to change variables that you pass to a function - inside that function. Without using Global Variables do e.g x=1;y=2 change(x,y) 'hopefully now x=3;y=5 Function change(a:int,b:int) a=a+2;b=b+2 end function I know in C you put an & sign before the variable in the function definition. Thanks - Rico |
| ||
Ok in C++ that's passing by reference, you are passing the actual variable as opposed to passing by value where only the numeric value of the variable is transfered. In BlitzMax you can use pointers to pass the Address of the variable and this can then be used to alter the value of the variable. e.g. x=1;y=2 Print x + " " + y change(Varptr x, Varptr y) Print x + " " + y 'hopefully now x=3;y=5 Function change(a:Int Ptr,b:Int Ptr) a[0]=a[0]+2;b[0]=b[0]+2 End Function The odd array syntax is used to access the values of the variable pointers. There may be a better way to write this, but hope it helps. Regards |
| ||
OK well I've got this function which finds the time of collision between two AABB's (rectangles). It seems to work. I've done my best to convert it to Blitz (I'm no expert). It returns whether a collision has occured and 'tf' contains the time of the first collision, and 'tl' the time of the last collision - the time at which the rectangles no longer collide. Basically you multiply the x-vector and y-vector of each object with 'tf' to get the position when they first collide. Here is the Code and functions: Blitz may have Max and Min functions but they weren't documented very well in the help section so I wrote my own. Type rect Field x1#,y1#,x2#,y2# Field w#,h# Field xv#,yv# End Type Function MovingBoxColl(a:rect,b:rect,tf:Float Ptr,tl:Float Ptr) If rectsoverlap(a.x1,a.y1,a.w,a.h,b.x1,b.y1,b.w,b.h) tf[0]=0;tl[0]=0 Return True EndIf 'calculate relative velocity rvx#=b.xv-a.xv rvy#=b.yv-a.yv 'initialise points of first and last contact tf[0]=0; tl[0]=1 'for X axis determine the times of first and last contact, if any If rvx<0 If b.x2<a.x1 Then Return False ' Non-intersecting and moving apart If a.x2<b.x1 Then tf[0]=RMax((a.x2-b.x1)/rvx,tf[0]) If b.x2>a.x1 Then tl[0]=RMin((a.x1-b.x2)/rvx,tl[0]) EndIf If rvx>0 If b.x1>a.x2 Then Return False ' Non-intersecting and moving apart If b.x2<a.x1 Then tf[0]=RMax((a.x1-b.x2)/rvx,tf[0]) If a.x2>b.x1 Then tl[0]=RMin((a.x2-b.x1)/rvx,tl[0]) EndIf 'No overlap possible if time of first contact occurs after time of last contact If tf[0]>tl[0] Then Return False 'for Y axis determine the times of first and last contact, if any If rvy<0 If b.y2<a.y1 Then Return False ' Non-intersecting and moving apart If a.y2<b.y1 Then tf[0]=RMax((a.y2-b.y1)/rvy,tf[0]) If b.y2>a.y1 Then tl[0]=RMin((a.y1-b.y2)/rvy,tl[0]) EndIf If rvy>0 If b.y1>a.y2 Then Return False ' Non-intersecting and moving apart If b.y2<a.y1 Then tf[0]=RMax((a.y1-b.y2)/rvy,tf[0]) If a.y2>b.y1 Then tl[0]=RMin((a.y2-b.y1)/rvy,tl[0]) EndIf 'No overlap possible if time of first contact occurs after time of last contact If tf[0]>tl[0] Then Return False Return True End Function Function RMax:Float(a:Float,b:Float) If b>a Then Return b Return a End Function Function RMin:Float(a:Float,b:Float) If b<a Then Return b Return a End Function Function rectsoverlap:Int(x0:Int,y0:Int,w0:Int,h0:Int,x2:Int,y2:Int,w2:Int,h2:Int) If x0>(x2+w2)Or(x0+w0)<x2 Then Return False If y0>(y2+h2)Or(y0+h0)<y2 Then Return False Return True End Function |
| ||
Hi - Just found out that to pass variable to a function by reference you can use Var. - Instead of Var Ptr and then indexing the pointer in the function. e.g Rem Var is a composite type containing a reference to a variable of the specified Type. End Rem ' the following illustrates parsing function parameters by reference Function ReturnMultiplevalues(a Var,b Var,c Var) a=10 b=20 c=30 Return End Function Local x,y,z ReturnMultipleValues(x,y,z) Print "x="+x '10 Print "y="+y '20 Print "z="+z '30 |