zoukankan      html  css  js  c++  java
  • C# 曲线上的点(一) 获取指定横坐标对应的纵坐标值

    获取直线上的点,很容易,那曲线呢?二阶贝塞尔、三阶贝塞尔、多段混合曲线,如何获取指定横坐标对应的纵坐标?

    如下图形:

     实现方案

    曲线上的点集

    Geometry提供了一个函数GetFlattenedPathGeometry,可以获取其绘制后显示的多边形。

    我们可以通过其Figures -> PathSegment -> Point,

     1     public List<Point> GetPointsOnPath(Geometry geometry)
     2     {
     3         List<Point> points = new List<Point>();
     4         PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry();
     5         foreach (var figure in pathGeometry.Figures)
     6         {
     7             var ordinateOnPathFigureByAbscissa = GetOrdinateOnPathFigureByAbscissa(figure);
     8             points.AddRange(ordinateOnPathFigureByAbscissa);
     9         }
    10         return points;
    11     }
    12     private List<Point> GetOrdinateOnPathFigureByAbscissa(PathFigure figure)
    13     {
    14         List<Point> outputPoints = new List<Point>();
    15         Point current = figure.StartPoint;
    16         foreach (PathSegment s in figure.Segments)
    17         {
    18             PolyLineSegment segment = s as PolyLineSegment;
    19             LineSegment line = s as LineSegment;
    20             Point[] points;
    21             if (segment != null)
    22             {
    23                 points = segment.Points.ToArray();
    24             }
    25             else if (line != null)
    26             {
    27                 points = new[] { line.Point };
    28             }
    29             else
    30             {
    31                 throw new InvalidOperationException("尼玛!");
    32             }
    33             foreach (Point next in points)
    34             {
    35                 var ellipse = new Ellipse()
    36                 {
    37                     Width = 6,
    38                     Height = 6,
    39                     Fill = Brushes.Blue
    40                 };
    41                 Canvas.SetTop(ellipse, next.Y);
    42                 Canvas.SetLeft(ellipse, next.X);
    43                 ContentCanvas.Children.Add(ellipse);
    44                 current = next;
    45             }
    46         }
    47         return outputPoints;
    48     }

    最终界面显示,获取的点集是如下布局的:

    曲线上的点

    我们发现,拐角越大,获取的点越密集。所以可以看出,角度变化越大,需要的点越密集。

    直线通过斜率很容易获取横坐标对应的纵坐标,那么这有如此多点的曲线呢?

    我们是不是可以曲线救国,通过相邻的俩个点画直接,从而获取俩点间的点坐标呢?我们来尝试下~

    还是原来的代码,传入一个X坐标参数即可。

    然后俩点之间,获取X坐标对应的Y坐标:

     1         private bool TryGetOrdinateOnVectorByAbscissa(Point start, Point end, double abscissa, out double ordinate)
     2         {
     3             ordinate = 0.0;
     4             if ((start.X < end.X && abscissa >= start.X && abscissa <= end.X) ||
     5                 (start.X > end.X && abscissa <= start.X && abscissa >= end.X))
     6             {
     7                 var xRatio = (abscissa - start.X) / (end.X - start.X);
     8                 var yLength = end.Y - start.Y;
     9                 var y = yLength * xRatio + start.Y;
    10                 ordinate = y;
    11                 return true;
    12             }
    13             return false;
    14         }

    点击窗口,在曲线上,获取点击处X坐标对应的点。效果图如下:

     

     Github: Demo

  • 相关阅读:
    Git中使用.gitignore忽略文件的推送
    git stash详解
    Git撤销&回滚操作(git reset 和 get revert)
    git rebase和git merge的区别
    git撤销已经push到远程仓库上的代码
    Git Merge
    git cherry-pick 教程
    Failed to start LSB: Bring up/down错误解决方法
    linux centos7安装部署gitlab服务器
    CentOs7 HP找回root密码
  • 原文地址:https://www.cnblogs.com/kybs0/p/10596426.html
Copyright © 2011-2022 走看看