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

dfty9e19  于 2023-03-19  发布在  其他
关注(0)|答案(3)|浏览(206)

我有三个已知的位置,目前我正在驾驶两条线路,如下所示:

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中做的那样:

或者至少得到类似的光滑度。

vom3gejh

vom3gejh1#

我想你是在找样条曲线
http://msdn.microsoft.com/en-us/library/554h284b.aspx
Gabe是正确的,这是从形式
在WPF下,你可以尝试一个PolyBezierSegment,但是它需要4个点。可能你可以在3个点和1个以上的形状。

<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>

这将产生以下曲线

olhwl3o2

olhwl3o22#

您希望使用PathFigure,特别是使用一组BezierSegments

uhry853o

uhry853o3#

为了实现平滑曲线,我们可以使用cubic bezier curves,如above answer上所示,带有PolyBezierSegment类。

工作原理

三次Bezier曲线由四个点定义:起始点、结束点和两个控制点。
对于集合中的每三个点,第一个点和第二个点指定曲线的两个控制点,第三个点指定终点。请注意,没有指定曲线的起点,因为起点与最后一段的终点相同。
如果只想指定动态计算控制点所需的每条线段的起点和终点,则这将取决于所需的曲率类型。
在下面的例子中,我将定义3个点,然后我将硬编码控制点来定义曲率,这应该是根据您的需要计算曲率的算法。

  • 请注意,我将起点添加到points集合中,尽管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);

结果:

相关问题