Velocity and Collisions

Started by
4 comments, last by Geometrian 16 years, 2 months ago
Hi: I found this: http://blog.generalrelativity.org/?p=7 I'm trying to figure out how to do sphere collisions, so I need something like this in 3D. I have two spheres each with positions x,y,z and with velocity xv,yv,zv. Since the spheres will not move very much in-between collision detects, the collision detection in the link, which finds the point at which the spheres crash, is unnecessary. I've researched this here on Gamedev, but I only came up with stuff about dot products. I don't know how to do that in Python (I'm using Python). I need some simple code to bounce the velocities. Can anyone do that? (Python code is obviously preferred). Thanks, Geometrian

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Advertisement
Generic dot product in python for vectors of any size:

def dot(v1,v2):  return sum(x*y for x,y in zip(v1, v2))

Replacing zip with izip from the itertools package may improve performance.
Great! What code should I do with this to make 3D sphere collisions?
About performance, the collision shouldn't happen too often, so a small temporary lag in fps is acceptable. Not to say I won't look into it...
G

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Look at this article. Equation 5 at the bottom of the first page is a very direct formula for finding the impulse in a collision between two spheres.

Note that most of the variables in that formula and the result are vectors. Writing some simple vector manipulating functions or using a vector library can simplify the code and make it look closer to the original formula (instead of writing out parallel manipulations of each of the components).

Using zip instead of izip shouldn't affect performance in any significant way unless the vectors are large (your vectors only have three elements).
I looked at the page, but I think the very first formula was what I wanted. I just need the resultant vectors. So now, I have a mostly working model, but sometimes, two circles will collide and then merge, then oscillate. I have no idea why. The program is not even a hundred lines long!
Here's the code related to collisions:
def CircleCollide(C1,C2):    C1Speed = math.sqrt((C1.speedx**2)+(C1.speedy**2))    XDiff = -(C1.x-C2.x)    YDiff = -(C1.y-C2.y)    if XDiff > 0:        if YDiff > 0:            Angle = math.degrees(math.atan(YDiff/XDiff))            XSpeed = -C1Speed*math.cos(math.radians(Angle))            YSpeed = -C1Speed*math.sin(math.radians(Angle))        elif YDiff < 0:            Angle = math.degrees(math.atan(YDiff/XDiff))            XSpeed = C1Speed*math.cos(math.radians(Angle))            YSpeed = C1Speed*math.sin(math.radians(Angle))    elif XDiff < 0:        if YDiff > 0:            Angle = 180 + math.degrees(math.atan(YDiff/XDiff))            XSpeed = C1Speed*math.cos(math.radians(Angle))            YSpeed = C1Speed*math.sin(math.radians(Angle))        elif YDiff < 0:            Angle = -180 + math.degrees(math.atan(YDiff/XDiff))            XSpeed = -C1Speed*math.cos(math.radians(Angle))            YSpeed = -C1Speed*math.sin(math.radians(Angle))    elif XDiff == 0:        if YDiff > 0:            Theta = 90        else:            Theta = -90        XSpeed = C1Speed*math.cos(math.radians(Angle))        YSpeed = C1Speed*math.sin(math.radians(Angle))    elif YDiff == 0:        if XDiff > 0:            Theta = 0        else:            Theta = 180        XSpeed = C1Speed*math.cos(math.radians(Angle))        YSpeed = C1Speed*math.sin(math.radians(Angle))    C1.speedx = XSpeed    C1.speedy = YSpeeddef CollisionDetect():    #Determine if the spheres are hitting the sides of the screen.  The screen is 800x600.    for Circle in Circles:        if Circle.x < Circle.radius or Circle.x > 800-Circle.radius:    Circle.speedx *= -1        if Circle.y < Circle.radius or Circle.y > 600-Circle.radius:    Circle.speedy *= -1    #Determine sphere to sphere collisions.    for Circle in Circles:        for Circle2 in Circles:            if Circle != Circle2:                if math.sqrt(  ((Circle.x-Circle2.x)**2)  +  ((Circle.y-Circle2.y)**2)  ) <= (Circle.radius+Circle2.radius):                    CircleCollide(Circle,Circle2)
CollisionDetect() is called from the main, once every frame.
Thanks,
G

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Just a stupid error. All fixed. The completed demo is here:
http://www.pygame.org/project/619/?release_id=1056
Thanks again!
Geometrian

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

This topic is closed to new replies.

Advertisement