Segment-Circle Intersection

by makurell

HTML

<canvas id='c' width='1000' height='1000'></canvas>

JavaScript

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

//circle vars
var cx = 400;
var cy = 160;
var r = 60;

//seg vars
var ax = 300;
var ay = 100;
var bx = 350;
var by = 300;

// draw line
ctx.beginPath();
ctx.moveTo(ax,ay);
ctx.lineTo(bx,by);
ctx.stroke();

// draw circle
ctx.beginPath();
ctx.arc(cx, cy, r, 0, 2 * Math.PI);
ctx.stroke();

if(segCircleIntersects(cx,cy,r,ax,ay,bx,by)){
	ctx.fillStyle = '#222222aa';
	ctx.fill();
}

function segCircleIntersects(cx,cy,r,ax,ay,bx,by){
	// cases where A or B inside circle
  if(Math.pow(ax-cx,2)+Math.pow(ay-cy,2)<=Math.pow(r,2)){
  	return true;
  }
  if(Math.pow(bx-cx,2)+Math.pow(by-cy,2)<=Math.pow(r,2)){
  	return true;
  }
  
  var ab = Math.sqrt(Math.pow(bx-ax,2)+Math.pow(by-ay,2)); // len of seg
  var d = ((cx-ax)*(bx-ax)+(cy-ay)*(by-ay))/ab;
  
  if(d<0 || d>ab){
  	// d outside seg so _segment_ AB does not intersect (but _line_ AB does)
  	return false;
  }

  var ratio = d/ab;

  var dx = ax+ratio*(bx-ax);
  var dy = ay+ratio*(by-ay);
  
  // return CD < r
  return Math.pow(cx-dx,2)+Math.pow(cy-dy,2)<=Math.pow(r,2);
}