2016-01-21 104 views
2

下面的代碼片段在路徑的末尾生成一條曲線線條和箭頭,如使用C#在wpf中的下圖所示。所有你需要做的就是提供一個起點和終點的功能。您會在下圖中看到左側的紅色箭頭與路徑錯誤對齊。 紅色箭頭在右邊是正確對齊,但我不知道如何計算正確的方向?有沒有人有我的建議或解決方案可以做到這一點?圖像中的綠色點表示該函數中正在生成的點。如何在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); 
} 

回答

1

免責聲明:我不是數學專家......所以這可能都是錯誤的。

您需要計算曲線在曲線末端的斜率。如果你在時間t = 0.95時使用貝塞爾曲線的參數方程(你可能需要調整這個值),然後再在時間t = 1.0(這就是這個結尾),然後減去它們,你會得到你需要(最後曲線的斜率)。

要計算它,請參閱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將趨向曲線的末端。

+0

:)感謝您的免責聲明。我會對此進行測試並進一步研究。如果我想出任何有用的東西,我會發布它。 – JokerMartini

+0

我也更新代碼,以產生更多的插件n播放 – JokerMartini

+0

你的解決方案完美的作品謝謝你。 – JokerMartini