判断多个区间是否相交

写一个算法判断多个区间是否存在交叉 在很久以前或许我会if else解决问题,随着工龄的增加对这种代码也是不屑一顾,思考良久出现一个方案还不错,提供给类似需求的人参观斧正

试想 多个区间在一个横坐标中 As Ad 分表标示A区间的开始结束,依次类推

—As—Ad———Bs——Cs——Bd————Cd———

在程序中要想表达A区间可以用map实现,As作为A区间的key,Ad作为A区间的value,便可实现区间的一个开始结束的对应关系的描述//是否想交

sections := make(map[float64]float64)

for _, v := range files {

        _, exist := sections[v.InsertTime]

         if exist { //如果key已经存在,那么出现依次想交即有两个Ns是重复的,抛出异常

            return errors.New(strconv.Itoa(exception.VideoSectionError) + "," + exception.MessageMap[exception.VideoSectionError])

         }

  sections[v.InsertTime] = v.InsertTime + v.Duration //组建 多区间map数据结构

}

这样就可以描述 多个区间 接下来就是判断是否想交问题咯,也是关键。

我的思想是 循环多个区间map将他们map的所有键值对加入数组,循环数组,判断数组的元素 N,的下一个元素N+1是否是Ns和Nd v

ar pave []float64 //存放区间键值对数组

for k, v := range sections { //想数组中存值

      pave = append(pave, k)

       pave = append(pave, v)

}

sort.Sort(sort.Float64Slice(pave)) //对数组进行排序

for i, startSection := range pave { //循环数组

       endSection, exist := sections[startSection] //在map数据中取 查询元素 是否为key

       if exist { //如果是key

          if endSection != pave[i+1] && startSection != pave[i+1] { //判断这个key的value是否是数组元素 startSection+1这个元素的值,如果不是,做出现咯相交

              return true

           }

       }

}

return false 到此为止,

核心思想就是多个区间在横坐标中形成一个数组,其中一个数组元素的如果为某个区间的开始那么他的下一个元素必定为这个区间的结束

转载于:https://my.oschina.net/dengdajun/blog/2961080

### C# 实现圆弧与矩形相交算法 为了实现判断圆弧与矩形是否相交的功能,可以采用几何方法来处理这个问题。具体来说,可以通过以下几个方面来进行计算: #### 圆弧定义 首先需要明确定义圆弧的数据结构。通常情况下,一个圆弧由中心点 `(cx, cy)`、半径 `r`、起始角度 `startAngle` 和结束角度 `endAngle` 组成。 ```csharp public class Arc { public double CenterX { get; set; } public double CenterY { get; set; } public double Radius { get; set; } public double StartAngle { get; set; } // 起始角 (度数) public double EndAngle { get; set; } // 结束角 (度数) public Arc(double centerX, double centerY, double radius, double startAngle, double endAngle) { CenterX = centerX; CenterY = centerY; Radius = radius; StartAngle = startAngle; EndAngle = endAngle; } } ``` #### 矩形定义 对于矩形,则通过左上角坐标 `(left, top)` 及宽度 `width` 和高度 `height` 来描述其位置和大小。 ```csharp public struct Rectangle { public double Left { get; set; } public double Top { get; set; } public double Width { get; set; } public double Height { get; set; } public Rectangle(double left, double top, double width, double height) { Left = left; Top = top; Width = width; Height = height; } public bool ContainsPoint(double x, double y) { return x >= Left && x <= Left + Width && y >= Top && y <= Top + Height; } } ``` #### 判断函数 接下来编写用于检测两者之间是否存在交叉关系的核心逻辑。这里主要考虑两种情况:一是整个圆形完全位于矩形内部;二是部分区域重叠但不一定覆盖全部范围的情况。 ```csharp using System; public static class IntersectionHelper { private const double PI_2 = Math.PI * 2; /// <summary> /// 将给定的角度转换到 [0, 360) 度区间内. /// </summary> private static double NormalizeAngleDegrees(double angleDeg) { while (angleDeg < 0) angleDeg += 360; while (angleDeg >= 360) angleDeg -= 360; return angleDeg; } /// <summary> /// 计算两点之间的距离平方. /// </summary> private static double DistanceSquared(double x1, double y1, double x2, double y2) { var dx = x2 - x1; var dy = y2 - y1; return dx * dx + dy * dy; } /// <summary> /// 检查指定的点是否落在圆弧范围内. /// </summary> private static bool IsPointOnArc(Arc arc, double px, double py) { var distSqrd = DistanceSquared(px, py, arc.CenterX, arc.CenterY); if (!Math.Abs(distSqrd - arc.Radius * arc.Radius).IsAlmostZero()) return false; var angleRad = Math.Atan2(py - arc.CenterY, px - arc.CenterX); // [-PI, PI] var angleDeg = NormalizeAngleDegrees(angleRad.ToDegrees()); var normalizedStartAngle = NormalizeAngleDegrees(arc.StartAngle); var normalizedEndAngle = NormalizeAngleDegrees(arc.EndAngle); if (normalizedStartAngle <= normalizedEndAngle) { return angleDeg >= normalizedStartAngle && angleDeg <= normalizedEndAngle; } else { return !(angleDeg < normalizedStartAngle && angleDeg > normalizedEndAngle); } } /// <summary> /// 测试两个图形是否有任何接触或重叠的部分. /// </summary> public static bool DoesIntersect(this Arc arc, Rectangle rect) { // 如果圆心在矩形外且离边界的最短距离大于等于半径则无交集 var closestDistToEdgeSqr = GetClosestDistanceFromCircleCenterToRectangleEdgesSquared(arc, rect); if (closestDistToEdgeSqr >= arc.Radius * arc.Radius) return false; // 枚举四个顶点看有没有落在圆弧上的 foreach (var corner in new[] { new Point(rect.Left, rect.Top), new Point(rect.Left + rect.Width, rect.Top), new Point(rect.Left, rect.Top + rect.Height), new Point(rect.Left + rect.Width, rect.Top + rect.Height)}) { if (IsPointOnArc(arc, corner.X, corner.Y)) return true; } // 进一步检查四条边上是否有线段穿过圆弧... // ...此处省略更多细节... throw new NotImplementedException(); } /// <summary> /// 获取圆心到矩形各边界最近的距离平方. /// </summary> private static double GetClosestDistanceFromCircleCenterToRectangleEdgesSquared(Arc arc, Rectangle rect) { var cx = arc.CenterX; var cy = arc.CenterY; var clampedX = Math.Max(Math.Min(cx, rect.Left + rect.Width), rect.Left); var clampedY = Math.Max(Math.Min(cy, rect.Top + rect.Height), rect.Top); return DistanceSquared(clampedX, clampedY, cx, cy); } } // 扩展浮点数比较工具类 public static class DoubleExtensions { public static bool IsAlmostZero(this double value) => Math.Abs(value) < 1e-8; public static double ToRadians(this double degrees) => degrees / 180.0 * Math.PI; public static double ToDegrees(this double radians) => radians * 180.0 / Math.PI; } /// <summary> /// 表示二维平面上的一个点. /// </summary> public struct Point { public readonly double X; public readonly double Y; public Point(double x, double y) : this() { X = x; Y = y; } } ``` 上述代码实现了基本框架,其中还缺少一些具体的边缘条件处理以及性能优化措施,在实际应用中可能还需要进一步完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值