4

我计算点之间的距离,如果距离相等,则点形成正方形,否则不。只有当我按以下顺序读取坐标时,我的代码才有效 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

4 回答 4

9

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

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

点之间总共有 6 个距离。计算所有这些。在这 6 个中,四个应该相等(称为它们的长度x)。-这保证了菱形

另外两个应该彼此相等(称为它们的长度y)。这保证了一个矩形

把一个菱形和一个长方形放在一起,BAM!- 正方形。

于 2012-05-28T14:22:31.257 回答
2

实际上,您可以使用内积仅使用角度来做到这一点。每个顶点 A 应该有另外两个顶点 B 和 C 使得 AB 和 AC 成直角(0 内积)以及一个顶点 D 使得 AB 和 AD 以及 AC 和 AD 都正好是 45 度(归一化点积 = acos(45 度),即 ~ 0.6675)。如果所有四个顶点都是这样,那么你就有了一个正方形。

于 2012-05-28T14:35:04.143 回答
2

选择正方形的一个顶点(不失一般性说 A)并认为这是原点。获取从原点到彼此角(AB,AC,AD)形成的 3 个向量。这些向量由 BA、CA 和 DA 给出。计算每个向量与另一个向量的内积。如果顶点形成一个矩形,则一个内积将为零(垂直边向量)。如果它们形成一个正方形,那么由于它们之间的公共角度为 45 度,其他 2 个内积也必须彼此相等。因此,如果一个内积为零且其他 2 个彼此相等且 4 个距离相同,则您有一个正方形。

于 2012-05-28T17:13:55.770 回答
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

}
于 2014-04-25T23:02:52.057 回答