读取4点坐标。他们做广场吗?

时间:2012-05-28 14:14:42

标签: c++ algorithm

我计算点之间的距离,如果距离相等,则点成正方形,否则不计算。只有当我按以下顺序读取坐标A(x,y),B(x,y),C(x,y),D(x,y)或反向时,我的代码才有效。但是,如果我读这样的例如A(x,y),B(x,y),D(x,y),C(x,y)它将不起作用,因为dist方法将计算方形的对角线长度。我该如何解决这个问题?

#include <iostream>
using namespace std;

struct {
    int x;
    int y;
}a[10];

int dist(int x1, int y1, int x2, int y2)
{
    int c1, c2;
    c1 = x2-x1;
    c2 = y2-y1;
    return (c1*c1)+(c2*c2);
}

int main()
{
    int d1, d2, d3, d4;
    for (int i=1; i<=4; i++)
    {
        cout << 'X' << i << '='; cin >> a[i].x;
        cout << 'Y' << i << '='; cin >> a[i].y;
    }
    d1 = dist(a[1].x, a[1].y, a[2].x, a[2].y);
    d2 = dist(a[2].x, a[2].y, a[3].x, a[3].y);
    d3 = dist(a[3].x, a[3].y, a[4].x, a[4].y);
    d4 = dist(a[4].x, a[4].y, a[1].x, a[1].y);
    if(d1==d2 && d1==d3 && d1==d4)
        cout << "Is a square";
    else
        cout << "Is not a square";
    return 0;
}

4 个答案:

答案 0 :(得分:9)

检查距离是不够的,你需要检查至少一个角度,因为形状可能是一个菱形。

仅检查角度也是不够的,因为你最终可能会得到一个矩形。

点之间总共有6个距离。计算所有这些。在这6个中,4个应该相等(称其长度为x)。 - 这可以保证菱形

其他两个在它们之间应该相等(称其长度为y)。 这可以保证矩形

将菱形和矩形放在一起, BAM! - 方形。

答案 1 :(得分:2)

实际上,您只能使用内部产品进行角度操作。每个顶点A应该具有另外两个顶点B和C,使得AB和AC处于直角(0内积)以及一个顶点D,使得AB和AD以及AC和AD都精确地处于45度(标准化)点积= acos(45度),即~0.666)。如果对于所有四个顶点都是如此,则您有一个正方形。

答案 2 :(得分:2)

选择正方形的一个顶点(不失一般性说A)并将其视为原点。获得从原点到彼此角(AB,AC,AD)形成的3个向量。矢量地,这些由B-A,C-A和D-A给出。用另一个计算每个向量的内积。如果顶点形成矩形,则一个内积将为零(垂直边矢量)。如果它们形成正方形,则其他2个内部产品也必须彼此相等,因为它们之间的共同角度为45度。因此,如果一个内积为零而另外两个相等于彼此且4个距离相同则你有一个正方形。

答案 3 :(得分:0)

有四个点,你总共有六个距离。如果你计算距离的平方(当然这更容易),那么对于长度为L1,L2的任何一对边,以下都是真的

L1 == L2 || 2*L1 == L2 || L1 = 2*L2

您可以创建以下代码来实现此目的:

int isSquare (point *p1, point *p2, point *p3, point *p4) {
double dx, dy;
double dd[6];
point *pp[4];

pp[0]=p1; pp[1]=p2; pp[2]=p3; pp[3]=p4;
int ii, jj, kk, nn;
kk = 0;
// loop over all combinations of first and second point
// six in all
for(ii=0; ii<3; ii++) {
  for(jj=ii+1; jj<4; jj++) {
    dx = pp[ii]->x - pp[jj]->x;
    dy = pp[ii]->y - pp[jj]->y;
    dd[kk]= dx*dx + dy*dy;
    if (dd[kk]==0) return 0; // two identical points: not a square
    if(kk>1) {
      for(nn= 0; nn < kk-1; nn++) {
        // if both are "sides", we expect their length to be the same;
        // if one is a diagonal and the other a side, their ratio is 2
        // since we are working with the square of the number
        if (!(((2*dd[nn] == dd[kk] ) || \
               (dd[nn] == dd[kk])    || \
               (2*dd[kk] == dd[nn] )))) return 0;
      }
    }
     kk++;
  }
}
return 1; // got here: all combinations tested OK, we have a square

}