title: Detecting mouse collision with closed Bezier curved shapes in Canvas
body: <p><strong>My situation:</strong></p>
  
  <p>I am working on a HTML5/Canvas/JavaScript framework for zooming-user-interface, which I then use for a data visualization web application project. One of the features that I need for my framework is to be able to detect whether the user's mouse is over a rendered shape. For more complex shapes like polygons and shapes with Bezier curves, this becomes a challenge.</p>
  
  <p>I found two ways of solving this problem:</p>
  
  <p>(1) One way is to draw everything on the canvas twice. The first time, every shape gets filled with a unique color from a hash table. The second time, the shapes get their real colors and masks over the first layer. To detect mouse-shape collision, I'd have to grab the color of the pixel under the mouse from the first layer and map the color I get to the corresponding shape in the hash table.</p>
  
  <p>(2) Or I can use the ray casting algorithm (<a href="http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm" rel="nofollow">http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm</a>). I have actually implemented this algorithm with code that detect ray-line collisions and ray-Bezier collisions.</p>
  
  <p><strong>The actual question:</strong></p>
  
  <p>I dislike the first approach because everything has to be drawn twice, which is not computationally cheap. But the second approach does not guarantee accuracy, due to rounding errors from computations.</p>
  
  <p>Ideally, I would like to improve the accuracy of the second approach to near-perfection.</p>
  
  <p>My attempt to improve accuracy is to cast 4 rays in different directions: top, left, bottom and right. If at least one horizontal and one vertical ray suggest the mouse is inside the shape, then I conclude the point is inside the shape. Although this eliminates most misfires, errors (not firing) still do occur when the mouse is inside the shape.</p>
  
  <p>It would be awesome if someone can suggest a fix to the ray casting algorithm, or perhaps even a third option!</p>
  
  <p>Thanks in advance.</p>