c# - 如何计算wpf中形状的方向

标签 c# wpf

下面的代码片段在路径的末端生成一条曲线和箭头,如下图所示,在使用 C# 的 wpf 中。您所要做的就是为函数提供起点和终点。您会在下图中看到左侧的红色箭头 与路径的对齐方式不正确。右侧的红色箭头 已正确对齐,但我不确定如何计算正确的方向?有没有人对我如何做到这一点有建议或解决方案?图像中的绿色点表示函数中生成的点。

谢谢。

enter image description here

// Return the shape's path and arrow geometry.
protected override Geometry DefiningGeometry
{
    get
    {
        GeometryGroup group = new GeometryGroup();

        // Used for curvey lines
        GenerateCurvedLine(group);
        //GeneratedCurvedArrow(group);

        // Used for straight lines
        //GeneratedStraightLine(group);
        GenerateArrowHeadGeometry(group);

        // Return cached geometry.
        return group;
    }
}

// Generate the geometry for a curved line connecting the start and end points.
private void GenerateCurvedLine(GeometryGroup geometryGroup)
{
    //Calculate points between start and end plugs
    Point secondPoint = new Point(this.Start.X, this.Start.Y + 50);
    Point thirdPoint = new Point(this.End.X, this.End.Y - 50);

    // Build geometry for the curvey line.
    PathFigure curvedPath = new PathFigure();
    curvedPath.IsClosed = false;
    curvedPath.IsFilled = false;
    curvedPath.StartPoint = this.Start;
    curvedPath.Segments.Add(new BezierSegment(secondPoint, thirdPoint, this.End, true));

    PathGeometry pathGeometry = new PathGeometry();
    pathGeometry.Figures.Add(curvedPath);
    geometryGroup.Children.Add(pathGeometry);
}

在路径的末端生成箭头,同时将其指向起点。

// Generate the geometry for the three optional arrow symbol at the end of the path.
private void GenerateArrowHeadGeometry(GeometryGroup geometryGroup)
{
    EllipseGeometry ellipse = new EllipseGeometry(this.Start, DotSize, DotSize);
    geometryGroup.Children.Add(ellipse);

    Vector startDir = this.End - this.Start;
    startDir.Normalize();
    Point basePoint = this.End - (startDir * ArrowHeadLength);
    Vector crossDir = new Vector(-startDir.Y, startDir.X);

    Point[] arrowHeadPoints = new Point[3];
    arrowHeadPoints[0] = this.End;
    arrowHeadPoints[1] = basePoint - (crossDir * (ArrowHeadWidth / 2));
    arrowHeadPoints[2] = basePoint + (crossDir * (ArrowHeadWidth / 2));

    // Build geometry for the arrow head.
    PathFigure arrowHeadFig = new PathFigure();
    arrowHeadFig.IsClosed = true;
    arrowHeadFig.IsFilled = true;
    arrowHeadFig.StartPoint = arrowHeadPoints[1];
    arrowHeadFig.Segments.Add(new LineSegment(arrowHeadPoints[0], true));
    arrowHeadFig.Segments.Add(new LineSegment(arrowHeadPoints[2], true));

    PathGeometry pathGeometry = new PathGeometry();
    pathGeometry.Figures.Add(arrowHeadFig);

    geometryGroup.Children.Add(pathGeometry);
}

最佳答案

免责声明:我不是数学专家...所以这可能都是错误的。

您需要计算出曲线向直线末端的斜率。如果您在时间 t=0.95 时使用贝塞尔曲线的参数方程(您可能需要调整此值),然后在时间 t=1.0 时再次使用(这就是 this.End),然后减去它们,您将得到您想要的需要(曲线末端的斜率)。

要计算它,请参阅 Quadratic Bezier Curve: Calculate Point - 您需要立方答案(第二个答案)。

在 GenerateCurvedLine 中,像这样计算箭头方向:

var t = 0.95;
var x1 = (1 - t) * (1 - t) * (1 - t) * this.Start.X
        + 3 * (1 - t) * (1 - t) * t * secondPoint.X
        + 3 * (1 - t) * t * t * thirdPoint.X
        + t * t * t * this.End.X;
var y1 = (1 - t) * (1 - t) * (1 - t) * this.Start.Y
        + 3 * (1 - t) * (1 - t) * t * secondPoint.Y
        + 3 * (1 - t) * t * t * thirdPoint.Y
        + t * t * t * this.End.Y;
arrowDir = new Vector(this.End.X - x1, this.End.Y - y1);

在 GenerateArrowHeadGeometry 中,使用上面的 arrowDir 而不是您的 startDir。

仅供引用 - 对于曲线上的点,t(时间)的范围为 0 到 1。 0 将是 this.Start,1 将是 this.End。因此,t=0.95 将接近曲线的末端。

关于c# - 如何计算wpf中形状的方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34932235/

相关文章:

c# - 如何在 .Net C# 中通过代理服务器打开套接字?

c# - 将即插即用设备映射到 PCI 插槽 ID,C#

c# - Visual Studio 2012 项目总是过时(.cs 已修改)

c# - 组合框不显示分组

c# - 调试由另一个 exe 运行的 exe

wpf - Windows 8 桌面应用程序 : Open tabtip. exe 到辅助键盘(用于数字文本框)

c# - 第一个敏捷项目——我应该先写什么?

c# - WPF 窗口 ShowDialog() 导致无法设置可见性或调用 Show

c# - IMul​​tiValueConverter - INotifyPropertyChanged

c# - 使用 .Net 类库进行依赖注入(inject)?