Closest point on a line segment
HTML
<script src="https://rawgithub.com/soulwire/sketch.js/master/js/sketch.js"></script>
CSS
html, body {
margin: 0;
}
JavaScript
var A, B;
function project( p, a, b ) {
var atob = { x: b.x - a.x, y: b.y - a.y };
var atop = { x: p.x - a.x, y: p.y - a.y };
var len = atob.x * atob.x + atob.y * atob.y;
var dot = atop.x * atob.x + atop.y * atob.y;
var t = min( 1, max( 0, dot / len ) );
dot = ( b.x - a.x ) * ( p.y - a.y ) - ( b.y - a.y ) * ( p.x - a.x );
return {
point: {
x: a.x + atob.x * t,
y: a.y + atob.y * t
},
left: dot < 1,
dot: dot,
t: t
};
}
function makeLine( mx, my ) {
A = { x: random( 20, mx - 40 ), y: random( 20, my - 40 ) };
B = { x: random( 20, mx - 40 ), y: random( 20, my - 40 ) };
}
Sketch.create({
setup: function() {
makeLine( this.width, this.height );
},
draw: function() {
// render line
this.beginPath();
this.moveTo( A.x, A.y );
this.lineTo( B.x, B.y );
this.stroke();
this.fillText( 'A', A.x, A.y );
this.fillText( 'B', B.x, B.y );
// render point
this.beginPath();
this.arc( this.mouse.x, this.mouse.y, 5, 0, TWO_PI );
this.stroke();
// nearest point
var data = project( this.mouse, A, B );
this.beginPath();
this.arc( data.point.x, data.point.y, 5, 0, TWO_PI );
this.stroke();
this.fillText( 'dot: ' + data.left, data.point.x + 10, data.point.y - 12 );
this.fillText( 'data: ' + data.dot.toFixed(3), data.point.x + 10, data.point.y );
this.fillText( 't: ' + data.t.toFixed(3), data.point.x + 10, data.point.y + 12 );
},
click: function() {
makeLine( this.width, this.height );
}
});