von dp am 23.August 98 um 20:50:36:
zu: intersecting sprites von dp am 23.August 98 um 20:38:36:
--
From: Brian Gray--Subject: Re: Collisions in Shockwave To: DIRECT-L@UAFSYSB.UARK.EDU Franco G. Chierchini wrote: >This first movie shows some 2D circular objects bouncing into a rectangular >frame in absence of gravity. Collisions happen in accordance with the law >of the linear momentum conservation for insulated systems. Hey, would you mind discussing code strategies? Every once in a while I look at expanding my own action game script collection, and it usually comes down to efficient handling of physical properties. How are you computing the collisions themselves? 1/2m1v1^2 = 1/2m2v2^2? m1v1 = m2v2? Are there coefficients for elasticity and kinetic/static friction? Here's how I do it currently; when I detect a collision (squared length of the difference vector < squared sum of the radii) I back up both objects until they are just barely touching. Then I split the velocity vectors into parallel and perpendicular components and transfer the parallels to each other. This works well as long as I remember to use momentum as a scaled product rather than just velocity. Here's my 2D vector class as it applies here: -- script "vector2d" property x, y on new me, aX, aY set x = aX set y = aY return me end -- Supplies the vector sum of two vectors on add me, you, sum set the x of sum = the x of me + the x of you set the y of sum = the y of me + the y of you end -- Supplies the vector difference of two vectors on subtract me, you, difference set the x of difference = the x of me - the x of you set the y of difference = the y of me - the y of you end -- Supplies the vector product of a vector and a scalar on multiply me, scalar, product set the x of product = the x of me * scalar set the y of product = the y of me * scalar end -- Supplies the vector quotient of a vector and a scalar on divide me, scalar, quotient set the x of quotient = the x of me / scalar set the y of quotient = the y of me / scalar end -- Returns the scalar product of two vectors on dotProduct me, you return the x of me * the x of you + the y of me * the y of you end -- Returns the scalar squared magnitude of a vector on lengthSq me return the x of me * the x of me + the y of me * the y of me end -- Returns a vector parallel to the combination of two vectors on getParallel me, you, parallel set the x of parallel = the y of me - the y of you set the y of parallel = the x of you - the x of me end -- Takes a vector (me) and splits it into vector components parallel -- (par) and perpendicular(perp) to a second vector (you) on split me, you, par, perp set length2 = lengthSq(you) set dp = dotProduct(me, you) multiply(you, (dp/length2), par) subtract(me, par, perp) end -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Thus to collide two normally-created ball objects in the absence of friction, inelasticity, and non-perfect shapes (properties: #mass (scalar), #radius (scalar), #pos (vector), #velocity (vector)): -- This is in my "ball" class on collide me, you if range(me, you) then -- If they collide separate(me, you) -- move them back until they don't -- Create a help line parallel to the contact tangent set parHelp = new(script "vector2d") getParallel(the pos of me, the pos of you, parHelp) -- Trade in our velocities for scaled momentum vectors set myMomentum = new(script "vector2d") set yourMomentum = new(script "vector2d") multiply(the velocity of me, the mass of me, myMomentum) multiply(the velocity of you, the mass of you, yourMomentum) -- Obtain momentum components parallel and perpendicular to the -- collision set p1 = new(script "vector2d") set n1 = new(script "vector2d") set p2 = new(script "vector2d") set n2 = new(script "vector2d") split(myMomentum, parHelp, p1, n1) split(yourMomentum, parHelp, p2, n2) -- Trade parallel components, keep perpendicular add(p1, n2, myMomentum) add(p2, n1, yourMomentum) -- Scale back to velocities divide(myMomentum, the mass of me, the velocity of me) divide(yourMomentum, the mass of you, the velocity of you) end if end -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ...so now I've shown you a glimpse of how I did it. How about we all compare notes and find out if this is or is not the best way? I'm always in the mood to find some cool efficient shortcuts. BTW, I have 2D, 3D and n-vector classes. Unfortunately, I've never studied linear algebra so I'm kind of shooting from the hip here. Anyone have a good cross-product implementation? I was thinking of expanding n-vector to a nxm matrix, but I don't have the math background for all the required transformations. I DO know that a vector can be described as a 1xn matrix, so some of my math should apply. -- Brian P.S. -- You may notice I tend to return scalar values and just fill in vectors. This is mainly because objects are passed by reference, but also because I often need to supply more than one value back to the caller. Is everyone comfortable with this way of thinking? I know it's not as common in Lingo as it would be in other languages. To be consistent, I'd love to do scalars the same way, but can't figure out how other than using 1-item lists. And that just gets bulky.
D. Plänitz