C# 曲线上的点获取指定横坐标对应的纵坐标值

39 阅读2分钟

前言

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

如下图形:

实现方案

曲线上的点集

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

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

public List<Point> GetPointsOnPath(Geometry geometry)
{
    List<Point> points = new List<Point>();
    PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry();
    foreach (var figure in pathGeometry.Figures)
    {
        var ordinateOnPathFigureByAbscissa = GetOrdinateOnPathFigureByAbscissa(figure);
        points.AddRange(ordinateOnPathFigureByAbscissa);
    }
    return points;
}
private List<Point> GetOrdinateOnPathFigureByAbscissa(PathFigure figure)
{
    List<Point> outputPoints = new List<Point>();
    Point current = figure.StartPoint;
    foreach (PathSegment s in figure.Segments)
    {
        PolyLineSegment segment = s as PolyLineSegment;
        LineSegment line = s as LineSegment;
        Point[] points;
        if (segment != null)
        {
            points = segment.Points.ToArray();
        }
        else if (line != null)
        {
            points = new[] { line.Point };
        }
        else
        {
            throw new InvalidOperationException("尼玛!");
        }
        foreach (Point next in points)
        {
            var ellipse = new Ellipse()
            {
                Width = 6,
                Height = 6,
                Fill = Brushes.Blue
            };
            Canvas.SetTop(ellipse, next.Y);
            Canvas.SetLeft(ellipse, next.X);
            ContentCanvas.Children.Add(ellipse);
            current = next;
        }
    }
    return outputPoints;
}

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

曲线上的点

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

直线通过斜率很容易获取横坐标对应的纵坐标,以上线形虽然不是直线,但是可以拿到一系列的密集点集。

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

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

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

private bool TryGetOrdinateOnVectorByAbscissa(Point start, Point end, double abscissa, out double ordinate)
{
    ordinate = 0.0;
    if ((start.X < end.X && abscissa >= start.X && abscissa <= end.X) ||
        (start.X > end.X && abscissa <= start.X && abscissa >= end.X))
    {
        var xRatio = (abscissa - start.X) / (end.X - start.X);
        var yLength = end.Y - start.Y;
        var y = yLength * xRatio + start.Y;
        ordinate = y;
        return true;
    }
    return false;
}

点击窗口,在曲线上,获取点击处X坐标对应的点。

效果图如下:

源码

Github: github.com/Kybs0/Point…

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:唐宋元明清2188

出处:cnblogs.com/kybs0/p/10596426.html

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!