Fact-checked by Grok 2 weeks ago

Nonzero-rule

The non-zero winding rule, also known as the nonzero-rule, is a fundamental in two-dimensional for determining whether a given point lies inside a closed or by computing a based on the directional traversal of the path's edges. This rule operates by imagining a extending from the test point to in any direction; as the ray intersects the path's edges, it accumulates a winding count where each left-to-right crossing (counterclockwise relative to the point) adds +1 and each right-to-left crossing () subtracts 1. If the total is nonzero, the point is considered inside the shape and filled accordingly; a zero winding number places it outside. This directional sensitivity allows the rule to handle complex, self-intersecting paths and nested subpaths effectively, such as in star shapes or overlapping regions where the net encirclement matters. In contrast to the even-odd rule, which simply counts the total number of edge intersections (odd for inside, even for outside) without regard to direction, the non-zero winding rule preserves the "insideness" of enclosed areas even in multiply-connected polygons. For example, in a figure-eight shape, the even-odd rule might leave the intersection unfilled, while the non-zero rule fills it if the windings do not cancel out. The non-zero winding rule is the default fill algorithm in standards like (SVG), where it is specified via the fill-rule attribute set to nonzero, and it is also employed in vector drawing software such as for rendering compound paths. Its adoption stems from early graphics systems like , ensuring consistent rendering of vector-based illustrations across rendering engines.

Fundamentals

Definition

The nonzero-rule, also known as the nonzero winding rule, is a fill rule employed in two-dimensional to determine whether a point lies inside a bounded by a closed , particularly for rendering filled shapes in systems. This method evaluates the enclosure of a point based on the directional traversal of the rather than simply counting boundary intersections, making it suitable for paths that may self-intersect or contain subpaths. At its core, the nonzero-rule computes a for the point relative to the , defined as the net number of complete rotations the makes around the point when traversed in its specified . Paths drawn counterclockwise contribute a positive increment to the (+1 for each full loop), while those drawn contribute negatively (-1 per loop), resulting in a signed sum that accounts for overlapping or nested regions. A point is classified as inside the shape—and thus filled—if this net is any nonzero value, ensuring that areas encircled an odd or even number of times in the same are treated consistently as interior. For instance, in a simple closed circular path traversed counterclockwise, the winding number is +1 for all points within the circle, filling the entire interior, while points outside have a winding number of 0. The rule's name, "nonzero," specifically distinguishes it from the alternative even-odd rule, which relies on the parity of intersection counts rather than directional winding.

Winding Number Principle

The winding number of a closed curve around a point in the plane is an integer that represents the net number of times the curve encircles the point in a counterclockwise direction, taking into account the direction of traversal along the path. This topological invariant measures the total rotational sweep of the curve relative to the point, where counterclockwise traversals contribute positively and clockwise ones negatively. Intuitively, the winding number can be visualized by imagining an observer standing at the point and tracking the direction of the as it is traversed; each full counterclockwise adds +1 to the count, while a clockwise subtracts 1, resulting in the net encirclements. This analogy captures the signed accumulation of turns, distinguishing between orientations without relying on parity alone. For simple closed curves, which do not intersect themselves, the winding number is 0 for all points exterior to the curve and ±1 for points in the interior, with the sign depending on the curve's (counterclockwise yielding +1 and -1). This property aligns with the , ensuring a clear separation between interior and exterior regions. In the case of self-intersecting paths or more complex curves, the can exceed 1 in for certain regions, allowing nested or overlapping areas to be filled based on the cumulative encirclements rather than simple inclusion. Such higher winding numbers enable the nonzero-rule to handle intricate shapes where regions may be encircled multiple times. This winding number serves as the conceptual foundation for determining filled areas in the nonzero-rule, and it can be computed practically via methods like as explored in subsequent sections.

Mathematical Formulation

Ray Casting Algorithm

The ray casting algorithm for the nonzero-rule computes the winding number by simulating a ray emanating from the test point and tallying directed crossings with polygon edges. To determine if a point lies inside a polygon under the nonzero-rule, a horizontal ray is cast from the point to infinity in the positive x-direction. Each edge of the polygon is examined for intersections with this ray; only crossings where the edge straddles the ray's y-coordinate (one endpoint at or below the point's y and the other above, or vice versa) are considered, provided the intersection occurs to the right of the point (x-intersection > point's x). Edges that are horizontal or tangent to the ray are ignored to avoid double-counting or ambiguity. The direction of each valid crossing contributes to the based on the edge's orientation relative to the . If the edge crosses the ray from below to above (y1 ≤ point.y < y2, where (x1, y1) and (x2, y2) are edge endpoints), it adds +1 to the winding number, indicating a counterclockwise contribution. Conversely, a crossing from above to below (y2 ≤ point.y < y1) subtracts 1, for a clockwise contribution. Special cases at vertices are handled by considering the ray to pass infinitesimally above vertices on the ray's y-level, ensuring vertices are not counted as crossings unless the edge properly spans the ray; this prevents erroneous counts for edges ending or starting at the ray level. The total winding number is the algebraic sum of these contributions across all edges. If the absolute value of the winding number is nonzero, the point is considered inside the polygon; otherwise, it is outside. This rule captures the net encirclements of the point by the polygon boundary, distinguishing it from simpler parity-based tests. An efficient implementation avoids explicit intersection computations by using orientation tests to check if the point lies to the left of the directed edge for potential crossings. The following pseudocode outlines the algorithm, assuming a polygon defined by vertices V[0..n-1] and a test point P = (px, py). The function inside() returns true if the point is inside:
function wn_PnPoly(P, V, n) {
    int    wn = 0;    // winding number counter
    // loop through all edges of the polygon
    for (int i = 0; i < n; i++) {
        int j = (i + 1) % n;
        if (V[i].y <= P.y) {         
            if (V[j].y > P.y)        
                if (isLeft(V[i], V[j], P) > 0)  
                    ++wn;            
        }
        else {                       
            if (V[j].y <= P.y)      
                if (isLeft(V[i], V[j], P) < 0)  
                    --wn;            
        }
    }
    return wn != 0;
}

function isLeft(P0, P1, P2) {
    return (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y);
}
Here, isLeft computes the cross product to determine the point's position relative to the edge; positive indicates left (for upward edges), negative indicates right (for downward). A simplified contribution to the winding number for a valid crossing edge can be expressed as w += \begin{cases} +1 & \text{if } y_2 > y_1 \\ -1 & \text{if } y_2 < y_1 \end{cases}, where the condition holds only if the edge spans py and the intersection x > px, verified via the orientation test. This form approximates the directional count without full intersection math in many implementations.

Handling Complex Paths

The nonzero winding rule extends naturally to self-intersecting by accumulating the across all edge crossings, allowing regions enclosed multiple times to exhibit higher winding values. For instance, in a figure-eight traversed such that one is counterclockwise and the other clockwise, the is +1 in one , 0 at the intersection point, and -1 in the other , resulting in selective filling based on nonzero accumulation rather than simple . In compound paths composed of multiple independent subpaths, each subpath contributes additively to the total at a given point, enabling nested or adjacent shapes. are typically created by orienting inner subpaths (negative winding) relative to an outer counterclockwise (positive) subpath, such that the net winding in the cancels to zero; this directional allows precise over filled versus excluded areas in representations. Overlapping regions in such paths are filled if the net winding number is nonzero, permitting nested fills or multi-layered enclosures that the even-odd rule would alternate or exclude based solely on crossing count. This makes the nonzero rule suitable for representing solid, continuous areas in designs with intentional overlaps, unlike the even-odd rule's tendency to produce voids in intersections. A representative example is the pentagram (a five-pointed star ), where the nonzero rule yields a winding number of 2 in the central due to dual encirclements by the path, filling it solidly, whereas the even-odd rule alternates fill and unfilled regions across the intersections. Limitations arise at vertices or tangent edges, where ray crossings may be ambiguous; these are resolved by selecting a consistent from the test point, such as horizontal to the right, which avoids counting vertical edges and uses quadrant-based to handle incidences without double-counting.

Comparison to Even-Odd Rule

Key Differences

The even-odd rule determines whether a point is inside a by counting the number of segment intersections along a from the point to , filling the if the count is odd and leaving it unfilled if even; this method ignores the of the segments. In contrast, the nonzero winding rule, also known as the nonzero rule, calculates a by adding +1 for each segment crossing the from left to right (counter-clockwise ) and -1 for each crossing from right to left ( ), filling the if the net is nonzero. These differences lead to distinct filling outcomes for complex paths with overlaps or self-intersections. The nonzero rule fills all regions enclosed by the path, including those formed by overlapping subpaths, as long as the net winding is nonzero, thereby treating the entire enclosed area as interior regardless of multiple layers. The even-odd rule, however, creates unfilled holes in regions where path segments intersect an even number of times, such as in overlapping areas, resulting in a more fragmented fill. A representative visual example is a self-intersecting bowtie-shaped path, formed by two adjacent triangles sharing a . Under the nonzero rule, the entire bowtie area, including the central , is filled because the remains ±1 or higher across the region due to consistent path orientation. With the even-odd rule, the central remains unfilled, as a from that point crosses the path an even number of times (twice), treating it as exterior. Conceptually, the nonzero rule preserves the topological enclosure of the path by relying on the net , a measure from that captures how the path winds around a point, ensuring coherent filling for oriented . The even-odd rule, by contrast, operates solely on the parity of boundary crossings, akin to a simpler toggling that does not account for path orientation or topological winding.

Use Cases for Each

The nonzero winding rule is particularly advantageous for hierarchical or nested shapes, where it ensures solid fills in enclosed regions and overlaps by accumulating winding numbers based on path direction. For instance, in diagrams constructed as paths, the rule fills intersection areas solidly without creating unintended holes, as inner contours with opposite winding subtract from the total while maintaining overall enclosure. This behavior aligns with the SVG specification's description of how nonzero handles enclosed subpaths, making it suitable for illustrations requiring intuitive, layered containment. In , the is essential for rendering outlines with counters, such as the inner in the letter 'O', where the opposite winding direction of the inner creates a precise without affecting the outer fill. Font formats like CFF2 mandate the nonzero for CharStrings to handle such overlaps correctly. ensuring consistent rendering of complex letterforms across devices. Conversely, the even-odd excels in patterns involving , alternations, or self-intersections, as it toggles fill status with each edge crossing, producing predictable alternating regions without relying on orientation. This is beneficial for designs like lace patterns or star shapes, where self-intersections should result in unfilled centers or modular voids, avoiding overfills that might occur under nonzero. The specification illustrates this for self-intersecting , highlighting even-odd's utility in artistic or procedural effects requiring parity-based insideness. Designers select the nonzero rule for "natural" enclosure in illustrations, such as logos or diagrams with nested elements, to mimic intuitive spatial . In contrast, the even-odd rule is favored for procedural or artistic effects, like generative patterns or intricate motifs, where consistent toggling simplifies creation of repetitive, hole-punctuated structures. A key trade-off is that nonzero can lead to overfilling in complex, multi-layered paths if winding directions are inconsistent, necessitating meticulous path construction to avoid artifacts. Even-odd offers greater predictability for modular designs, as its parity mechanism reduces sensitivity to direction, though it may produce unexpected holes in nested scenarios. In , the nonzero rule serves as the default for paths and compound paths, supporting its prevalence in standard illustration workflows.

Applications in Graphics

Vector Standards and Formats

The nonzero winding rule is formally specified in the Scalable Vector Graphics (SVG) 1.1 standard as the 'nonzero' value of the fill-rule attribute, which serves as the default for filling path elements. This attribute determines the interior of a by calculating the : a is drawn from the test point, and crossings are counted with direction (+1 for left-to-right, -1 for right-to-left); regions with a nonzero total are filled. In and Portable Document Format (PDF), the nonzero winding rule is the default for path filling operations, such as the fill (f) in and its equivalent in PDF. Adobe's PostScript Language Reference Manual describes this rule for determining interior regions during the fill process, where the winding number dictates filled areas based on path orientation; PDF inherits this behavior, standardizing it for consistent rendering in document interchange. The showpath , used to render paths for stroking or filling, operates within this framework, ensuring implementations align with the nonzero convention. Graphics APIs like OpenGL and DirectX provide support for the nonzero rule to handle fill rules in 2D vector rendering. OpenGL's GLU tessellator enables it via the GLU_TESS_WINDING_NONZERO property in gluTessProperty, classifying regions as interior if their winding number is nonzero, which is useful for tessellating complex paths; advanced usage can involve stencil buffer tests to enforce winding-based filling. In DirectX, Direct2D's D2D1_FILL_MODE_WINDING option in geometry sinks and render targets fills intersecting areas with nonzero winding counts, promoting hardware-accelerated 2D graphics consistency. The incorporates the nonzero rule through the fillRule property on CanvasRenderingContext2D, defaulting to 'nonzero' for filling methods like fill(), where open subpaths are implicitly closed and interiors are determined by . This specification ensures cross-browser for web-based vector rendering. Overall, the nonzero rule's integration across , PDF, , , , and supports consistent handling of oriented s in complex geometries, reducing rendering discrepancies compared to even-odd alternatives that ignore path direction.

Implementation in Software

In , the nonzero winding rule serves as the default fill rule for compound paths and shapes, ensuring that enclosed areas are filled based on path directionality rather than simple parity. Users can toggle between the nonzero and even-odd rules via the Attributes panel, particularly when working with Pathfinder operations to merge or divide paths. Similarly, in , shape layers and paths default to the nonzero winding rule for filling compound shapes, with options to adjust via path properties in the Paths panel for precise control over interior regions. Open-source tools like provide support for both fill rules through the Fill and Stroke dialog, where users select nonzero for complex artwork involving overlapping subpaths to maintain consistent filling of nested regions. issues warnings or visual feedback for self-intersecting paths under the nonzero rule to alert designers of potential rendering inconsistencies. also implements both rules in its vector editing workflow, defaulting to nonzero (labeled as "Fill Holes") for designs with internal enclosures, accessible via the Property Bar during shape creation or editing. Graphics libraries commonly integrate the nonzero rule for robust path filling. In the library, used by applications, the default fill rule is set to CAIRO_FILL_RULE_WINDING (nonzero), applied during path filling operations with checks to determine interior points. Skia, powering rendering in and , employs the nonzero winding rule in its SkPath for filled areas, evaluating path direction to resolve overlaps without requiring explicit user intervention. Java's Graphics2D API, via the GeneralPath , uses WIND_NON_ZERO as the default winding rule for filling shapes, integrated with BasicStroke for outline rendering while preserving fill behavior. For dynamic implementations, standards form the basis, allowing to set the fill rule programmatically on path elements. For instance, to apply the nonzero rule to a for handling shapes like animated icons, the following can be used:
javascript
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M10 10 L90 10 L90 90 L10 90 Z'); // Example path data
path.style.fillRule = 'nonzero';
svgElement.appendChild(path);
This approach ensures consistent rendering across browsers for paths with potential self-intersections or holes. A key challenge in software implementations of the nonzero rule, particularly those relying on for point-in-polygon tests, is floating-point precision errors that can misclassify edge points as interior or exterior. Libraries address this by incorporating epsilon tolerances, such as small offset values (e.g., 1e-10) during ray-edge intersection computations to avoid ambiguity in calculations.

History and Development

Origins in Graphics

The nonzero winding rule in draws its topological foundation from the , proposed by Camille Jordan in 1887, which establishes that a simple closed curve in the plane separates it into a bounded interior region and an unbounded exterior region. This mathematical principle provided the conceptual basis for determining whether points lie inside or outside closed paths, influencing later computational methods for rendering filled shapes. In the , as advanced with the need for efficient filling in raster displays, began adapting topological ideas like the to handle scan conversion of complex polygons. These adaptations addressed challenges in identifying interior regions for self-intersecting or multiply-wound paths, building on earlier point-in-polygon tests from the , such as Shimrat's 1962 , which laid groundwork for boundary traversal though primarily using crossing counts. By the late , winding-based approaches emerged in to better support hierarchical or nested structures in vector data. The term "nonzero winding" was introduced in graphics literature around 1980 to explicitly contrast with the even-odd () rule, emphasizing the counting of net edge windings around a point for tests. Adobe's language, developed from 1982 to 1984, formalized the nonzero winding as the default for path filling operations in printer drivers, enabling precise rendering of overlapping vector paths. A pivotal milestone occurred with the 1985 release of Apple's printer, which integrated and thereby popularized the nonzero in workflows, allowing designers to produce professional-quality output from complex illustrations without manual adjustments for path overlaps.

Adoption in Standards

The nonzero winding rule has been incorporated into several foundational standards for and document rendering, serving as a core mechanism for determining filled regions in paths and shapes. Its adoption began with early page description languages and extended to web and font technologies, often as the default fill rule to handle complex contours consistently. In the language, introduced by in 1982, the nonzero rule is used for filling closed paths, where a point is considered inside if the net number of path windings around it is nonzero. The even-odd rule is also supported via specific operators, but nonzero is the default for the fill operator. This dual support influenced subsequent standards, as PostScript became a cornerstone for and printing. The Portable Document Format (PDF), standardized as ISO 32000, builds directly on PostScript's imaging model and adopts the nonzero winding rule for path filling. Operators such as f (fill using nonzero rule) and b (close, fill using nonzero, and stroke) implement it, while starred variants like f* use the even-odd rule. Nonzero is the default for non-starred fill operators, ensuring compatibility with PostScript-derived workflows in document exchange and rendering. This adoption dates to PDF 1.0 in 1993, with refinements in later versions for enhanced support. Scalable Vector Graphics (SVG), developed by the W3C and first published in 1999 with SVG 1.0, specifies the nonzero rule via the fill-rule presentation attribute, which defaults to nonzero for shapes and paths. It determines insideness by computing the from ray crossings, filling regions where the count is nonzero, while evenodd provides an alternative for specific designs like icons. This choice aligns SVG with and PDF for web-based vector rendering, promoting interoperability in browsers and graphics software. SVG 2 (2015) retains this behavior with minor clarifications for complex paths. In font outline standards, (part of the specification, ISO/IEC 14496-22) mandates the nonzero winding rule for rasterizing contours. Contours are oriented clockwise for exterior boundaries and counterclockwise for interiors (or vice versa), with the scan converter filling pixels where the is nonzero. This ensures precise rendering of letterforms with holes, such as 'O' or 'Q', and has been standard since 's release in 1991 by Apple and . fonts, extending since 1996, inherit this rule for scalable across platforms. The Khronos Group's OpenVG API (version 1.0, 2005), for hardware-accelerated 2D on embedded systems, supports both nonzero and even-odd fill rules through functions like vgFillPath. The nonzero rule fills areas based on winding accumulation, making it suitable for device-independent rendering in and automotive applications. Its inclusion standardizes vector operations across vendors, drawing from PDF and precedents.

References

  1. [1]
  2. [2]
    [PDF] 559 General Polygons
    Non-Zero Winding Rule. • Any non-zero winding is “inside”. • What Adobe Illustrator does. • Odd Winding Rule / Positive Winding Rule / …. 0. Page 2. 2. Polygon.
  3. [3]
    Defining winding rules · OpenFL Developer's Guide - Books
    For non-zero winding, the values assigned to the paths are used. When the combined values of the path are not 0, the area is filled. When the combined value is ...
  4. [4]
    Painting: Filling, Stroking and Marker Symbols — SVG 2
    The fill-rule property indicates the algorithm (or winding rule) which is to be used to determine what parts of the canvas are included inside the shape.
  5. [5]
    [PDF] 2 Winding Numbers
    If the polygon winds clockwise around o, the winding number is negative. Crucially, the winding number is only well defined if the polygon does not contain the ...<|control11|><|separator|>
  6. [6]
    Winding numbers: a topological tool for geometry processing
    Mar 26, 2025 · Intuitively, the winding number at a point p p p measures the infinitesimal angle subtended by the curve at p p p, and sums up all these angles ...
  7. [7]
    Point in Polygon Strategies - Eric Haines
    A ray is shot from the test point along an axis (+X is commonly used) and the number of crossings is computed (Figure 1). Either the Jordan Curve or winding ...Missing: rule | Show results with:rule
  8. [8]
    [PDF] The Point in Polygon Problem for Arbitrary Polygons
    the pseudo-code of a very intelligible algorithm that determines the winding number of a point with respect to an arbitrary polygon. The winding number ω(R ...
  9. [9]
    Painting: Filling, Stroking and Marker Symbols – SVG 1.1 ... - W3C
    The following drawing illustrates the nonzero rule: Image showing nonzero fill rule. View this example as SVG (SVG-enabled browsers only). evenodd: This rule ...
  10. [10]
    [PDF] PostScript Language Reference, third edition - Adobe
    ... Nonzero winding number rule 195. 4.4. Even-odd rule 196. 4.5. Color ... definition in systemdict, fetches the associated value (the operator object itself) ...
  11. [11]
    [PDF] Portable document format — Part 1: PDF 1.7 - Adobe Open Source
    Jul 1, 2008 · This document is about PDF 1.7, a portable document format, and is derived from the ISO 32000-1 standard. It is an authorized copy.
  12. [12]
    [XML] gluTessProperty - Khronos Registry
    The winding rule classifies a region as ``inside'' if its winding number belongs to the chosen category (odd, nonzero, positive, negative, or absolute value of ...Missing: gluTes | Show results with:gluTes
  13. [13]
    D2D1_FILL_MODE (d2d1.h) - Win32 apps | Microsoft Learn
    Jan 30, 2022 · Specifies how the intersecting areas of geometries or figures are combined to form the area of the composite geometry.
  14. [14]
    NV_path_rendering - NVIDIA
    RESOLVED: GL_PATH_FILL_MODE_NV should initially be GL_COUNT_UP_NV. This is consistent with SVG default non-zero fill rule and the typical usage of PostScript.
  15. [15]
    Paint and path operations, Shape attributes for shape layers
    Jul 3, 2024 · The nonzero winding fill rule considers path direction; the even-odd fill rule does not. After Effects and Illustrator use the nonzero winding ...
  16. [16]
    fill-rule behaviour - Beyond the Basics - Inkscape Forum
    Clicking either of the ( looks like mouse ears ) fill rule icons in the fill panel will apply either fill-rule:non-zero or fill-rule:even-odd to the current ...
  17. [17]
    Explicitly set fill-rule:non-zero for text by default. (#3888) - GitLab
    Oct 23, 2020 · Idea: The new text elements could default to style="fill-rule:nonzero;" since that is what's expected in most usages of text.
  18. [18]
    Fills - Corel Vector Help
    Aug 5, 2022 · Non-Zero (Fill Holes) – Internal enclosed areas are NOT regarded as holes; Even-Odd (Keep Holes) – Internal enclosed areas ARE regarded as holes.
  19. [19]
    cairomm: Cairo::Context Class Reference
    This is just a description of the rule that is applied.) The default fill rule is Cairo::FillRule::WINDING. New entries may be added in future versions ...
  20. [20]
    SkPath Class Reference - Skia
    When used to draw a filled area, SkPath describes whether the fill is inside or outside the geometry. SkPath also describes the winding rule used to fill ...
  21. [21]
    fill-rule - SVG - MDN Web Docs - Mozilla
    Apr 16, 2025 · The fill-rule attribute is a presentation attribute defining the algorithm to use to determine the inside part of a shape.
  22. [22]
    3.9 Managing Rounding Error
    Floating-point round-off error can cause the ray–bounding box intersection test to miss cases where a ray actually does intersect the box. While it's ...
  23. [23]
    [PDF] Floating Point Precision Ray Tracing of Freeform Surfaces - Uni Ulm
    Jun 15, 2005 · Ray casting is an image generation method, where rays are shot from the camera through a pixel into a. 3d scene to determine the closest ...
  24. [24]
    How PostScript Kickstarted Desktop Publishing - IEEE Spectrum
    Dec 8, 2022 · PostScript and the Adobe Type Library revolutionized printing and publishing, and kickstarted the explosive growth of desktop publishing ...
  25. [25]
    None
    Nothing is retrieved...<|separator|>
  26. [26]
    TrueType fundamentals (OpenType 1.9.1) - Typography
    May 30, 2024 · This chapter introduces the basic concepts needed to create and instruct an OpenType font that contains TrueType outline data.<|control11|><|separator|>
  27. [27]
    [PDF] OpenVG Specification - Khronos Registry
    Dec 3, 2008 · According to the even/odd rule, it is outside the path, whereas according to the non-zero rule it is inside. Implementations must be able to ...<|control11|><|separator|>