如何在WPF中绘制平滑的曲线?

12

我有三个已知位置,目前我正在驱动两条线路,如下:

Line line = new Line
{
    StrokeThickness = 3,
    Stroke = lineColor,
    X1 = MyX,
    Y1 = MyY,
    X2 = MyX,
    Y2 = MiddleY
};

Graph.Children.Add(line);

line = new Line
{
    StrokeThickness = 3,
    Stroke = lineColor,
    X1 = MyX,
    Y1 = MiddleY,
    X2 = TargetX,
    Y2 = TargetY
};

Graph.Children.Add(line);

这是结果:

在此输入图像描述

所以,你可以看到,这几乎是我想要的,除了我希望它更加平滑一点。

现在我正在寻找任何方法来设置三个点,将中间点设置为某种平滑/弯曲程度,然后在其上绘制具有实色的线条。 就像我在Photoshop中所做的那样:

在此输入图像描述

或者至少获得类似的平滑效果。


2
从这里开始:https://www.google.cz/search?q=spline+wpf - Euphoric
https://dev59.com/7mHVa4cB1Zd3GeqPqMhe - HB MAAM
4
@HBMAAM:你的链接与完全无关的问题。这个问题是关于绘制曲线,而你链接的问题是关于渐变的。 - Gabe
3个回答

15

我认为你在寻找样条曲线。

http://msdn.microsoft.com/en-us/library/554h284b.aspx

Gabe说的是关于Forms的。

在WPF下,你可以尝试使用PolyBezierSegment,但它需要4个点。 也许你可以放置三个点并再加一个来形成所需的形状。

<Canvas>
    <Path Stroke="Black" StrokeThickness="10">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigureCollection>    
                        <PathFigure StartPoint="100,80">
                            <PathFigure.Segments>
                                <PathSegmentCollection>
                                    <PolyBezierSegment Points="90,200 140,200 160,200 180,200 430,190 430,280" />
                                </PathSegmentCollection>
                            </PathFigure.Segments>
                        </PathFigure>
                    </PathFigureCollection>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
    </Path>
</Canvas>
这会产生以下曲线。

enter image description here


2
是的,楼主正在寻找样条曲线,但你提供的链接是针对WinForms的。楼主正在使用WPF,所以那个链接并没有帮助。 - Gabe
@Gabe 你说得对,我会寻找一个 WPF 的替代方案或者将其删除。谢谢。 - paparazzo
1
三个点再加上一个点来塑造它。试错法。 - paparazzo

2

0
为了实现平滑曲线,我们可以使用三次贝塞尔曲线,如上面的答案所示,使用PolyBezierSegment类。

它是如何工作的

一个三次贝塞尔曲线由四个点定义:起始点、终止点和两个控制点。

对于集合中的每三个点,第一个和第二个点指定曲线的两个控制点,第三个点指定终点。请注意,没有指定曲线的起始点,因为起始点与上一段的终点相同。

如果您只想指定每个段的起始点和终止点,则需要动态计算控制点,这将取决于您需要的曲率类型。

在以下示例中,我将定义3个点,然后硬编码控制点以定义曲率,这应该使用根据您的需求计算曲率的算法来完成。
请注意,我正在将起始点添加到点集合中,尽管path figure类需要一个起始位置点,而PolyBezierSegment类需要一个包含多个3(2个控制点和一个结束点)的集合。
//create 3 positions
Point start = new(50, 50),
    mid = new(80, 100),
    end = new(200, 150);

Point[] _points = new[]
{
    //start of line (and first segment)
    start,
    //First control point:
    new(start.X, start.Y + (mid.Y - start.Y) / 2),
    //Second control point:
    new(mid.X - (mid.X - start.X) / 2, mid.Y),
    //end of first segment and start of second.
    mid,
    new(mid.X + (end.X - mid.X) / 2, mid.Y),
    new(end.X, end.Y - (end.Y - mid.Y) / 2),
    end
;

//Create the segment connectors
PathGeometry connectorGeometry = new()
{
    Figures = new PathFigureCollection()
    {
        new PathFigure()
        {
            //define the start of the smooth line
            StartPoint = _points[0],
            //define the coordinates of the smooth line
            Segments = new PathSegmentCollection()
            {
                new PolyBezierSegment(
                    //in this example I added the start to the collection,
                    //so we skip the first coordinate already used on "StartPoint"
                    points: _points.Skip(1),
                    isStroked: true)
            }
        }
    }
};

Path smoothCurve = new()
{
    Stroke = Brushes.Black,
    StrokeThickness = 3,
    Data = connectorGeometry
};

Graph.Children.Add(smoothCurve);

结果:

Example


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接