我在C# WPF中有两个Line对象,我想构建一个方法来计算两条线是否相交,并找出它们的交点坐标。尽管我费尽心思回忆起高中数学知识,但是我仍然无法将其转换为编程格式。请问有谁知道如何解决这个问题?
非常感谢! Becky
我猜你的线对象由两个点组成。你应该做的是获得这两条线的方程。
然后你应该解决以下方程:
equation-line1 = equation-line2
计算一条线的斜率:
float _slope = 1e+10;
if ((p2.x - p1.x) != 0)
_slope = (p2.y - p1.y) / (p2.x - p1.x);
p1 = 线段的第一个点 p2 = 线段的第二个点
直线方程:
y = ax + b
a = 您计算得出的斜率 b = 截距
解直线方程:
a1 = p1.y - b1 * p1.x;
a2 = q1.y - b2 * q1.x;
x = (a1 - a2) / (b2 - b1);
y = a2 + b2 * x;
变量:
因此,x和y是两条直线相交的点的坐标。
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);
Geometry.Combine
中调用shape2.TransformToVisual(shape1)
的参数替换为null
。如何找到两条线段/射线与矩形的交点
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 + "]";
}
}
完整的示例在这里描述。