javascript - Finding xy coordinates that fall within filled canvas arcs - Stack Overflow

Here is the fiddleThe arcs I've drawn around the outside of the circle - I'd like to know how

Here is the fiddle

The arcs I've drawn around the outside of the circle - I'd like to know how to find all of the x/y coordinates that they cover so that I don't have to re-draw them every time using isPointInPath() to determine whether the mouse cursor is over them or not. I was thinking about writing all of the x/y coordinates to an array that I could check against the mouse position x/y coordinates and if I find a match then I change the cursor. The problem is, I don't know the code to derive all of the x/y values.

Here is the fiddle

The arcs I've drawn around the outside of the circle - I'd like to know how to find all of the x/y coordinates that they cover so that I don't have to re-draw them every time using isPointInPath() to determine whether the mouse cursor is over them or not. I was thinking about writing all of the x/y coordinates to an array that I could check against the mouse position x/y coordinates and if I find a match then I change the cursor. The problem is, I don't know the code to derive all of the x/y values.

Share Improve this question asked Sep 22, 2011 at 17:46 jamaussjamauss 1,0431 gold badge15 silver badges36 bronze badges 5
  • 2 You know, you don't actually have to redraw your arcs to use .isPointInPath()-- omit any calls to .fill() or .stroke() and you'll have a path which you can use to test whether it contains a point. – ellisbben Commented Sep 22, 2011 at 19:05
  • @ellisbben You should post that as an answer! :) – Phrogz Commented Sep 22, 2011 at 19:31
  • Hmm, I wonder why I didn't consider that. Let me give that a try. – jamauss Commented Sep 22, 2011 at 20:08
  • @ellisben - thanks for the suggestion. That actually worked great because my bottleneck was the constant re-rendering of several items on the canvas. If you'd like to add your ment as an answer I'd be happy to accept it. – jamauss Commented Sep 22, 2011 at 21:28
  • Done. I'm glad when people recognize a good answer in hiding. :) – ellisbben Commented Sep 22, 2011 at 21:33
Add a ment  | 

4 Answers 4

Reset to default 3

You don't actually have to redraw your arcs to use .isPointInPath()-- just omit any calls to .fill() or .stroke() and you'll have a path which you can use to test whether it contains a point.

I would suggest having one function which outlines the arc path (.beginPath(), path mands, .closePath()) and then two functions which call it-- one which calls the arc path function, then sets the fill style and fills the path to draw it, and another which calls the arc path function and then just tests whether a point is in the path.

This is the method you should use: http://en.wikipedia/wiki/Point_in_polygon

The way it works is actually extremely simple: if the amount of times a ray that ends at any point passes through the polygon perimeter is even, the respective point HAS to be outside of the polygon. If it's odd, it's within the polygon.

Here's a function found by Pimvdb:

function isPointInPoly(poly, pt){
    for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
        ((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
        && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
        && (c = !c);
    return c;
}

I wouldn't call what you have 'arcs' (they're more like bowed rectangles), but here's a broad sketch of how to write a function to determine if a point is within such a thing:

  1. Calculate the center of the circle from the end points and radius.
    1. If the point is closer to the center than the close arc (distance-to-center-squared is greater than close-radius-squared) then return false.
    2. If the point is farther from the center than the far arc then return false.
  2. Calculate the start and end angles for the endpoints of your rectangles with respect to the center of the circle. (Hint: Math.atan2)
    1. Calculate the angle for the point with respect to the center of the circle. If it is not between the angles for the end points, return false.
      • Beware endpoints that cross the wrapping values for Math.atan2.
  3. Return true if other tests passed.

You can't calculate "all" points in this region, as there an an infinite number of them. Creating a lookup table of all integer pixel coordinates in your image is possible, but wasteful.

What I would do, instead of what you are proposing, is use a retained-mode graphics system (hint: SVG) and let it track mouse events for me using its far-more-efficient code.

Here's an easier method:

I've altered the drawtabs function to also check if mouse is within a tab: http://jsfiddle/kkDqz/4/

WARNING

This method is easy, but requires you to redraw EVERYTHING on mousemove.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745431530a4627412.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信