src/Collision.js
/**
 * Test a sweep-circle against convex shape.
 *
 * @param {Circle}      circle        Circle used in test
 * @param {Vec2}        movement      Vector describing movement
 * @param {ConvexShape} shape         Shape to be tested against
 * @return {Collisions}               Collision objects that holds both contact points and intersection time.
 */
Test a sweep-circle against convex shape.
@param {Circle}      circle        Circle used in test
@param {Vec2}        movement      Vector describing movement
@param {ConvexShape} shape         Shape to be tested against
@return {Collisions}               Collision objects that holds both contact points and intersection time.
Test a sweep - circle against convex shape . @param { Circle } circle Circle used in test @param { Vec2 } movement Vector describing movement @param { ConvexShape } shape Shape to be tested against @return { Collisions } Collision objects that holds both contact points and intersection time .
function GetCollisionShape(circle, movement, shape) {
    var contactPoints = [];
    var foundOne = false;
    var minIntersectionTime = Number.MAX_VALUE;
    var localIntersectionTime = Number.MAX_VALUE;
    var i = 0;      
    var pt;         
    var contact;    
    if (shape.NumPoints() > 1) {
        pt = shape.points;
        for (i = 0; i < pt.length; i++) {
            var last = pt[i];
            var curr = i+1 === pt.length ? pt[0] : pt[i+1];
            var normal = new Vec2(-(curr.y - last.y), curr.x - last.x);
            if (0 < normal.Dot(movement)) { 
                continue; 
            }
            normal.Normalize();
            var _last = new Vec2(normal.x, normal.y);
            _last.mul(circle.r + SWEEP_EPSILON);
            _last.add(last);
            var _curr = new Vec2(normal.x, normal.y);
            _curr.mul(circle.r + SWEEP_EPSILON);
            _curr.add(curr);
            var endPos = new Vec2(circle.c.x, circle.c.y);
            endPos.add(movement);
            var localContact = new Vec2();
			var res = IntersectLineSegments(new LineSegment2(circle.c, endPos), new LineSegment2(_last, _curr));
			if (res) {
                if (res.intersectionTime < minIntersectionTime) {
                    foundOne = true;
                    minIntersectionTime = res.intersectionTime;
                    var _lc = new Vec2(normal.x, normal.y);
                    _lc.mul(circle.r);
                    res.intersectionPoint.sub(_lc);
                    contact = new CollisionContact(res.intersectionPoint, normal, 0, shape.user, shape.material);
                }
            }
        }
    }
    if (!foundOne) {
        pt = shape.points;
        for (i = 0; i < pt.length; i++) {
            localIntersectionTime = Number.MAX_VALUE; 
            var _mov = new Vec2(movement.x, movement.y);
            _mov.mul(1.1);
            if (IntersectRaySphere(new Ray2(circle.c, _mov), new Circle(pt[i], circle.r))) {
                localIntersectionTime = closure();
                if (localIntersectionTime < minIntersectionTime) {
                    foundOne = true;
                    minIntersectionTime = localIntersectionTime;
                    var _normal = new Vec2(movement.x, movement.y);
                    _normal.mul(localIntersectionTime);
                    _normal.sub(pt[i]);
                    _normal.add(circle.c);
					_normal.Normalize();
                    contact = new CollisionContact(pt[i], _normal, 0, shape.user, shape.material);
                }
            }
        }
    }
    if (foundOne) {
        contactPoints.push(contact);
        return new Collisions(contactPoints, minIntersectionTime);
    }
    else {
        return null;
    }
}
function GetCollisionShape ( circle , movement , shape ) { var contactPoints = [ ] ; var foundOne = false ; var minIntersectionTime = Number . MAX_VALUE ; var localIntersectionTime = Number . MAX_VALUE ; var i = 0 ; var pt ; var contact ; if ( shape . NumPoints ( ) > 1 ) { pt = shape . points ; for ( i = 0 ; i < pt . length ; i ++ ) { var last = pt [ i ] ; var curr = i + 1 === pt . length ? pt [ 0 ] : pt [ i + 1 ] ; var normal = new Vec2 ( - ( curr . y - last . y ) , curr . x - last . x ) ; if ( 0 < normal . Dot ( movement ) ) { continue ; } normal . Normalize ( ) ; var _last = new Vec2 ( normal . x , normal . y ) ; _last . mul ( circle . r + SWEEP_EPSILON ) ; _last . add ( last ) ; var _curr = new Vec2 ( normal . x , normal . y ) ; _curr . mul ( circle . r + SWEEP_EPSILON ) ; _curr . add ( curr ) ; var endPos = new Vec2 ( circle . c . x , circle . c . y ) ; endPos . add ( movement ) ; var localContact = new Vec2 ( ) ; var res = IntersectLineSegments ( new LineSegment2 ( circle . c , endPos ) , new LineSegment2 ( _last , _curr ) ) ; if ( res ) { if ( res . intersectionTime < minIntersectionTime ) { foundOne = true ; minIntersectionTime = res . intersectionTime ; var _lc = new Vec2 ( normal . x , normal . y ) ; _lc . mul ( circle . r ) ; res . intersectionPoint . sub ( _lc ) ; contact = new CollisionContact ( res . intersectionPoint , normal , 0 , shape . user , shape . material ) ; } } } } if ( ! foundOne ) { pt = shape . points ; for ( i = 0 ; i < pt . length ; i ++ ) { localIntersectionTime = Number . MAX_VALUE ; var _mov = new Vec2 ( movement . x , movement . y ) ; _mov . mul ( 1.1 ) ; if ( IntersectRaySphere ( new Ray2 ( circle . c , _mov ) , new Circle ( pt [ i ] , circle . r ) ) ) { localIntersectionTime = closure ( ) ; if ( localIntersectionTime < minIntersectionTime ) { foundOne = true ; minIntersectionTime = localIntersectionTime ; var _normal = new Vec2 ( movement . x , movement . y ) ; _normal . mul ( localIntersectionTime ) ; _normal . sub ( pt [ i ] ) ; _normal . add ( circle . c ) ; _normal . Normalize ( ) ; contact = new CollisionContact ( pt [ i ] , _normal , 0 , shape . user , shape . material ) ; } } } } if ( foundOne ) { contactPoints . push ( contact ) ; return new Collisions ( contactPoints , minIntersectionTime ) ; } else { return null ; } }
Test a sweep-circle against convex shape.
Test a sweep - circle against convex shape .
// Used for iteration // Handle during loops // Placeholder for eventual contact point // last & curr is now start and end points of the line. // last = last + normal * (circle.r + SWEEP_EPSILON) // curr = curr + normal * (circle.r + SWEEP_EPSILON) // localContact - normal * circle.r // Multiply the length of the ray to make sure that the spheres won't go // through each other at extremely low speeds // Got collision. // circle.c + localIntersectionTime * movement - pt[i] // Contact point is the vertex. // Normal is vector from corner to position of sphere at collision time.