2017-10-14 55 views
0

我是c#wpf的新手,我想畫一個圖。我用CappedLine.cs作爲邊和橢圓作爲節點。我想繪製線條,直到到達圓圈並且不進入圓圈的邊界。如何連接線和圓圈的邊界

任何人都可以幫助我解決這個問題嗎? 如何檢測圓的邊界?

這裏是我的MainWindow.xaml.cs代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace LineCaps 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      Ellipse ellipse = new Ellipse(); 
      ellipse.Height = 20; 
      ellipse.Width = 20; 
      ellipse.Stroke = Brushes.Black; 
      Canvas.SetLeft(ellipse, 0); 
      Canvas.SetTop(ellipse, 40); 
      can.Children.Add(ellipse); 

      PathFigure myPathFigure = new PathFigure(); 
      myPathFigure.StartPoint = new Point(10, 50); 

      LineSegment myLineSegment = new LineSegment(); 
      myLineSegment.Point = new Point(200, 70); 

      PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection(); 
      myPathSegmentCollection.Add(myLineSegment); 

      myPathFigure.Segments = myPathSegmentCollection; 

      PathFigureCollection myPathFigureCollection = new PathFigureCollection(); 
      myPathFigureCollection.Add(myPathFigure); 

      PathGeometry myPathGeometry = new PathGeometry(); 
      myPathGeometry.Figures = myPathFigureCollection; 

      CappedLine myPath = new CappedLine(); 
      myPath.Stroke = Brushes.Black; 
      myPath.StrokeThickness = 1; 
      myPath.LinePath = myPathGeometry; 

      Geometry g= Geometry.Parse("M0,0 L6,-6 L6,6 z"); ; 
      myPath.BeginCap = g; 

      can.Children.Add(myPath); 

     } 
    } 
} 

,這是我的XAML代碼:

<Window x:Class="LineCaps.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:loc="clr-namespace:LineCaps" 
     Title="MainWindow"> 
    <Viewbox x:Name="vb"> 
     <Canvas x:Name="can" Height="350" Width="525"> 

     </Canvas> 
    </Viewbox> 
</Window> 

我以前從這裏CappedLine代碼:

https://blogs.msdn.microsoft.com/mrochon/2011/01/09/custom-line-caps-in-wpf/

我有這個結果:

I have this result

但我想這一個:

But I want this one

+0

不能正常工作......當線位於橢圓的左側時..那麼線會到達圓的右下側 –

+0

要做到這一點,我認爲你需要找到交點你的直線和矩形(使用直線和橢圓方程),然後從這一點開始你的直線(現在你從任意10,50點開始)。 – Evk

回答

2

首先,用數學的方法來找到圓與線之間的交叉點:

public Point? CalculateIntersection(Point circleCenter, double circleRadius, Point lineStart) 
{ 
    if (Math.Abs(circleCenter.X - lineStart.X) < double.Epsilon) 
    { 
     if (circleCenter.Y > lineStart.Y) 
     { 
      return new Point(circleCenter.X, circleCenter.Y - circleRadius); 
     } 
     return new Point(circleCenter.X, circleCenter.Y - circleRadius); 
    } 
    if (Math.Abs(circleCenter.Y - lineStart.Y) < double.Epsilon) 
    { 
     if (circleCenter.X > lineStart.X) 
     { 
      return new Point(circleCenter.X - circleRadius, circleCenter.Y); 
     } 
     return new Point(circleCenter.X + circleRadius, circleCenter.Y); 
    } 

    // translate to origin point 
    var translate = new Vector(-circleCenter.X, -circleCenter.Y); 

    circleCenter = circleCenter + translate; 
    lineStart = lineStart + translate; 

    // y=kx+t -> kx1+t=y1, kx2+t=y2 
    // k=(y1-y2)/(x1-x2), t=y1-kx1 
    var k = (circleCenter.Y - lineStart.Y)/(circleCenter.X - lineStart.X); 
    var t = circleCenter.Y - k * circleCenter.X; 

    // x^2+y^2=r^2, y=kx+t 
    // x^2+(kx+t)^2=r^2 -> (k^2+1)*x^2+2ktx+(t^2-r^2)=0 
    // ax^2+bx+c=0 -> x1=[-b+sqrt(b^2-4ac)]/2a x2=[-b-sqrt(b^2-4ac)]/2a 

    var r = circleRadius; 

    var a = k * k + 1; 
    var b = 2 * k * t; 
    var c = t * t - r * r; 

    var delta = b * b - 4 * a * c; 
    if (delta < 0) 
    { 
     // has no intersection 
     return null; 
    } 

    var sqrt = Math.Sqrt(delta); 

    var x1 = (-b + sqrt)/(2 * a); 
    var y1 = k * x1 + t; 

    var x2 = (-b - sqrt)/(2 * a); 
    var y2 = k * x2 + t; 

    var point1 = new Point(x1, y1); 
    var point2 = new Point(x2, y2); 

    if ((point1 - lineStart).Length < (point2 - lineStart).Length) 
    { 
     return point1 - translate; 
    } 
    return point2 - translate; 
} 

然後,連接他們:

var point = CalculateIntersection(new Point(10, 50), 10, new Point(200, 70)); 
if (point == null) 
{ 
    throw new Exception("no intersection between the line and the circle?"); 
} 
myPathFigure.StartPoint = point.Value; 
+0

這個很棒! 非常感謝.. –