Point-Line Collision
by makurell
HTML
<canvas id="c"></canvas>
CSS
* { margin:0; padding:0; }
html, body { width:100%; height:100%; }
canvas { display:block; }
JavaScript
var c = document.getElementById('c'),
cx = c.getContext('2d');
var t = 0; //gametime
var speed = 1; //gamespeed
var fps = 120;//max is 1000
var f = 1000.0/fps*speed;
var balls=[];//list of ball objects
var lines=[];
function newBall(x,y,vx=0,vy=0){
return {
x:x,
y:y,
m:20,//mass
r:20,
vx:vx,
vy:vy,
w:1,//width
}
}
function newLine(x1,y1,x2,y2){
return {
x1:x1,
y1:y1,
x2:x2,
y2:y2,
w:1,//width
}
}
function init(){
lines.push(newLine(300,30,400,550));
lines.push(newLine(30,650,400,550));
balls.push(newBall(30,30,0.7,0.3));
}
function update(){
for(var i=0; i<balls.length; i++){
var ball=balls[i];
//collision with line
for(var j=0; j<lines.length; j++){
var line=lines[j];
if(distPS(ball.x+ball.vx*f,ball.y+ball.vy*f,line.x1,line.y1,line.x2,line.y2)<ball.r){
//collided
//store ball vel magnitude
var mag=Math.sqrt(Math.pow(ball.vx,2)+Math.pow(ball.vy,2));
//compute n
var d = dist(line.x1,line.y1,line.x2,line.y2);
var nx = (line.y1-line.y2)/d;
var ny = (line.x2-line.x1)/d;
//console.log({nx,ny});
//split ball vel into components:
var ux=(ball.vx*nx+ball.vy*ny/nx*nx+ny*ny)/nx;
var uy=(ball.vx*nx+ball.vy*ny/nx*nx+ny*ny)/ny;
var wx=ball.vx-ux;
var wy=ball.vy-uy;
//compute resultant vel
rx=(wx-ux);
ry=(wy-uy);
//compute k (constant to result in same mag)
var k = (mag*Math.sqrt(Math.pow(rx,2)+Math.pow(ry,2)))/(Math.pow(rx,2)+Math.pow(ry,2));
//apply vel
ball.vx=k*rx;
ball.vy=k*ry;
}
}
//updt vels
ball.x=ball.x+ball.vx*f;
ball.y=ball.y+ball.vy*f;
}
}
function draw(){
for(var i=0; i<lines.length;i++){
drawLine(lines[i]);
}
for(var i=0; i<balls.length;i++){
drawBall(balls[i]);
}
}
function drawLine(line){
cx.beginPath();
...