2010-06-12 3 views
4

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

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

ответ

4

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

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

уравнение-line1 = уравнение-line2

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

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

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

Уравнение линии:

у = ах + Ь

а = наклон вы рассчитывали б = Интерсекта

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

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

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

VARS:

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

Таким образом, х и у координаты точки, где две линии пересекаются

+0

Ее, как сделать это программно, что я не могу работать. –

+0

Я получил это далеко, это было линейное уравнение1 = линейное уравнение2, которое я не могу понять, так как, конечно, алгебра будет меняться каждый раз? –

+0

Имеет ли смысл? –

3

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

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.

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

0

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

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 + "]"; 
    } 
} 

полный образец описывается here

Смежные вопросы