Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 [Module] Collision
Index -> Programming, Turing -> Turing Tutorials
Goto page Previous  1, 2
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Aange10




PostPosted: 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 Wink


EDIT: I also changed the circle to circle collision to not use Square roots.



Collision.rar
 Description:

Download
 Filename:  Collision.rar
 Filesize:  3.08 KB
 Downloaded:  258 Time(s)

Sponsor
Sponsor
Sponsor
sponsor
Zren




PostPosted: 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. >:]
Aange10




PostPosted: 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. >:]

>Very Happy Good, I've learned a lot already xD
Aange10




PostPosted: Tue Jan 24, 2012 10:21 pm   Post subject: RE:[Module] Collision

A response would be appreciated Smile
Zren




PostPosted: 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:

Turing:

if circleX >= recX1 - radius and circleY >= recY1 - radius and circleX <= recX2 + radius and circleY <= recY2 + radius then

...

elsif (circleX - recX1) ** 2 + (circleY - recY1) ** 2 <= radius ** 2 then

...


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.
Aange10




PostPosted: 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:

Turing:

if circleX >= recX1 - radius and circleY >= recY1 - radius and circleX <= recX2 + radius and circleY <= recY2 + radius then

...

elsif (circleX - recX1) ** 2 + (circleY - recY1) ** 2 <= radius ** 2 then

...



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:
Turing:

    {parameters called}
        [CircleToCircle]
         * Detect if its a circle or an oval.
            () If its a circle check the differense between the distacne and the sum of the radii
                - Output result
            () If one or both circles are an oval, create bounding boxes for them
                - Output results by detecting the bounding boxes as rectangleToRectangle
        [RectangleToRectangle]
        * Make sure the points are in the correct order
            () If they are not in the correct order, it fixes them.
                - Output results based on the detection Mir showed us
            () If they are in the correct order
                - Outputs results based on the detection Mir showed us
        [RectangleToCircle]
        * Check the 'Circle' to see if its an oval or not
            () If it's an oval
                - Create a bounding box
                    & Output results by detecting the bounding box as a rectangle in rectangleToRectangle
            () If it'
s a circle
                - Check to see if the center point is close to the box
                    & See if the center point is in the box
                        # Output true
                    & See if the circle is within its own radius from any of the corners
                        # Output true
                    & otherwise
                        # Output false
                - otherwise
                    & Output false


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]
code:

if radi1 = radi2 then
 circleToCircle
else
circleToOval
end if



So, I figure I should split the program into twelve functions?:

Turing:

    Collision.circleToCircle
    Collision.circleToOval
    Collision.ovalToOval
    Collision.rectangleToRectangle
    Collision.circleToRectangle
    Collision.ovalToRectangle
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    Collision.drawCircleToCircle
    Collision.drawCircleToOval
    Collision.drawOvalToOval
    Collision.drawRectangleToRectangle
    Collision.drawCircleToRectangle
    Collision.drawOvalToRectangle
Zren




PostPosted: 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:

Turing:

if circleX >= recX1 - radius and circleY >= recY1 - radius and circleX <= recX2 + radius and circleY <= recY2 + radius then

...

elsif (circleX - recX1) ** 2 + (circleY - recY1) ** 2 <= radius ** 2 then

...



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:

Turing:

if isPointInRectangle(px, py, rectX1, rectY1, rectX2, rectY2) then
....
elsif isPointInCircle(px, py, circleX, circleY, circleRadius) then


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.
Turing:

    fcn CircleCollision (x1, y1, xRadius1, yRadius1, x2, y2, xRadius2, yRadius2 : int) : boolean
        var distance : real
        % Collision detection
        distance := sqrt ((x2 - x1) ** 2 + (y2 - y1) ** 2)
        if distance <= xRadius1 + xRadius2 then
            result true
        end if
        result false
    end CircleCollision

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:
Turing:

            () If it's a circle
                - Check to see if the center point is close to the box
                    & See if the center point is in the box (pointInRectangle)
                        # Output true
                    & See if the circle is within its own radius from any of the corners (See if pointA and pointB are within xDistance)
                        # Output true
                    & otherwise
                        # Output false
                - otherwise
                    & Output false
 



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

Turing:

    Collision.circleToCircle
    Collision.circleToOval
    Collision.ovalToOval
    Collision.rectangleToRectangle
    Collision.circleToRectangle
    Collision.ovalToRectangle
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    Collision.drawCircleToCircle
    Collision.drawCircleToOval
    Collision.drawOvalToOval
    Collision.drawRectangleToRectangle
    Collision.drawCircleToRectangle
    Collision.drawOvalToRectangle


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.
Aange10




PostPosted: 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.
Turing:

    fcn CircleCollision (x1, y1, xRadius1, yRadius1, x2, y2, xRadius2, yRadius2 : int) : boolean
        var distance : real
        % Collision detection
        distance := sqrt ((x2 - x1) ** 2 + (y2 - y1) ** 2)
        if distance <= xRadius1 + xRadius2 then
            result true
        end if
        result false
    end CircleCollision

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:

Turing:

% Points
Collision.isPointInCircle (pointX, pointY, circleX, circleY, circleRadius : int) : boolean
Collision.isPointInOval (pointX, pointY, circleX, circleY, circleXRadius, circleYRadius : int) : boolean
Collision.isPointInRectangle (pointX, pointY, rectangleX1, rectangleY1, rectangleX2, rectangleY2 : int) : boolean
Collision.are2PointsWithinDistance (point1X, point1Y, point2X, point2Y, distance : int) : boolean
% Collision
Collision.circleToCircle (circle1X, circle1Y, circle1Radius, circle2X, circle2Y, circle2Radius : int) : boolean
Collision.circleToOval (circleX, circleY, circleRadius, ovalX, ovalY, ovalXRadius, ovalYRadius : int) : boolean
Collision.rectangleToRectangle (box1_x1, box1_y1, box1_x2, box1_y2, box2_x1, box2_y1, box2_x2, box2_y2 : int) : boolean
Collision.circleToRectangle (circleX, circleY, circleRadius, recX1, recY1, recX2, recY2 : int) : boolean
Collision.ovalToRectangle (ovalX, ovalY, ovalXRadius, ovalYRadius, recX1, recY1, recX2, recY2 : int) : boolean
Collision.ovalToOval (oval1X, oval1Y, oval1XRadius, oval1YRadius, oval2X, oval2Y, oval2XRadius, oval2YRadius : int) : boolean
% Drawing (Collision)
Collision.drawOvalToOval (oval1X, oval1Y, oval1XRadius, oval1YRadius, oval2X, oval2Y, oval2XRadius, oval2YRadius : int)
Collision.drawOvalToRectangle (ovalX, ovalY, ovalXRadius, ovalYRadius, recX1, recY1, recX2, recY2 : int)
Collision.drawCircleToRectangle (circleX, circleY, radius,recX1, recY1, recX2, recY2 : int)
Collision.drawRectangleToRectangle (box1_x1, box1_y1, box1_x2, box1_y2, box2_x1, box2_y1, box2_x2, box2_y2 : int)
Collision.drawCircleToOval (circleX, circleY, circleRadius, ovalX, ovalY, ovalXRadius, ovalYRadius : int)
Collision.drawCircleToCircle (circle1X, circle1Y, circle1Radius, circle2X, circle2Y, circle2Radius : int)


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.



Collision.rar
 Description:

Download
 Filename:  Collision.rar
 Filesize:  3.46 KB
 Downloaded:  260 Time(s)

Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> Programming, Turing -> Turing Tutorials
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 2 of 2  [ 23 Posts ]
Goto page Previous  1, 2
Jump to:   


Style:  
Search: