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; } } } }