sprite collision


[ Zettels Traum ] [ search / suche ]

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.



--



Dazu:























D. Plänitz