방법: 복합 도형의 채우기 제어

GeometryGroup 또는 PathGeometryFillRule 속성은 주어진 점이 기하 도형의 일부인지 여부를 결정하는 데 복합 도형이 사용하는 "규칙"을 지정합니다. FillRule에 대해 EvenOddNonzero의 두 가지 가능한 값이 있습니다. 다음 섹션에서는 이러한 두 가지 규칙을 사용하는 방법을 설명합니다.

EvenOdd: 이 규칙은 해당 점에서 모든 방향으로 무한대로 광선을 그리고 광선이 교차하는 지정된 도형 내에서 경로 세그먼트 수를 계산하여 채우기 영역에 점이 있는지 여부를 결정합니다. 이 숫자가 홀수이면 점이 안에 있고, 짝수이면 밖에 있습니다.

예를 들어 아래 XAML은 FillRuleEvenOdd로 설정된 일련의 동심 링(대상)으로 구성된 복합 도형을 만듭니다.

<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>

다음 그림은 이전 예제에서 만든 도형을 보여 줍니다.

서로 다른 색상을 가진 일련의 동심원으로 구성된 원.

이전 그림에서 보면 중심 및 세 번째 링이 채워져 있지 않음을 알 수 있습니다. 두 링 중 하나에 있는 점에서 그린 광선이 짝수의 세그먼트를 통과하기 때문입니다. 다음 그림을 참조하세요.

원에 그려진 EvenOdd 광선을 보여주는 다이어그램.

NonZero: 이 규칙은 해당 점에서 모든 방향으로 무한대로 광선을 그린 후 도형의 세그먼트가 광선과 교차하는 위치를 검사하여 경로의 채우기 영역에 점이 있는지 여부를 결정합니다. 0부터 시작하여 세그먼트가 왼쪽에서 오른쪽으로 광선과 교차할 때마다 1을 추가하고 경로 세그먼트가 오른쪽에서 왼쪽으로 광선과 교차할 때마다 1을 뺍니다. 교차 수를 계산한 후 결과가 0이면 점이 경로의 밖에 있습니다. 그렇지 않으면 점이 내부에 있습니다.

<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>

이전 예제를 사용하여 FillRule에 대한 Nonzero 값은 결과적으로 다음 그림과 같습니다.

모두 동일한 색상으로 채워진 일련의 중심원으로 구성된 원.

여기에서 볼 수 있듯이 모든 링이 채워집니다. 모든 세그먼트가 같은 방향으로 실행되므로 임의 점에서 그린 광선이 하나 이상의 세그먼트와 교차하고 교차의 합계가 0이 아니기 때문입니다. 예를 들어 다음 그림에서 빨간색 화살표는 세그먼트가 그려지는 방향을 나타내고 흰색 화살표는 가장 안쪽 링의 점에서 실행되는 임의 광선을 나타냅니다. 광선이 교차하는 각 세그먼트에 대해 0 값부터 시작할 경우 세그먼트가 왼쪽에서 오른쪽으로 광선과 교차하므로 1이 추가됩니다.

NonZero와 같은 FillRule 속성 값을 표시하는 다이어그램.

Nonzero 규칙의 동작을 더 잘 설명하기 위해 다른 방향으로 진행되는 세그먼트가 있는 좀 더 복잡한 도형이 필요합니다. 아래의 XAML 코드는 완전히 닫힌 동심원보다는 4개의 동심 호를 만드는 EllipseGeometry가 아닌 PathGeometry로 만들어진다는 점을 제외하고 이전 예제와 비슷한 도형을 만듭니다.

<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>

다음 그림은 이전 예제에서 만든 도형을 보여 줍니다.

세 번째 호가 채워지지 않은 상태로 서로 다른 색상을 가진 일련의 동심원으로 구성된 원.

중심에서 세 번째 호까지는 채워지지 않습니다. 다음 그림에서는 이 이유를 보여 줍니다. 이 그림에서 빨간색 화살표는 세그먼트가 그려진 방향을 나타냅니다. 두 개의 흰색 화살표는 “채워지지 않은” 영역의 점에서 외부로 이동되는 2개의 임의 광선을 나타냅니다. 이 그림에서 볼 수 있듯이 해당 경로에서 세그먼트를 교차하는 지정된 광선의 값 합계는 0입니다. 앞에서 정의한 대로 합계가 0이 아닌 경우는 해당 점이 형상에 속하는 것을 의미하지만 합계가 0이라는 사실은 해당 점이 형상에 속하지 않음을 의미합니다(채우기의 일부가 아님).

세그먼트를 가로지르는 임의 광선을 보여주는 다이어그램.

참고

FillRule의 목적을 위해 모든 도형은 닫힌 것으로 간주됩니다. 세그먼트에 틈이 있으면 가상선을 그려 닫습니다. 위의 예제에서는 링에 작은 틈이 있습니다. 이점을 고려할 때 이러한 틈을 지나가는 광선이 다른 결과를 가져와 광선이 다른 방향으로 진행될 것으로 예상할 수 있습니다. 다음은 이러한 틈 중 하나와 해당 틈을 닫는 "가상 세그먼트"(FillRule을 적용하기 위해 그린 세그먼트)를 확대해서 나타낸 것입니다.

항상 닫혀 있는 FillRule 세그먼트를 보여주는 다이어그램.

예제

참고 항목