如何在圆的边界处连接线和圆

时间:2017-10-14 10:33:34

标签: c# wpf

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

1 个答案:

答案 0 :(得分:2)

首先,使用数学方法找到圆与直线之间的交点:

result = json.loads(requests.get('https://robot-reviewer.vortext.systems/report_view/'+id+'/json').content)

然后,连接他们:

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