WPF Координаты пересечения от двух линейных объектов - PullRequest
4 голосов
/ 12 июня 2010

У меня есть два объекта Line в C # WPF, и я пытаюсь создать метод для определения координат, при которых линии пересекаются (если вообще). После того, как я почувствовал головную боль, напоминая себе о математике в старшей школе, я не могу понять, как преобразовать это в формат программирования - кто-нибудь знает, как это сделать?

Большое спасибо, Бекки

Ответы [ 3 ]

4 голосов
/ 13 июня 2010

Это скорее отвратительный ответ, чем практический, потому что если все, что вы делаете, пересекает две линии, то это очень медленно.Однако я подумал, что стоит упомянуть.

WPF имеет возможность пересекать любые две контуры фигуры, включая две линии, и сообщать вам местоположение пересечения.

Вот общая методикадля пересечения двух контуров (края, а не область заливки):

var shape1 = ...;
var shape2 = ...;

var thinPen = new Pen(Brush.Transparent, 0.001);

var geometry1 = shape1.RenderedGeometry.GetWidenedPathGeometry(thinPen);
var geometry2 = shape2.RenderedGeometry.GetWidenedPathGeometry(thinPen);

var combined = Geometry.Combine(
                 geometry1,
                 geometry2,
                 GeometryCombineMode.Intersect,
                 shape2.TransformToVisual(shape1));

var bounds = combined.GetRenderBounds(thinPen);

Если известно, что фигуры имеют одинаковое положение, shape2.TransformToVisual(shape1) в вызове Geometry.Combine можно заменить на null.

Этот метод может быть очень полезен, если, например, вам необходимо пересечь линию с произвольной кривой.

4 голосов
/ 12 июня 2010

Полагаю, ваши линейные объекты состоят из двух точек. Что вы должны сделать, это получить уравнения обеих линий.

Тогда вы должны решить следующее уравнение:

уравнение-линия1 = уравнение-линия2

Рассчитать наклон линии:

    float _slope = 1e+10;
    if ((p2.x - p1.x) != 0)
        _slope = (p2.y - p1.y) / (p2.x - p1.x);

p1 = Точка 1 вашей линии p2 = точка 2 вашей линии

Уравнение строки:

у = топор + б

a = уклон, который вы рассчитали б = пересечение

Решение уравнения:

    a1 = p1.y - b1 * p1.x;
    a2 = q1.y - b2 * q1.x;

    x = (a1 - a2) / (b2 - b1);
    y = a2 + b2 * x;

вары:

  • b1 = линия наклона 1
  • b2 = наклонная линия 2
  • q1 = точка 1 вашей второй линии

Итак, x и y - координаты точки пересечения двух линий

0 голосов
/ 29 июня 2013

Как найти пересечение двух линий / сегментов / луча с прямоугольником

public class LineEquation{
    public LineEquation(Point start, Point end){
        Start = start;
        End = end;

        IsVertical = Math.Abs(End.X - start.X) < 0.00001f;
        M = (End.Y - Start.Y)/(End.X - Start.X);
        A = -M;
        B = 1;
        C = Start.Y - M*Start.X;
    }

    public bool IsVertical { get; private set; }

    public double M { get; private set; }

    public Point Start { get; private set; }
    public Point End { get; private set; }

    public double A { get; private set; }
    public double B { get; private set; }
    public double C { get; private set; }

    public bool IntersectsWithLine(LineEquation otherLine, out Point intersectionPoint){
        intersectionPoint = new Point(0, 0);
        if (IsVertical && otherLine.IsVertical)
            return false;
        if (IsVertical || otherLine.IsVertical){
            intersectionPoint = GetIntersectionPointIfOneIsVertical(otherLine, this);
            return true;
        }
        double delta = A*otherLine.B - otherLine.A*B;
        bool hasIntersection = Math.Abs(delta - 0) > 0.0001f;
        if (hasIntersection){
            double x = (otherLine.B*C - B*otherLine.C)/delta;
            double y = (A*otherLine.C - otherLine.A*C)/delta;
            intersectionPoint = new Point(x, y);
        }
        return hasIntersection;
    }

    private static Point GetIntersectionPointIfOneIsVertical(LineEquation line1, LineEquation line2){
        LineEquation verticalLine = line2.IsVertical ? line2 : line1;
        LineEquation nonVerticalLine = line2.IsVertical ? line1 : line2;

        double y = (verticalLine.Start.X - nonVerticalLine.Start.X)*
                   (nonVerticalLine.End.Y - nonVerticalLine.Start.Y)/
                   ((nonVerticalLine.End.X - nonVerticalLine.Start.X)) +
                   nonVerticalLine.Start.Y;
        double x = line1.IsVertical ? line1.Start.X : line2.Start.X;
        return new Point(x, y);
    }

    public bool IntersectWithSegementOfLine(LineEquation otherLine, out Point intersectionPoint){
        bool hasIntersection = IntersectsWithLine(otherLine, out intersectionPoint);
        if (hasIntersection)
            return intersectionPoint.IsBetweenTwoPoints(otherLine.Start, otherLine.End);
        return false;
    }

    public bool GetIntersectionLineForRay(Rect rectangle, out LineEquation intersectionLine){
        if (Start == End){
            intersectionLine = null;
            return false;
        }
        IEnumerable<LineEquation> lines = rectangle.GetLinesForRectangle();
        intersectionLine = new LineEquation(new Point(0, 0), new Point(0, 0));
        var intersections = new Dictionary<LineEquation, Point>();
        foreach (LineEquation equation in lines){
            Point point;
            if (IntersectWithSegementOfLine(equation, out point))
                intersections[equation] = point;
        }
        if (!intersections.Any())
            return false;

        var intersectionPoints = new SortedDictionary<double, Point>();
        foreach (var intersection in intersections){
            if (End.IsBetweenTwoPoints(Start, intersection.Value) ||
                intersection.Value.IsBetweenTwoPoints(Start, End)){
                double distanceToPoint = Start.DistanceToPoint(intersection.Value);
                intersectionPoints[distanceToPoint] = intersection.Value;
            }
        }
        if (intersectionPoints.Count == 1){
            Point endPoint = intersectionPoints.First().Value;
            intersectionLine = new LineEquation(Start, endPoint);
            return true;
        }

        if (intersectionPoints.Count == 2){
            Point start = intersectionPoints.First().Value;
            Point end = intersectionPoints.Last().Value;
            intersectionLine = new LineEquation(start, end);
            return true;
        }

        return false;
    }

    public override string ToString(){
        return "[" + Start + "], [" + End + "]";
    }
}

полный образец описан здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...