Even–odd rule

The even–odd rule is an algorithm implemented in vector-based graphic software,[1] like the PostScript language and Scalable Vector Graphics (SVG), which determines how a graphical shape with more than one closed outline will be filled. Unlike the nonzero-rule algorithm, this algorithm will alternatively color and leave uncolored shapes defined by nested closed paths irrespective of their winding.

A curve (top) is filled according to two rules: the even–odd rule (left), and the non-zero winding rule (right). In each case an arrow shows a ray from a point P heading out of the curve. In the even–odd case, the ray is intersected by two lines, an even number; therefore P is concluded to be 'outside' the curve. By the non-zero winding rule, the ray is intersected in a clockwise direction twice, each contributing −1 to the winding score: because the total, −2, is not zero, P is concluded to be 'inside' the curve.

The SVG defines the even–odd rule by saying:

This rule determines the "insideness" of a point on the canvas by drawing a ray from that point to infinity in any direction and counting the number of path segments from the given shape that the ray crosses. If this number is odd, the point is inside; if even, the point is outside.

The rule can be seen in effect in many vector graphic programs (such as Freehand or Illustrator), where a crossing of an outline with itself causes shapes to fill in strange ways.

On a simple curve, the even–odd rule reduces to a decision algorithm for the point in polygon problem.

The SVG computer graphics vector standard may be configured to use the even–odd rule when drawing polygons, though it uses the non-zero rule by default.[2]

Implementation

Below is an example implementation in Python:[3]

def is_point_in_path(x: int, y: int, poly) -> bool:
    """Determine if the point is in the path.

    Args:
      x -- The x coordinates of point.
      y -- The y coordinates of point.
      poly -- a list of tuples [(x, y), (x, y), ...]

    Returns:
      True if the point is in the path.
    """
    num = len(poly)
    i = 0
    j = num - 1
    c = False
    for i in range(num):
        if ((poly[i][1] > y) != (poly[j][1] > y)) and \
                (x < poly[i][0] + (poly[j][0] - poly[i][0]) * (y - poly[i][1]) /
                                  (poly[j][1] - poly[i][1])):
            c = not c
        j = i
    return c
gollark: You kind of have to go off them to find any useful information other than "wait till the timer runs down and give it views".
gollark: It's probably because of our exclusion from the ridiculous "don't talk about NDs" rule on the forums.
gollark: I was hoping my hatchery would help, but noooo...
gollark: Feesh, I think, got an IOU for 72 ash/boreal hatchlings for an ND, which is on the same rarity level as a 2G prize, right?
gollark: I mean, you do have a CB prize, too.

See also

References

  1. J. D. Foley, A. van Dam, S. K. Feiner, and J. F. Hughes. Computer Graphics: Principles and Practice. The Systems Programming Series. Addison-Wesley, Reading, 2nd edition, 1990.
  2. , w3c.org, retrieved 2019-03-28
  3. "PNPOLY - Point Inclusion in Polygon Test - WR Franklin (WRF)".


This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.