午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

曲線Pathを近似の直線PathにするGetFlattenedPathGeometry使ってみた

GetFlattenedPathGeometryメソッドを使って曲線のPathGeometryから直線のPathGeometryを取得
 
GetFlattenedPathGeometry(tolerance, ToleranceType)
Tolerance:公差、許容できる誤差をdouble型で指定
ToleranceType:Absolute絶対 or Relative相対のどちらかを指定
 
今回のアプリのダウンロード先
 
イメージ 1
オレンジ線が元のベジェ曲線で、細い青線がそれから取得した直線のPathGeometry
Toleranceの値を大きくすると雑になる
 
 
 
 
イメージ 4
Tolerance=0ならToleranceTypeはAbsoluteでもRelativeでも結果は同じ
青線は曲線に見えるくらい細かい直線の集まり、丁寧で正確
 
 
ToleranceType.Relative
イメージ 2
ToleranceTypeがRelativeだとToleranceが0.1でも、かなり雑になってカクカク
 
イメージ 3
1.2でアンカーポイントだけになって、これ以上大きくしても変化なしだったので、これが一番雑な状態みたい
 
 
ToleranceType.Absolute
イメージ 5
AbsoluteだとTolerance=1.2でも曲線に近い
 
イメージ 6
19.4まで大きくしたらRelativeの0.1と同じになった
 
イメージ 7
一番雑な状態になったのは310.1
 
 
ベジェ曲線を少し変更、伸ばしてみた
イメージ 9
Relative
イメージ 8
イメージ 10
Relativeだと一番雑な状態になったのは1.5
さっきは1.2だった
 
Absolute
イメージ 11
イメージ 12
Absoluteだと510、さっきは310.1だった
なので元になるPathGeometryの長さとか大きさで変わるみたい
でも、どれくらいの値を指定すればどれくらいの丁寧さが得られるのかの見当がつかないなあ、何を基準にした絶対や相対なのかがわからん
 
 
デザイン画面

f:id:gogowaten:20191213100218p:plain

イメージ 14
コード
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace _20180613_曲線Pathを直線Pathに変換
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            PathGeometry pathGeometry = MyPath.Data.GetFlattenedPathGeometry();
            StepLine.Data = pathGeometry;
            StepSlider.ValueChanged += StepSlider_ValueChanged;
            StepSlider.MouseWheel += StepSlider_MouseWheel;
            RadioRelative.Checked += Radio_Checked;
            RadioAbsolute.Checked += Radio_Checked;
        }
        //RadioButtonのチェック変更時
        private void Radio_Checked(object sender, RoutedEventArgs e)
        {
            ChangeGeometry();
        }
        //Sliderのマウスホイール動作時
        private void StepSlider_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Delta > 0)
            {
                StepSlider.Value += StepSlider.SmallChange;
            }
            else
            {
                StepSlider.Value -= StepSlider.SmallChange;
            }
        }
        //Sliderの値変更時
        private void StepSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            ChangeGeometry();
        }
        //GetFlattenedPathGeometryを使って曲線のPathGeometryから直線のPathGeometryを取得して変更
        private void ChangeGeometry()
        {
            //tolerance(公差、許容できる誤差)は0に近いほど正確だけど、そのぶん計算量が多そう
            //toleranceTypeはよくわからん、Absolute絶対 or Relative相対を指定
            if (RadioAbsolute.IsChecked == true)
            {
                StepLine.Data = MyPath.Data.GetFlattenedPathGeometry(StepSlider.Value, ToleranceType.Absolute);
            }
            else if (RadioRelative.IsChecked == true)
            {
                StepLine.Data = MyPath.Data.GetFlattenedPathGeometry(StepSlider.Value, ToleranceType.Relative);
            }
        }
    }
}
 
曲線を近似の直線に変換してもあんまり嬉しくないけど、直線にすると長さを測れるとかがある
 
 
コード
 
関連記事
次、2018/06/15は翌日
Pathを等分したところに印と角度を表示してみた、GetPointAtFractionLength ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15550562.html