开发者

Finding x/y coordinates that fall within filled canvas arcs

开发者 https://www.devze.com 2023-04-06 14:53 出处:网络
Here is the fiddle T开发者_Python百科he 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 t

Here is the fiddle

T开发者_Python百科he 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.


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 commands, .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.org/wiki/Point_in_polygon

Finding x/y coordinates that fall within filled canvas arcs

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.net/kkDqz/4/

WARNING

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号