下面的代码片段在路径末尾生成一条曲线和箭头,如下图所示,使用C#在wpf中看到。您所要做的就是为函数提供起点和终点。您将在下图中看到左侧的红色箭头与路径错误对齐。右侧的红色箭头正确对齐,但我不确定如何计算正确的方向?有没有人有关于我如何做到这一点的建议或解决方案?图像中的绿点表示在函数中生成的点。
谢谢。
// 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);
}
答案 0 :(得分:1)
免责声明:我不是数学专家......所以这可能都是错的。
你需要弄清线的末端曲线的斜率。如果你在时间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。
FYI - t(时间)对于曲线上的点,范围从0到1。 0将是this.Start和1将是this.End。因此,t = 0.95将接近曲线的末端。