Computer Science Canada [Module] Collision |
Author: | Aange10 [ Mon Jan 16, 2012 12:54 am ] | ||||
Post subject: | [Module] Collision | ||||
Features
This module does collision, so you don't have to! It takes all the stress out of collision, by allowing you to simply input the co-ordinates, and that's it. *Relatively no math involved. Specifically, checking rectangular collisions becomes easier because this module checks 14 points, increasing accuracy, and keeping you from running needless perimeterfors. *Shutters* How it Works
Here's a simple breakdown: CircleToCircle : The module finds the distance between the centers of the two circles and compares it the the sum of the radii. RectangeToRectangle : The module distinguishes a plane for the Rectangle, and detects 14 key points and looks for plane interception. RectangleToCircle : The module fabricates a box to represent the Circle, and detects its 14 points along with the Rectangles. Syntax
The syntax is super simple. [See The Turing Walkthrough for importing modules] After importing the module you can call it by these parameters:
The syntax is very self explanatory, and all of the functions output a Boolean that indicates collision. The parameters are also all integers. Instructions
1) Import Collision.tu 2) Call the functions with their appropriate syntaxs. 3) Done! The Module
Just copy and paste this in a Turing File, and name it "Collision.tu"!
Working Example
Posted Below! |
Author: | Raknarg [ Mon Jan 16, 2012 7:09 pm ] |
Post subject: | RE:[Module] Collision |
Pretty useful. However, to be honest, the rectangle to rectangle seems to be like a lot more work than it should've been. |
Author: | Aange10 [ Mon Jan 16, 2012 7:18 pm ] |
Post subject: | RE:[Module] Collision |
Why so? A lot of times people settle for checking 4 points (corners), or decide to check the perimeter. I do see how this could be a bit more, but i built it to reasonably check the entire rectangle, without actually doing so. The 14 strategic points allot a more accuracy than corners, but less time than scanning the perimeter. However, I also designed it to check for collision at the most common intersections first, and find its result as quickly as possible. |
Author: | Raknarg [ Mon Jan 16, 2012 7:27 pm ] |
Post subject: | RE:[Module] Collision |
Actually, now that I think about it, my way would have taken just as much time haha nevermind |
Author: | Aange10 [ Mon Jan 16, 2012 7:31 pm ] |
Post subject: | RE:[Module] Collision |
Out of curiosity, what would your way have been? |
Author: | Raknarg [ Mon Jan 16, 2012 7:35 pm ] |
Post subject: | RE:[Module] Collision |
It would have just been a corner comparison... but I was thinking of my game where I only have to compare 1 corner to 4 corners instead of 4 to 4 |
Author: | mirhagk [ Tue Jan 17, 2012 10:43 am ] | ||
Post subject: | RE:[Module] Collision | ||
If x1 and x2 are ordered so x1 is smaller than x2, then your rectangular collision detection can be a lot shorter and faster.
EDIT: Also your circle to circle accepts 2 radius's for each circle, which suggests that the function calculates the intersection of 2 ovals (which it doesn't). You can shorten that to just accept one radius for each, and then only have the 1 if statement (instead of 4) |
Author: | Zren [ Tue Jan 17, 2012 11:23 am ] | ||||
Post subject: | RE:[Module] Collision | ||||
You assume x1 and y1 are smaller than x2 and y2. You should *not* assume this. Your function should determine the smallest first. Otherwise you end up with a negative width. Also learn about bitwise operators (and, or, ...). Your if chain could be broken down into:
Turing is also doesn't force you to end a statement at the end of the line. So for really long lines, you can do:
|
Author: | Aange10 [ Tue Jan 17, 2012 7:20 pm ] |
Post subject: | RE:[Module] Collision |
Quote: Also learn about bitwise operators (and, or, ...). Your if chain could be broken down into:
I do know about these. However, I was thinking that splitting up the if statements would allow the program to determine a false result faster. However my err is in that I forgot that in an or statement the program will stop computing the rest of the statement if one of the ors become true. My mistake. I'm going to implement both of your suggestions. |
Author: | crossley7 [ Tue Jan 17, 2012 10:29 pm ] |
Post subject: | RE:[Module] Collision |
Just wondering why you need to check 14 points for rectangle to rectangle because if they intersect, 1 of the corners will overlap except in the case where 1 is very tall and narrow and the other is shorter and wider and the whole thing overlaps. you just have to check that case so there are really 9 cases. the 8 corners (2 rectangles) inside the other rectangle and the edge case where the centres overlap. For circle to rectangle, you have to check 9 things again. The radius on corners and then radius overlapping a side and circle completely within rectangle. (Circle larger than rectangle should be covered by all of the first 8) |
Author: | mirhagk [ Wed Jan 18, 2012 1:09 am ] |
Post subject: | RE:[Module] Collision |
Is there a reason the algorithm I suggested can't be used? Of course you will also need to make sure the points are ordered correctly (but this is easy to do) |
Author: | Aange10 [ Wed Jan 18, 2012 7:52 am ] |
Post subject: | Re: RE:[Module] Collision |
mirhagk @ 18/1/2012, 12:09 am wrote: Is there a reason the algorithm I suggested can't be used? Of course you will also need to make sure the points are ordered correctly (but this is easy to do)
Nope, I'm working on that right now. |
Author: | Aange10 [ Sat Jan 21, 2012 7:58 pm ] |
Post subject: | Re: [Module] Collision |
Okay, I've implemented the new formulas, circle collision also now works with ovals. Critiques, please? I'm going to attach it, since it's 190 lines. |
Author: | Zren [ Sun Jan 22, 2012 1:16 am ] |
Post subject: | RE:[Module] Collision |
Bounding boxes are usually suppose to surround the entire shape. It's usually better to have false positives then not detecting possible collisions (Eg: better to have some places the character can't move to then being half inside a wall). Also this: http://imgur.com/usygV There does exist ways to test oval collisions perfectly, but it's rather non-critical. You're better off wondering how to test collisions on regular shapes once those shapes have been rotated. |
Author: | Aange10 [ Sun Jan 22, 2012 10:38 am ] |
Post subject: | RE:[Module] Collision |
Quote: Bounding boxes are usually suppose to surround the entire shape. It's usually better to have false positives then not detecting possible collisions (Eg: better to have some places the character can't move to then being half inside a wall). I've made the boxes all bigger. I'm going to implement that CircleToRectangle formula, and to insure ovals will still work, I'll use my current formula for ovals, and this new one for circles (when comparing to rectangles) |
Author: | Aange10 [ Sun Jan 22, 2012 12:45 pm ] |
Post subject: | Re: [Module] Collision |
Okay, here is the new collision detector. It fully features each new technique I've learned :3 Any problems? And *hint* is working to get it on the sticky list EDIT: I also changed the circle to circle collision to not use Square roots. |
Author: | Zren [ Sun Jan 22, 2012 2:14 pm ] |
Post subject: | RE:[Module] Collision |
I like the part where you didn't even use your own functions for the new CircleRectangle collision test... You also didn't remove the use of sqrt in CircleCircle collision tests. You will still get undetected collisions from your oval check, as the box doesn't cover the entire oval. Yes, I do mean that you should treat ovals the same as rectangles until such a time as you can refine the area down to just the oval (which might be complicated/code intensive thus the use of a bounding box check first). Also, add circleToCircleCollision and other ___Collision functions to the export list as those are the ones that people will want to use, not the ones you use for debugging which add extra code overhead. I haven't added this to the list as it can still be improved upon. While I can't do much quality control for ancient ass modules, your's can be. >:] |
Author: | Aange10 [ Sun Jan 22, 2012 2:41 pm ] |
Post subject: | RE:[Module] Collision |
Quote: I like the part where you didn't even use your own functions for the new CircleRectangle collision test... What do you mean? Quote: You also didn't remove the use of sqrt in CircleCircle collision tests. I did, after I attached it. That's why I edited it; I didn't remove the attachment because somebody had already downloaded it. So I just put an edit saying that I did. Quote: You will still get undetected collisions from your oval check, as the box doesn't cover the entire oval. The sides inch off, but I'll just cover the entire oval (and a lot of extra space around it), if you think that is best. Quote: Also, add circleToCircleCollision and other ___Collision functions to the export list as those are the ones that people will want to use, not the ones you use for debugging which add extra code overhead. I don't see the problem with the Boolean giving you an option to draw what is being detected. If I would have named it "drawBox" you probably wouldn't even complain about it. It's an extra feature with one Boolean parameter, and only one if statement to check for it in the module. Why should I add the internal collision detection functions to the export list? They don't have a reason to use them; the functions already detect the difference between ovals and circles, misplaced x/y bounds of rectangles, etc. There is no reason not to use them. They determine if the shape is correct, and then execute collision detection. Likewise, they also offer you a choice to draw what is being detected. I don't know about you, but I've had many occasions where collision was not working because of miss typed coordinates. Giving an option to draw what is being detected just makes it 100x easier to detect those mistypes. Quote: I haven't added this to the list as it can still be improved upon. While I can't do much quality control for ancient ass modules, your's can be. >:] > Good, I've learned a lot already xD |
Author: | Aange10 [ Tue Jan 24, 2012 10:21 pm ] |
Post subject: | RE:[Module] Collision |
A response would be appreciated |
Author: | Zren [ Wed Jan 25, 2012 12:35 am ] | ||
Post subject: | Re: RE:[Module] Collision | ||
Hmmm oh right. Aange10 @ Sun Jan 22, 2012 2:41 pm wrote: Quote: I like the part where you didn't even use your own functions for the new CircleRectangle collision test... What do you mean? I mean you redid rectangle and circle collision tests instead of using your own functions... Just look at your circleXrect function:
Ah sorry, now that I look at it, you really only just have a circle vs circle collision function. You could simplify that with twoPointsWithinDist(p1, p2, dist) which can be easily used for pointXcircle collision. twoPointsWithinDist(point, circle.center, cricle.radius). And also, for circleXcircle, twoPointsWithinDist(cir1.center, cir2.center, cir1.radius + cir2.radius). Basically, you can simplify the code you have now as well as expand it to include shape colliding with a point. Which is really where you should have been starting from, not complex shape vs complex shape. After all, mouse coordinates are points, making it silly that a user would need to write his own methods for colliding with points. So sorry, I misread how you implemented your functions. However that misunderstand led to this point. Aange10 @ Sun Jan 22, 2012 2:41 pm wrote: Quote: Also, add circleToCircleCollision and other ___Collision functions to the export list as those are the ones that people will want to use, not the ones you use for debugging which add extra code overhead. I don't see the problem with the Boolean giving you an option to draw what is being detected. If I would have named it "drawBox" you probably wouldn't even complain about it. It's an extra feature with one Boolean parameter, and only one if statement to check for it in the module. Why should I add the internal collision detection functions to the export list? They don't have a reason to use them; the functions already detect the difference between ovals and circles, misplaced x/y bounds of rectangles, etc. There is no reason not to use them. They determine if the shape is correct, and then execute collision detection. Likewise, they also offer you a choice to draw what is being detected. Having a choice to only use the logic code which is the only thing I'd use isn't a bad thing. Of course, I can obviously just edit the file myself. The point is, when you eventually reach using a language where recompiling someone else's library is annoying/unwanted, it's better to leave all your options open that are not explicitly private functions. Think of the most annoying parameter you use in a function in Turing. Eg: Pic.Draw (picID, x, y, mode : int). 99% of the time, the user uses picCopy mode, however every time he wants to use the function, he must type that out. Replace picCopy with picMerge if the user has learned about colouy keys/transparency. Examples of private stuff are either functions that could break usage elsewhere. Hmmm, and example being that the function only erases all the data, but normal behaviour would be to call another function that would remove that object from a list. Another one would be if the function is probably not permanent in your library, and you don't want to people to become dependent on it. None of your function actually modify the data sent in the parameters. Nor does it modify any variables in the module's scope itself. It only reads and chucks out a response according to the state of those parameters. So it doesn't fall in the first example. It could arguably fall in the second one, this module isn't exactly stable enough to warrant that (yet). Another reason is clarity. Your function names have nothing to do with 'draw'. Another thing is that boolean's as parameters can lead to some confusing code. Say you changed the name to drawCircleCollision. When you write code that calls this function: drawCircleCollision(cir1, cir2, false) Just glancing at that code, WITHOUT looking at the source of the collision module will confuse the reader into wondering what that parameter actually does. Where as: checkCircleCollision(cir1, cir2) drawAndCheckCircleCollision(cir1, cir2) ... Are more readable. Better explanation. Aange10 @ Sun Jan 22, 2012 2:41 pm wrote: I don't know about you, but I've had many occasions where collision was not working because of miss typed coordinates. Giving an option to draw what is being detected just makes it 100x easier to detect those mistypes. Having options is fine. Preventing them is not/annoying. ~ Also: circleToCircle(): The name of this method implies that it is used for two circles, when in fact it compares two ovals, THEN simplifies if they are in fact, circles. |
Author: | Aange10 [ Wed Jan 25, 2012 7:24 pm ] | ||||||||
Post subject: | Re: RE:[Module] Collision | ||||||||
Zren @ 24/1/2012, 11:35 pm wrote: I mean you redid rectangle and circle collision tests instead of using your own functions... Just look at your circleXrect function:
No, that's two different if statements, not an elsif branch. It has to do with the little square in the picture you linked me. Quote: Ah sorry, now that I look at it, you really only just have a circle vs circle collision function. You could simplify that with twoPointsWithinDist(p1, p2, dist) which can be easily used for pointXcircle collision. twoPointsWithinDist(point, circle.center, cricle.radius). And also, for circleXcircle, twoPointsWithinDist(cir1.center, cir2.center, cir1.radius + cir2.radius). I already to check the distance between two points (and compare to the sum of radii). Line 27-32 is the entire circle collision process. Quote: Basically, you can simplify the code you have now as well as expand it to include shape colliding with a point.
I guess I don't understand what you mean; I don't see where checking the distance between point A and B, and comparing it something C, is any use. If anything I already utilize that. Quote: Which is really where you should have been starting from, not complex shape vs complex shape. After all, mouse coordinates are points, making it silly that a user would need to write his own methods for colliding with points. So sorry, I misread how you implemented your functions.
I'm really not sure what you mean. I didn't start from complex vs complex. Understandably, circles, ovals, and rectangles are as basic as it gets. The only less is comparing two points, which is if point1X = point2X and point1Y = point2Y then. So, I don't see why it is silly that a user would write their own methods for colliding with points...? I'm sure we have some confusion between us here. Here is basically how the program works thus far:
Quote: However that misunderstand led to this point. Aange10 @ Sun Jan 22, 2012 2:41 pm wrote: Quote: Also, add circleToCircleCollision and other ___Collision functions to the export list as those are the ones that people will want to use, not the ones you use for debugging which add extra code overhead. I don't see the problem with the Boolean giving you an option to draw what is being detected. If I would have named it "drawBox" you probably wouldn't even complain about it. It's an extra feature with one Boolean parameter, and only one if statement to check for it in the module. Why should I add the internal collision detection functions to the export list? They don't have a reason to use them; the functions already detect the difference between ovals and circles, misplaced x/y bounds of rectangles, etc. There is no reason not to use them. They determine if the shape is correct, and then execute collision detection. Likewise, they also offer you a choice to draw what is being detected. Having a choice to only use the logic code which is the only thing I'd use isn't a bad thing. Of course, I can obviously just edit the file myself. The point is, when you eventually reach using a language where recompiling someone else's library is annoying/unwanted, it's better to leave all your options open that are not explicitly private functions. Think of the most annoying parameter you use in a function in Turing. Eg: Pic.Draw (picID, x, y, mode : int). 99% of the time, the user uses picCopy mode, however every time he wants to use the function, he must type that out. Replace picCopy with picMerge if the user has learned about colouy keys/transparency. Examples of private stuff are either functions that could break usage elsewhere. Hmmm, and example being that the function only erases all the data, but normal behaviour would be to call another function that would remove that object from a list. Another one would be if the function is probably not permanent in your library, and you don't want to people to become dependent on it. None of your function actually modify the data sent in the parameters. Nor does it modify any variables in the module's scope itself. It only reads and chucks out a response according to the state of those parameters. So it doesn't fall in the first example. It could arguably fall in the second one, this module isn't exactly stable enough to warrant that (yet). Why exactly do I want *most* of my functions public? (Though I concur with the points you posted below, as I'll be describing) Quote: Another reason is clarity. Your function names have nothing to do with 'draw'. Another thing is that boolean's as parameters can lead to some confusing code. Say you changed the name to drawCircleCollision. When you write code that calls this function: drawCircleCollision(cir1, cir2, false) Just glancing at that code, WITHOUT looking at the source of the collision module will confuse the reader into wondering what that parameter actually does. Where as: checkCircleCollision(cir1, cir2) drawAndCheckCircleCollision(cir1, cir2) ... Are more readable. Better explanation. I've never thought of it that way, and I have to agree. I now plan on reformatting my code, and I will definetly split that boolean parameter into two functions (drawCollsionX and CollisionX). [Yes, I read the article] Quote: Aange10 @ Sun Jan 22, 2012 2:41 pm wrote: I don't know about you, but I've had many occasions where collision was not working because of miss typed coordinates. Giving an option to draw what is being detected just makes it 100x easier to detect those mistypes. Having options is fine. Preventing them is not/annoying. What do you mean preventing them? Quote: ~ Also: circleToCircle(): The name of this method implies that it is used for two circles, when in fact it compares two ovals, THEN simplifies if they are in fact, circles. I made this module in mind of simplicity for the user. A lot of new users would overlook the differenses of an oval and a circle. Also, I wanted a function that would work for circles of changing dimensions. However that could be as simple as [in my games code, if I were making one]
So, I figure I should split the program into twelve functions?:
|
Author: | Zren [ Thu Jan 26, 2012 12:57 am ] | ||||||||||
Post subject: | Re: RE:[Module] Collision | ||||||||||
Aange10 @ Wed Jan 25, 2012 7:24 pm wrote: Zren @ 24/1/2012, 11:35 pm wrote: I mean you redid rectangle and circle collision tests instead of using your own functions... Just look at your circleXrect function:
No, that's two different if statements, not an elsif branch. It has to do with the little square in the picture you linked me. I know that. What I'm getting at is that they could be their own functions themselves as you used the same logic 3x and 4x respectively. Eg:
Aange10 @ Wed Jan 25, 2012 7:24 pm wrote: Quote: Ah sorry, now that I look at it, you really only just have a circle vs circle collision function. You could simplify that with twoPointsWithinDist(p1, p2, dist) which can be easily used for pointXcircle collision. twoPointsWithinDist(point, circle.center, cricle.radius). And also, for circleXcircle, twoPointsWithinDist(cir1.center, cir2.center, cir1.radius + cir2.radius). I already to check the distance between two points (and compare to the sum of radii). Line 27-32 is the entire circle collision process. You implement the logic yes, but if you wanted to use it for more than two ovals, you have to fill out useless parameters.
Your function doesn't even use the yRadiuses to begin with (which you imply that it would need as you force the user to supply them. To use it for two points (if we removed the already useless parameters), we'd need to enter 0 for one of the xRadiuses. Rather confusing eh? CircleCollision(p1.x, p1.y, dist, p2.x, p2.y, 0) Aange10 @ Wed Jan 25, 2012 7:24 pm wrote: Quote: Basically, you can simplify the code you have now as well as expand it to include shape colliding with a point.
I guess I don't understand what you mean; I don't see where checking the distance between point A and B, and comparing it something C, is any use. If anything I already utilize that. Eg: Does the mouse collide with the object? You also used that subroutine repeatedly (as I mentioned above). Aange10 @ Wed Jan 25, 2012 7:24 pm wrote: Quote: Which is really where you should have been starting from, not complex shape vs complex shape. After all, mouse coordinates are points, making it silly that a user would need to write his own methods for colliding with points. So sorry, I misread how you implemented your functions.
I'm really not sure what you mean. I didn't start from complex vs complex. Understandably, circles, ovals, and rectangles are as basic as it gets. The only less is comparing two points, which is if point1X = point2X and point1Y = point2Y then. So, I don't see why it is silly that a user would write their own methods for colliding with points...? 0D collisions are rather useless. So I'll agree on that point. 1D collisions are used all the time. They are what you use to build 2D collisions with. Point collides with range on single axis. Range collides with range. Though admittedly, turning those into function is useless for the average user of this module. As if they require functions to do that, they need to learn how collisions work first. The only thing in difficulty between point vs point and shape vs shape IS point vs shape (and line vs shape). You do use point collides with [insert 2D shape] in your own module (even if it isn't a function yet). Quote: I'm sure we have some confusion between us here. Here is basically how the program works thus far:
I edited in the parts where you actually use collision with points. Quote: Why exactly do I want *most* of my functions public? (Though I concur with the points you posted below, as I'll be describing) As they relate to the Collision detection, which is the point of the module. [quote] Quote: Having options is fine. Preventing them is not/annoying. What do you mean preventing them? Quote: Uhg. I dug myself into a hole for this one. I'll retract that statement. Quote: I made this module in mind of simplicity for the user. A lot of new users would overlook the differenses of an oval and a circle. Also, I wanted a function that would work for circles of changing dimensions. ... So, I figure I should split the program into twelve functions?:
Looks good (nudges at collisions with points). The confusion/error of a user is less likely to happen since the drawing functions are called Draw.Oval(). Not too mention they'll distinguish that there IS a difference when the look at the list of functions available. |
Author: | Aange10 [ Fri Jan 27, 2012 9:38 pm ] | ||||
Post subject: | Re: RE:[Module] Collision | ||||
Zren @ 25/1/2012, 11:57 pm wrote: You implement the logic yes, but if you wanted to use it for more than two ovals, you have to fill out useless parameters.
Your function doesn't even use the yRadiuses to begin with (which you imply that it would need as you force the user to supply them. To use it for two points (if we removed the already useless parameters), we'd need to enter 0 for one of the xRadiuses. Rather confusing eh? With the new functions that parameter problem should be resolved. Quote: I edited in the parts where you actually use collision with points. Relatively close to what I have now... Quote: Looks good (nudges at collisions with points). The confusion/error of a user is less likely to happen since the drawing functions are called Draw.Oval(). Not too mention they'll distinguish that there IS a difference when the look at the list of functions available. Added - Here is the new list:
I kept all the parameters in order of the name. (I.E circleToRectangle will require Circle parameters first, then Rectangle parameters) I'd honestly like to find a better Oval Vs Oval collision algorithm. I've found this one to be the same as making a bounding box (because it really is), which is inaccurate. I also plan on remaking the testing program, because it is absolutely disgusting to work with. It's a mess of copy and pasting. But I'll fix that before my next update, or before my final post. |