Collision test

by mvasilkov

HTML

<canvas id=c></canvas>

CSS

canvas {
    background: #101010
}

JavaScript

function wtfcmp(wall, ab) {
    return (
        ((ab[2] - ab[0]) * (wall[1] - ab[1]) -
         (ab[3] - ab[1]) * (wall[0] - ab[0]))
        *
        ((ab[2] - ab[0]) * (wall[3] - ab[1]) -
         (ab[3] - ab[1]) * (wall[2] - ab[0])))
}

function determinant(a, b) {
    return a[0] * b[1] - b[0] * a[1]
}

function insideP(pos, future, wall) {
    var pq = [pos[2] - pos[0], 0]
    var pr = [future[0] - pos[0], future[1] - pos[1]]
    var d = determinant(pq, pr)
    
    var wall0 = [
        wall[0] - pos[0], wall[1] - pos[1],
        wall[2] - pos[0], wall[3] - pos[1]
    ]
    
    var foo = -determinant([wall0[0], wall0[1]], pq) / d
    var bar = determinant([wall0[0], wall0[1]], pr) / d

    /*
    var foo1 = -determinant([wall[2], wall[3]], pq) / d
    var bar1 = determinant([wall[2], wall[3]], pr) / d
    */
    
    return (0 <= foo && foo <= 1 && 0 <= bar && bar <= 1)
}

function collisionTest(pos, future, wall) {
    
    if ((wall[1] < pos[1]) == (wall[1] < future[1]))
        return false
    
    var ab0 = [
        pos[0], pos[1],
        future[0], future[1]
    ]
    var ab1 = [
        pos[2], pos[3],
        future[2], future[3]
    ]
    
    if (wtfcmp(wall, ab0) > 0 && wtfcmp(wall, ab1) > 0 &&
        !insideP(pos, future, wall)) return false
    
    return true
}



















/* canvas */

var c = document.getElementById('c')
var canvas = c.getContext('2d')

c.height = c.width = 500

/* movement parallelogram */

var middle = 250
var baselinex = 300 * Math.random() + 50
var baselinelength = 50 * Math.random() + 50
var movementx = 40 * Math.random() + 20
var movementy = 100 * (2 * Math.random() - 1 > 0 ? 1 : -1)

var baseline = [
    baselinex, middle,
    baselinex + baselinelength, middle
]
var movement = [
    baselinex + movementx, middle + movementy,
    baselinex + baselinelength + movementx, middle + movementy
]

/* paint movement parallelogram */

canvas.translate(0.5, 0.5)

canvas.beginPath()
canvas.moveTo(baseline[0],...