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

Username:   Password: 
 RegisterRegister   
 Collision Detection with distance from point to line segment
Index -> Programming, Turing -> Turing Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
PhOtO!




PostPosted: Sun Jun 18, 2006 2:38 pm   Post subject: Collision Detection with distance from point to line segment

Me and my partner are working on this air hockey game for our final project (Air Hockey). We're almost done our program but we have problems with our collision detection (which is using distance between 2 circles) when users move thier paddle too fast. This is because the computer can not pick up on all of the movements of the mouse.
So, we are going to make a variable for the previous mouse position and a variable for the current mouse position. Then we are going to make an imaginary line from those two points (y = mx + b). Now, we want to see if the distance from our ball (another circle) to the closest point on our imaginary line segment is less than 50 (then the mouse has gone through the ball). However, we don't know the formula for the distance from a point to a line segment. Also, could you tell us if this will work or if there are much more efficent ways.

If you need the source code, just tell me.

Thanks for any help
Sponsor
Sponsor
Sponsor
sponsor
PhOtO!




PostPosted: Sun Jun 18, 2006 3:17 pm   Post subject: (No subject)

Actually, here is the source code :

code:
setscreen ("graphics:700;max,position:center;center,nobuttonbar,offscreenonly")
var x, y, button, paddlex, paddley := 100
var cpux, cpuy := maxx div 2 % x and y value of paddle
var ballx, bally : real := 100 % x and y value of ball
var dx, dy : real := 0 % difference in x and y value for ball
var cpuxd, cpuyd := 1 % difference in x and y value for comp paddle
var maxspeed := 3 % maximum speed for comp paddle
var numofhits : int := 0
var maxballspeed : int := 3
var a, b : int := 0
var paddler : int := 35
var ballr : int := 30
cpuy := maxy - 100
ballx := maxx div 2
bally := maxy div 2

proc drawscreen
    drawfillbox (0, 0, maxx, maxy, red) % Border
    drawfillbox (20, 20, maxx - 20, maxy - 20, 1) %Background
    drawfillbox (20, maxy div 2 - 150, maxx - 20, maxy div 2 - 155, red) % bottom line from center
    drawfillbox (20, maxy div 2 + 150, maxx - 20, maxy div 2 + 155, red) % top line from center
    drawfillbox (20, 20, maxx - 20, 30, grey) % bottom
    drawfillbox (maxx div 2 - 70, 20, maxx div 2 + 70, 40, black) % net
    drawfillbox (20, maxy - 20, maxx - 20, maxy - 30, grey) % top
    drawfillbox (maxx div 2 - 70, maxy - 20, maxx div 2 + 70, maxy - 40, black) % net
    drawfillbox (20, maxy div 2, maxx - 20, maxy div 2 + 5, grey) %center line
    %Center Circle
    drawfilloval (maxx div 2, maxy div 2, 80, 80, grey)
    drawfilloval (maxx div 2, maxy div 2, 70, 70, 1)
    drawfilloval (maxx div 2, maxy div 2, 10, 10, grey)
    % Left top circle
    drawfilloval (maxx div 2 - 200, maxy div 2 + 250, 70, 70, grey)
    drawfilloval (maxx div 2 - 200, maxy div 2 + 250, 60, 60, 1)
    % Right top circle
    drawfilloval (maxx div 2 + 200, maxy div 2 + 250, 70, 70, grey)
    drawfilloval (maxx div 2 + 200, maxy div 2 + 250, 60, 60, 1)
    % Right bottom
    drawfilloval (maxx div 2 + 200, maxy div 2 - 250, 70, 70, grey)
    drawfilloval (maxx div 2 + 200, maxy div 2 - 250, 60, 60, 1)
    % Left bottom
    drawfilloval (maxx div 2 - 200, maxy div 2 - 250, 70, 70, grey)
    drawfilloval (maxx div 2 - 200, maxy div 2 - 250, 60, 60, 1)
    %ball
    if ballx > 35 and ballx < maxx - 35 and bally > 35 and bally < maxy - 35 then
        drawfilloval (round (ballx), round (bally), ballr, ballr, black)
    end if
    %paddle
    drawfilloval (paddlex, paddley, paddler, paddler, 12)
    drawfilloval (cpux, cpuy, paddler, paddler, 12)
    locate (1, 1)
    put "Computer score:", a
    locate (1, 30)
    put "Player score:", b
    View.Update
end drawscreen

proc detection
    %if the ball hits either end then make it go in the opposite direction
    if ballx > maxx - 35 then
        dx := abs (dx) * -1
    elsif ballx < 35 then
        dx := abs (dx)
    end if
    %if the ball hits either side then make it go in the opposite direction
    if bally > maxy - 35 then
        dy := abs (dy) * -1
    elsif bally < 35 then
        dy := abs (dy)
    end if
   
    %if the distance between the ball and the paddle is less than 50 (touching) then change direction
    if abs (sqrt ((ballx - paddlex) ** 2 + (bally - paddley) ** 2)) < 50 then
        dx := (ballx - paddlex) / 10    %the ball will go back in the same direction at the same
        dy := (bally - paddley) / 10    %angle at which it came into the paddle
    end if

    if (sqrt ((ballx - cpux) ** 2 + (bally - cpuy) ** 2)) < paddler + ballr then
        dx := (ballx - cpux) / 10
        dy := (bally - cpuy) / 10
        numofhits := numofhits + 1
    end if
end detection



loop
    if bally < maxy - 75 then
        numofhits := 0
    end if
    if numofhits > 3 then
        cpux := maxx div 2
    end if


    %USER PADDLE
    mousewhere (x, y, button)
    if y + paddler > maxy div 2 then  %if the mouse is above the center line, the paddle stays at center line
        paddley := maxy div 2 - paddler
    elsif y < paddler + 20 then
        paddley := paddler + 20
    else
        paddley := y
    end if
    if x > maxx - paddler + 20 then    %if the mouse is off the screen to the right then make the paddle be at the
        paddlex := maxx - (paddler + 20) %furthest point horizontally on the screen (maxx)
    elsif x < paddler + 20 then     %**same as above but for the left side**
        paddlex := paddler + 20
    else
        paddlex := x
    end if

    %BALL MOVEMENT
    ballx += dx %make the ball move
    bally += dy %""

    %COMPUTER PADDLE
    cpux := cpux + cpuxd % makes comp paddle move

    if cpux > ballx then % checks if cpu x coordinate is greater than ball x coordinate
        cpuxd := cpuxd - 1 % comp paddle x value moves negative direction
    elsif
            cpux < ballx then % checks if cpu x coordinate is less than ball x coordinate
        cpuxd := cpuxd + 1 % comp paddle x value moves positive direction
    end if



    % Computer paddle speed doesn't go past assigned maximum speed
    if cpuxd > maxspeed then %
        cpuxd := maxspeed
    elsif cpuxd < maxspeed * -1 then
        cpuxd := maxspeed * -1
    end if

    % Keeps computer paddle inside the table
    if cpux > maxx - 100 then
        cpux := maxx - 100
    elsif
            cpux < 100 then
        cpux := 100
    end if


    detection

    if ballx > maxx div 2 - 70 and ballx < maxx div 2 + 70 and bally < 35 then
        a := a + 1
        ballx := maxx div 2
        bally := maxy div 2
        delay (500)
    elsif ballx > maxx div 2 - 70 and ballx < maxx div 2 + 70 and bally > maxy - 35 then
        b := b + 1
        ballx := maxx div 2
        bally := maxy div 2
        delay (500)
    end if
    drawscreen

end loop
[Gandalf]




PostPosted: Sun Jun 18, 2006 3:21 pm   Post subject: (No subject)

Check out the Math.DistancePointLine() function in the Turing help files. Also, here are two topics/posts you may want to read:
this and
this
PhOtO!




PostPosted: Sun Jun 18, 2006 3:26 pm   Post subject: (No subject)

I have version 4.01 so I don't have this funtion. Can you please post up the actual function?
[Gandalf]




PostPosted: Sun Jun 18, 2006 3:30 pm   Post subject: (No subject)

Sure thing. Smile

code:
function MathDistance (x1, y1, x2, y2 : real) : real
    var dx : real := x1 - x2
    var dy : real := y1 - y2
    result sqrt (dx * dx + dy * dy)
end MathDistance

function MathDistancePointLine (px, py, x1, y1, x2, y2 : real) : real
    var lineSize : real := MathDistance (x1, y1, x2, y2)
    if lineSize = 0 then
        result MathDistance (px, py, x1, y1)
    end if

    var u : real := ((px - x1) * (x2 - x1) +
        (py - y1) * (y2 - y1)) / (lineSize * lineSize)

    if u < 0.0 then
        result MathDistance (px, py, x1, y1)
    elsif u > 1.0 then
        result MathDistance (px, py, x2, y2)
    else
        var ix : real := x1 + u * (x2 - x1)
        var iy : real := y1 + u * (y2 - y1)
        result MathDistance (px, py, ix, iy)
    end if
end MathDistancePointLine

You will also need MathDistance because MathDistancePointLine makes use of it.
PhOtO!




PostPosted: Sun Jun 18, 2006 4:01 pm   Post subject: (No subject)

Thanks alot Gandalf

We decided that we're gonna finish a simple space frogger game for the final project since we have many more glitches with the air hockey program.

But we'll continue working on that and post it up soon.
upthescale




PostPosted: Sun Jun 18, 2006 4:57 pm   Post subject: (No subject)

how wud the space frogger werk? anyway awsome game
PhOtO!




PostPosted: Sun Jun 18, 2006 7:20 pm   Post subject: (No subject)

It's just a simple frogger version. We didnt' add alot of things we planned to add. We'll probably post it up tommorow.
Sponsor
Sponsor
Sponsor
sponsor
Display posts from previous:   
   Index -> Programming, Turing -> Turing Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 8 Posts ]
Jump to:   


Style:  
Search: