172 lines
5.5 KiB
C#
172 lines
5.5 KiB
C#
|
||
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;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
}
|