[WPF/xaml] Pathで描いた図形サンプル集(ひし形、角を丸くした四角、楕円など)

# やりたいこと
xamlで描いた画面の中に、図形・記号を表示したい。
それほど難しい形を出したいわけではなく、ちょっと角を丸くした四角、とか、ひし形、とかその程度でいい。

ちょっと調べた結果、「Path」を使ってやれば、自由な形を描画できそうなので、どうやったら好きな図形を描けるか調べる。

# やり方
Pathの`Data`に、図形のもととなる「コマンド」をセットしてやる。

# サンプル

### ひし形

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/c6647973-5400-791a-6702-d5acaa0c1f83.png)

```ひし形.xaml
<Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="3"
      Data="M 0,50 L 50,100 L 100,50 L 50,0 Z" />
```

### 三角

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/c3d80717-ab20-d2aa-3b7d-b91bb672e641.png)

```三角.xaml
<Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="3"
      Data="M 0,0 L 100,100 L 100,0 Z"/>
```

### 扇形 その１

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/a05f5f15-3cc6-cebf-39e6-ee0fa5fb1d6a.png)

```扇形その１.xaml
<Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="1"
      Data="M 0,0 A 50,50 0 0 1 50,50 L 50,0 Z"/>
```

### 扇形 その２

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/5343c53c-d8e6-0840-f81e-6921f2ce0380.png)

```扇形その２.xaml
<Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="1"
      Data="M 0,0 A 50,50 0 0 0 50,50 L 50,0 Z" d:IsHidden="True"/>
```

### 楕円 その１

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/5e347e0b-7e09-8f3f-5f95-2014196072eb.png)

```楕円その１.xaml
<Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
      Data="M 0,0 A 50,25 0 1 0 50,25"/>
```

### 楕円 その２

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d2e48bff-649f-a190-fab8-851fb6e7bafc.png)

```楕円その２.xaml
<Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
      Data="M 0,0 A 50,25 0 0 1 50,25"/>
```

### 楕円 その３

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/c2a2c034-50a9-4dd1-f189-fe873c0690cc.png)

```楕円その３.xaml
<Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
      Data="M 0,0 A 50,25 0 1 1 50,25"/>
```

### 楕円 その４
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/75dbb422-96f4-16ad-bf00-000db399813e.png)

```楕円その４.xaml
<Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
      Data="M 0,0 A 50,25 90 1 1 50,25"/>
```

### 四角の下の角を丸くしたもの その１

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/39139aad-77ab-25ec-fe7b-6a1446fe2488.png)

```四角の下の角を丸くしたものその１.xaml
<Path Stroke="LightPink" Fill="LemonChiffon" StrokeThickness="1"
      Data="M 0,0 L 0,90 A 10,10 90 0 0 10 100 L 90,100 A 10,10 90 0 0 100,90 L 100,0 Z"/>
```

### 四角の下の角を丸くしたもの その２

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/fa246209-edde-a76d-900c-8982d07d2291.png)

```四角の下の角を丸くしたものその２.xaml
<Path Stroke="LightPink" Fill="LemonChiffon" StrokeThickness="1" Stretch="Fill"
      Data="M 0,0 L 0,90 A 10,10 90 0 0 10 100 L 90,100 A 10,10 90 0 0 100,90 L 100,0 Z"/>
```
# サンプル全体

```MainWindow.xaml
<Window x:Class="WpfApp34.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp34"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="200">
    <Grid Width="120" Height="120" Background="Transparent">
        <Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="3"
              Data="M 0,50 L 50,100 L 100,50 L 50,0 Z" />

        <Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="3"
              Data="M 0,0 L 100,100 L 100,0 Z"/>

        <Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="1"
              Data="M 0,0 A 50,50 0 0 1 50,50 L 50,0 Z"/>
        
        <Path Stroke="LightPink" Fill="LemonChiffon" Stretch="Fill"  StrokeThickness="1"
              Data="M 0,0 A 50,50 0 0 0 50,50 L 50,0 Z"/>

        <Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
              Data="M 0,0 A 50,25 0 0 0 50,25"/>
        
        <Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
              Data="M 0,0 A 50,25 0 1 0 50,25"/>
        
        <Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
              Data="M 0,0 A 50,25 0 0 1 50,25"/>
        
        <Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
              Data="M 0,0 A 50,25 0 1 1 50,25"/>
        
        <Path Stroke="LightPink" Fill="LemonChiffon"  StrokeThickness="1"
              Data="M 0,0 A 50,25 90 1 1 50,25"/>

        <Path Stroke="LightPink" Fill="LemonChiffon" StrokeThickness="1"
              Data="M 0,0 L 0,90 A 10,10 90 0 0 10 100 L 90,100 A 10,10 90 0 0 100,90 L 100,0 Z"/>
       
        <Path Stroke="LightPink" Fill="LemonChiffon" StrokeThickness="1" Stretch="Fill"
              Data="M 0,0 L 0,90 A 10,10 90 0 0 10 100 L 90,100 A 10,10 90 0 0 100,90 L 100,0 Z"/>
    </Grid>
</Window>

```


# わかりにくかったところメモ
PathのDataにコマンドをセットすると、線を描画できる。
「M」がスタート地点を指定する、
「Z」は最後の描画点からスタート地点を自動で結んで閉じてくれる、
「L」が現在地点から指定の地点までの線を引く、というのは分かりやすかったが、
「A」の楕円を描く、というのがなんともわかりにくかった。

# コマンド「A」について
Aの説明は、MSDOCSではこのようになっている。
https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/graphics-multimedia/path-markup-syntax
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/672ba60e-fee3-4e46-6e9a-e8c7a50bdc60.png)

### sweepDirectionFlagの意味
まずわからなかったのが「sweepDirectionFlag」の意味。
実験したところ、

- sweepDirectionFlagが１だと、開始地点から**「右回り(正の方向)」**に、楕円が描画される
- sweepDirectionFlagが０だと、開始地点から**「左回り(負の方向)」**に、楕円が描画される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/f403db4d-ce57-ad9d-b899-e4e8a8310d9b.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/2ce7dc2b-a545-e89a-00aa-8275e4f2b2a8.png)

### isLargeArcFlagの意味
さらに「isLargeArcFlag」も意味が分からなかった。
実験したところ、

- isLargeArcFlagが１だと、開始地点から目的地まで、180度より大きい経路を通って楕円を描く
- isLargeArcFlagが０だと、開始地点から目的地まで、180度より小さい経路を通って楕円を描く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/3cf4c912-77d0-3093-6d64-fa1a7804b503.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/dbf441c5-4b5a-5f58-c892-19618628868c.png)

### sweepDirectionFlag と isLargeArcFlag
sweepDirectionFlag と isLargeArcFlagが両方０、
sweepDirectionFlag と isLargeArcFlagが両方１、にして楕円を描くと、
丁度反対周りで楕円を描いたようになる。
(二つ合わせて一つの楕円のようになる)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/0b73244a-d808-ffb9-4580-ab81125943ad.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/557208f1-97ac-1b0d-7ca6-b4014052a3b7.png)

### rotationAngleの意味
rotationAngleを例えば90にすると、楕円が90度回転したようになる。
→上の「楕円その４.xaml」参照

# PathのStretchについて
Pathの「Stretch」を"Fill"にしておいてやると、親のGridの大きさに合わせて書いた図形が伸長してくれるので、大体の形をPathで作っておいて、最終的に画面に収めるときはGridの大きさで微調整する、ということもできる。(ただし、上の「四角の下の角を丸くしたもの その２」でそれをやると、Gridが横長だったりすると、角を丸めた部分が横に伸びて丸まったようになる(見た目が崩れる)ので注意が必要。)

# まとめ
以上のことが大体わかれば、画面にUIの部品として出すための図形くらいであれば、よっぽど奇抜なUIでなければ描けると思う。


# 参考

パスマークアップの構文
https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/graphics-multimedia/path-markup-syntax