当前位置: 首页 > 知识库问答 >
问题:

两个圆形扇形的交点

李森
2023-03-14

我正在尝试解决简单的任务,但我没有找到任何优雅的解决方案。

我基本上解决了两个圆形扇区的交集。每个扇区由(-pi, pi]范围内的2个角度(从atan2 func)给出。每个选择器占用的最大角度为179.999。所以每两个角度就可以知道圆形扇区的位置。

返回值应根据以下内容描述互交:

基本情况和一些例子见下图

问题是有太多的案件需要处理,我正在寻找一些优雅的方法来解决。

只有当两个角度在单位圆的右侧时,我才能比较它们

if(x not in <-pi/2, pi/2>)
{
    c = getSign(x)*pi/2;
    x = c - (x - c);
}

但是占据单位圆两半部分的扇区存在一个问题…

案例实在是太多了...有人知道如何优雅地解决这个问题吗?(我使用c,但任何提示或伪代码都可以)


共有1个答案

董良策
2023-03-14

您可以执行以下操作:

>

  • 将每个扇区归一化为形式(s_starts_start),其中s _start</code>位于(-pi,pi]),s _start位于( )。
  • 对扇区进行排序(交换),以便s0_start

    a)<代码> s1_start

    b)s1_start

    b1)s0_start2*pi

    B2) s0_start 2*pi

    因此,我们得到以下代码:

    const double PI = 2.*acos(0.);
    struct TSector { double a0, a1; };
    
    // normalized range for angle
    bool isNormalized(double a)
    { return -PI < a && a <= PI; }
    // special normal form for sector
    bool isNormalized(TSector const& s)
    { return isNormalized(s.a0) && s.a0 <= s.a1 && s.a1 < s.a0+PI; }
    
    // normalize a sector to the special form:
    // * -PI < a0 <= PI
    // * a0 < a1 < a0+PI
    void normalize(TSector& s)
    {
       assert(isNormalized(s.a0) && isNormalized(s.a1));
    
       // choose a representation of s.a1 s.t. s.a0 < s.a1 < s.a0+2*PI
       double a1_bigger = (s.a0 <= s.a1) ? s.a1 : s.a1+2*PI;
       if (a1_bigger >= s.a0+PI)
         std::swap(s.a0, s.a1);
       if (s.a1 < s.a0)
         s.a1 += 2*PI;
    
       assert(isNormalized(s));
    }
    
    bool intersectionNormalized(TSector const& s0, TSector const& s1,
                                TSector& intersection)
    {
      assert(isNormalized(s0) && isNormalized(s1) && s0.a0 <= s1.a0);
    
      bool isIntersecting = false;
      if (s1.a0 <= s0.a1) // s1.a0 inside s0 ?
      {
        isIntersecting = true;
        intersection.a0 = s1.a0;
        intersection.a1 = std::min(s0.a1, s1.a1);
      }
      else if (s0.a0+2*PI <= s1.a1) // (s0.a0+2*PI) inside s1 ?
      {
        isIntersecting = true;
        intersection.a0 = s0.a0;
        intersection.a1 = std::min(s0.a1, s1.a1-2*PI);
      }
      assert(!isIntersecting || isNormalized(intersection));
    
      return isIntersecting;
    }
    
    main()
    {
      TSector s0, s1;
      s0.a0 = ...
      normalize(s0);
      normalize(s1);
      if (s1.a0 < s0.a0)
        std::swap(s0, s1);
      TSection intersection;
      bool isIntersection = intersectionNormalized(s0, s1, intersection);
    }
    

  •  类似资料:
    • 我有两个矩形,每个矩形有4个值: 左侧位置< code>X、顶部位置< code>Y、宽度< code>W和高度< code>H: 矩形不旋转,如下所示: 判断两个矩形的交集是否为空的最佳解是什么?

    • 创建一个名为“Circle”的Java类来实现Java。io。可串行化接口,并基于半径对圆进行建模。半径不能小于零。实现radius的getter和setter方法。还包括在circle类中重写toString。创建类的比较器,用于比较Circle类型的两个对象。 这就是我目前所拥有的 这是我的比较器类 我的问题是我做得对还是不对?

    • 我有一组随机分布的二维点。我需要对这些点的一个小子集执行时间密集操作,但我需要首先找出我需要对哪些点执行这个时间密集操作。为了确定我需要什么点,它们必须通过一系列几何准则。 有没有一个有效的算法来找到什么2D点在一个圆扇区? 需要注意的是,我们的特定系统在浮点数学和三角学方面都很慢,所以一个解决方案涉及的较少,需要大量的浮点数学和三角学是更好的解决方案。

    • 我需要找到从圆和矩形的交点创建的最大弧线。我有了圆心,半径和矩形的坐标,我需要找到与圆心交点的角。 我有一个可以工作的代码,但它是通过迭代圆周上的点来计算解的,我想知道是否有更优雅的方法来使用三角学而不是“蛮力”来计算解。 这是我的代码:

    • 每个扇区可以表示为(x,y,r,a,d),其中x,y是位置,r是半径,d是方向,a是角度。给定两个圆形扇区的这些信息,如何确定它们是否相互重叠?有没有什么高效的算法来解决它?谢谢!

    • 问题内容: 我正在寻找一种确定矩形和圆形之间相交区域的快速方法(我需要进行数百万次此类计算)。 一个特殊的属性是,在所有情况下,圆形和矩形始终具有2个相交点。 问题答案: 给定2个交点: *圆内有 *0个顶点 :圆形线段的面积 1个顶点 在圆内:圆弧段和三角形的面积之和。 *圆内有 *2个顶点 :两个三角形和一个圆形线段的面积之和 *圆内有 *3个顶点 :矩形的面积减去三角形的面积再加上圆形线段的