Gör så här: Kontrollera fyllningen i en sammansatt form
Egenskapen FillRule för en GeometryGroup eller en PathGeometry, anger en "regel" som den sammansatta formen använder för att avgöra om en viss punkt är en del av geometrin. Det finns två möjliga värden för FillRule: EvenOdd och Nonzero. I följande avsnitt beskrivs hur du använder dessa två regler.
EvenOdd: Den här regeln avgör om en punkt är i fyllningsregionen genom att rita en stråle från den punkten till oändligheten i valfri riktning och räkna antalet sökvägssegment inom den angivna formen som strålen korsar. Om det här talet är udda, är punkten inuti; om jämnt, är punkten utanför.
Till exempel skapar XAML nedan en sammansatt form som består av en serie koncentriska ringar (mål) med en FillRule inställd på EvenOdd.
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
<EllipseGeometry RadiusX="70" RadiusY="70" Center="75,75" />
<EllipseGeometry RadiusX="100" RadiusY="100" Center="75,75" />
<EllipseGeometry RadiusX="120" RadiusY="120" Center="75,75" />
</GeometryGroup>
</Path.Data>
</Path>
Följande bild visar formen som skapades i föregående exempel.
Observera att mitten och den tredje ringen inte är fyllda i föregående bild. Detta beror på att en stråle som dras från någon punkt inom någon av dessa två ringar passerar genom ett jämnt antal segment. Se följande bild:
NonZero: Den här regeln avgör om en punkt är i sökvägens fyllningsregion genom att rita en stråle från den punkten till oändligheten i någon riktning och sedan undersöka de platser där ett segment av formen korsar strålen. Börja med att räkna från noll, lägg till en varje gång ett segment korsar strålen från vänster till höger och subtrahera en varje gång ett sökvägssegment korsar strålen från höger till vänster. Om resultatet är noll när korsningarna har räknats ligger punkten utanför sökvägen. Annars är det inuti.
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<GeometryGroup FillRule="NonZero">
<EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
<EllipseGeometry RadiusX="70" RadiusY="70" Center="75,75" />
<EllipseGeometry RadiusX="100" RadiusY="100" Center="75,75" />
<EllipseGeometry RadiusX="120" RadiusY="120" Center="75,75" />
</GeometryGroup>
</Path.Data>
</Path>
Med hjälp av föregående exempel ger värdet Nonzero för FillRule följande bild som ett resultat:
Som du ser är alla ringar fyllda. Detta beror på att alla segment körs i samma riktning och därför kommer en stråle som dras från en punkt att korsa ett eller flera segment och summan av korsningarna inte är lika med noll. I följande bild representerar till exempel de röda pilarna riktningen segmenten ritas och den vita pilen representerar en godtycklig stråle som körs från en punkt i den innersta ringen. För ett utgångsvärde av noll läggs ett värde till för varje segment som strålen korsar, eftersom segmentet korsar strålen från vänster till höger.
För att bättre demonstrera beteendet för Nonzero regel krävs en mer komplex form med segment som körs i olika riktningar. XAML-koden nedan skapar en liknande form som föregående exempel, förutom att den skapas med en PathGeometry snarare än en EllipseGeometry som skapar fyra koncentriska bågar i stället för helt stängda koncentriska cirklar.
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<GeometryGroup FillRule="NonZero">
<PathGeometry>
<PathGeometry.Figures>
<!-- Inner Ring -->
<PathFigure StartPoint="10,120">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="50,50" IsLargeArc="True" SweepDirection="CounterClockwise" Point="25,120" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<!-- Second Ring -->
<PathFigure StartPoint="10,100">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="70,70" IsLargeArc="True" SweepDirection="CounterClockwise" Point="25,100" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<!-- Third Ring (Not part of path) -->
<PathFigure StartPoint="10,70">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment Size="100,100" IsLargeArc="True" SweepDirection="CounterClockwise" Point="25,70" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
<!-- Outer Ring -->
<PathFigure StartPoint="10,300">
<PathFigure.Segments>
<ArcSegment Size="130,130" IsLargeArc="True" SweepDirection="Clockwise" Point="25,300" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
Följande bild visar formen som skapades i föregående exempel.
Observera att den tredje bågen från mitten inte är fylld. Följande bild visar varför detta är det. I bilden representerar de röda pilarna den riktning som segmenten ritas i. De två vita pilarna representerar två godtyckliga strålar som rör sig ut från en punkt i den "icke-fyllda" regionen. Som du kan se i bilden är summan av värdena från en given stråle som korsar segmenten i sin väg noll. Enligt definitionen ovan innebär en summa av noll att punkten inte är en del av geometrin (inte en del av fyllningen) medan en summa som är inte noll, inklusive ett negativt värde, är en del av geometrin.
Notera
För FillRuleanses alla former vara stängda. Om det finns en lucka i ett segment ritar du en imaginär linje för att stänga den. I exemplet ovan finns det små luckor i ringarna. Med tanke på detta kan man förvänta sig en stråle som löper genom gapet för att ge ett annat resultat och sedan en stråle som körs i en annan riktning. Nedan visas en förstorad bild av en av dessa luckor och det "imaginära segmentet" (segment som ritas för att tillämpa FillRule) som stänger det.
Exempel
Se även
- Skapa en sammansatt form
- Översikt över geometri
.NET Desktop feedback