【问题标题】:Integer point's Counter Clock Wise sorting整数点的逆时针排序
【发布时间】:2013-08-21 13:09:14
【问题描述】:

给定一个四边形的四个整数点,可以是任何类型(如菱形、矩形、梯形、平行四边形、正方形或普通四边形),我如何逆时针对这些点进行排序(不使用 atan2()函数或任何双点计算),这样我就不会以对角线作为它的边?

我已经将这样的代码编码为 struct :

typedef struct {
      long long x,y ;
} point ;

vector<point> p ;

在不使用任何双点计算的情况下,我无法弄清楚 sort 函数中的比较函数以 CCW 顺序对点进行排序。有人可以帮我吗?

【问题讨论】:

  • 四边形的形状不明确怎么办?请参阅此图像的最后一个(右下)示例:en.wikipedia.org/wiki/File:Six_Quadrilaterals.svg。这四个点可以用来画几个不同的四边形,这可能会改变你对排序的含义。
  • 您无法以一种或另一种方式使用小数。您可以使用分子和分母自己实现精确分数,但简单地使用浮点数更容易。您无法解决这个问题,因为在您的算法中的某个时刻,您将不得不比较点彼此之间的角度。要计算这些角度,没有办法绕过小数。这就引出了一个问题:为什么要避免“双分”?
  • 顺便说一句,tan(a)

标签: c++ geometry


【解决方案1】:

尝试类似的方法(假设您的支点位于 0, 0 ):

bool operator<(point other)
{
    // normalize both points
    if(y > 0 && other.y > 0)
        return x < other.x;
    else if(y < 0 && other.y < 0)
        return x > other.x;
    else
    {
        return y < other.y;
    }
}

【讨论】:

  • 对于没有“双点计算”的标准化点(brr...你的意思是从原点到点的向量,对吗?),我们需要使两个向量的长度相同,例如: first = (this)*length(other)/gcd(length(*this), length(other));第二=其他长度(第一)/gcd(长度(*这个),长度(其他));
  • 尝试在数据 { {1, -1}, {-1, 1}, {1, 1}, {-1, -1} } 我得到结果 { {1, -1}, {-1, -1}, {-1, 1}, {1, 1} },即顺时针,不是逆时针。
【解决方案2】:

您可以使用此代码(不需要规范化向量,也假设枢轴在 (0,0)):

int Quadrant( const Point &pt ) {
    if( pt.x >= 0 && pt.y >= 0 )
        return 0;
    if( pt.x < 0 && pt.y >= 0 )
        return 1;
    if( pt.x < 0 && pt.y < 0 )
        return 2;
    if( pt.x >= 0 && pt.y < 0 )
        return 3;
}

std::sort( std::begin( pt ), std::end( pt ), []( const Point &lhs, const Point &rhs ) {
    return Quadrant(lhs) < Quadrant(rhs) || ( Quadrant(lhs) == Quadrant(rhs) && lhs.x*rhs.y - lhs.y*rhs.x > 0 );
    });

我们将来自不同象限的点按象限进行比较,为了比较同一象限中的点,我们找到从原点到第二点的向量的点积符号,并在逆时针向量上从原点到第一点旋转 90 度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2011-10-16
    • 1970-01-01
    • 2021-11-05
    • 2012-12-11
    相关资源
    最近更新 更多