Files
MetroGauges-Old/MetroGauges/Controls/LineWithRect.cs
2026-02-23 17:02:55 +08:00

172 lines
5.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace MetroGauges.Controls
{
public class Circle
{
double _r, _x, _y;
public double R { get { return _r; } }
public double X { get { return _x; } }
public double Y { get { return _y; } }
Circle(double r, double x, double y) {
_r = r;
_x = x;
_y = y;
}
}
public class LineWithRect
{
public Rect rect = new Rect();
public Transform LineStart;
public Transform lineEnd;
Point leftDown
{
get
{
return new Point(rect.X, rect.Y+rect.Height);
}
}
Point leftUp
{
get
{
return new Point(rect.X, rect.Y);
}
}
Point RigtDown
{
get
{
return new Point(rect.X+rect.Width, rect.Y+rect.Height);
}
}
Point RightUp
{
get
{
return new Point(rect.X+rect.Width, rect.Y);
}
}
// 线是否在矩形内
public bool LineInRect(Point lineStart, Point lineEnd, Rect rect)
{
return rect.Contains(lineStart) || rect.Contains(lineEnd);
}
// 线与矩形是否相交
public bool LineIntersectRect(Point lineStart, Point lineEnd, Rect rect)
{
if (LineIntersectLine(lineStart, lineEnd, leftDown, leftUp))
return true;
if (LineIntersectLine(lineStart, lineEnd, leftUp, RightUp))
return true;
if (LineIntersectLine(lineStart, lineEnd, RightUp, RigtDown))
return true;
if (LineIntersectLine(lineStart, lineEnd, RigtDown, leftDown))
return true;
return false;
}
// 线与线是否相交
public bool LineIntersectLine(Point l1Start, Point l1End, Point l2Start, Point l2End)
{
return QuickReject(l1Start, l1End, l2Start, l2End) && Straddle(l1Start, l1End, l2Start, l2End);
}
// 快速排序。 true=通过, false=不通过
public bool QuickReject(Point l1Start, Point l1End, Point l2Start, Point l2End)
{
double l1xMax = Math.Max(l1Start.X, l1End.X);
double l1yMax = Math.Max(l1Start.Y, l1End.Y);
double l1xMin = Math.Min(l1Start.X, l1End.X);
double l1yMin = Math.Min(l1Start.Y, l1End.Y);
double l2xMax = Math.Max(l2Start.X, l2End.X);
double l2yMax = Math.Max(l2Start.Y, l2End.Y);
double l2xMin = Math.Min(l2Start.X, l2End.X);
double l2yMin = Math.Min(l2Start.Y, l2End.Y);
if (l1xMax < l2xMin || l1yMax < l2yMin || l2xMax < l1xMin || l2yMax < l1yMin)
return false;
return true;
}
// 跨立实验
public bool Straddle(Point l1Start, Point l1End, Point l2Start, Point l2End)
{
double l1x1 = l1Start.X;
double l1x2 = l1End.X;
double l1y1 = l1Start.Y;
double l1y2 = l1End.Y;
double l2x1 = l2Start.X;
double l2x2 = l2End.X;
double l2y1 = l2Start.Y;
double l2y2 = l2End.Y;
if ((((l1x1 - l2x1) * (l2y2 - l2y1) - (l1y1 - l2y1) * (l2x2 - l2x1)) *
((l1x2 - l2x1) * (l2y2 - l2y1) - (l1y2 - l2y1) * (l2x2 - l2x1))) > 0 ||
(((l2x1 - l1x1) * (l1y2 - l1y1) - (l2y1 - l1y1) * (l1x2 - l1x1)) *
((l2x2 - l1x1) * (l1y2 - l1y1) - (l2y2 - l1y1) * (l1x2 - l1x1))) > 0)
{
return false;
}
return true;
}
//相/判断直线p1p2与圆c是否相交交返回true否则返回false
public bool CheckLineCrircleReject(Point p1, Point p2, Circle c)
{
bool flag1 = (p1.X - c.X) * (p1.X - c.X) + (p1.Y - c.Y) * (p1.Y - c.Y) <= c.R * c.R;
bool flag2 = (p2.X - c.X) * (p2.X - c.X) + (p2.Y - c.Y) * (p2.Y - c.Y) <= c.R * c.R;
if (flag1 && flag2) //情况一、两点都在圆内 :一定不相交
return false;
else if (flag1 || flag2) //情况二、一个点在圆内,一个点在圆外:一定相交
return true;
else //情况三、两个点都在圆外
{
double A, B, C, dist1, dist2, angle1, angle2;
//将直线p1p2化为一般式Ax+By+C=0的形式。先化为两点式然后由两点式得出一般式
A = p1.Y - p2.Y;
B = p2.X - p1.X;
C = p1.X * p2.Y - p2.X * p1.Y;
//使用距离公式判断圆心到直线ax+by+c=0的距离是否大于半径
dist1 = A * c.X + B * c.Y + C;
dist1 *= dist1;
dist2 = (A * A + B * B) * c.R * c.R;
if (dist1 > dist2)//圆心到直线p1p2的距离大于半径不相交
return false;
angle1 = (c.X - p1.X) * (p2.X - p1.X) + (c.Y - p1.Y) * (p2.Y - p1.Y);
angle2 = (c.X - p2.X) * (p1.X - p2.X) + (c.Y - p2.Y) * (p1.Y - p2.Y);
if (angle1 > 0 && angle2 > 0)//余弦为正,则是锐角,一定相交
return true;
else
return false;
}
}
}
}