C中的凸四边形

时间:2015-07-18 20:22:11

标签: c computational-geometry

有人可以帮我完成我的代码吗?我的程序应该计算每个不同的凸四边形,它可以由给定的点形成。 但是我的代码计算每个凸四边形,而不仅仅是这些,它们是不同的。

示例:

input
5
0 0
6 0
0 6
6 6
5 3
output
3     

但我的程序将printf 24用于此输入,因为它会计算每个凸四边形的次数。如何编辑我的代码只计算一次四边形?

编辑:我有这个代码只存储不同的凸四边形,但我的代码太慢,因为它仍然尝试每个选项。有没有其他方法来计算凸四边形? 我编辑的代码:

#include<stdio.h>

void bubbleSort(int list[],int size) {
  // kontrola prohozeni
  int swapped = 1,temp;
  while (swapped) {
    swapped = 0;
    for (int i = 0; i < size; i++) {
      // prohozeni
      if (list[i] > list[i + 1]) {
        temp = list[i];
        list[i] = list[i + 1];
        list[i + 1] = temp;
        swapped = 1;
      }
    }
    size--;
  }
}

/**
struct for coordination
*/
typedef struct
{
    int x;
    int y;
} POINT;

typedef struct
{
    int a;
    int b;
    int c;
    int d;

} ZAZNAM;

/**
*   if point 'z' is on right from line 'xy', function return negative value;
*   if point 'z' is on left from line 'xy', function return positive value;
*   if point 'z' is on line 'xy', function return 0;
*/
int calculate_vector(POINT x, POINT y, POINT z)
{
    int ux = y.x - x.x;
    int uy = y.y - x.y;
    int vx = z.x - x.x;
    int vy = z.y - x.y;
    return ux*vy - uy*vx;
}

int main()
{
    int i,j,k,l,n;
    int res1,res2,res3,res4,num;
    res1 = res2 = res3 = res4 = num = 0;
    scanf("%d",&n);
    POINT array[n];
    ZAZNAM zaz[120000];
    int cislo = 0;
    int nove;
    for(i = 0; i < n; i++)
        scanf("%d%d",&array[i].x, &array[i].y);
    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            if(j != i){
                for(k = 0; k < n; k++){
                    if(k != i && k != j){
                        for(l = 0; l < n; l++){
                            if(l != i && l != k && l != j){

                                                                                 //res1....res4 - position of point
                                res1 = calculate_vector(array[i],array[j],array[k]);   //position of *THIRD* POINT relative to line from the *FIRST* point to the *SECOND* point
                                res2 = calculate_vector(array[j],array[k],array[l]);   //position of *FOURTH* POINT relative to line from the *SECOND* point to the *THIRD* point
                                res3 = calculate_vector(array[l],array[k],array[i]);   //position of *FIRST* POINT relative to line from the *THIRD* point to the *FOURTH* point
                                res4 = calculate_vector(array[i],array[l],array[j]);   //position of *SECOND* POINT relative to line from the *FOURTH* point to the *FIRST* point
                                if((res1 > 0 && res2 > 0 && res3 > 0 && res4 > 0)||(res1 < 0 && res2 < 0 && res3 < 0 && res4 < 0)){ //if all points are from each other on right or on left, the quadrilateral is convex.
                                    int sort[4];
                                    sort[0] = i;
                                    sort[1] = j;
                                    sort[2] = k;
                                    sort[3] = l;
                                    bubbleSort(sort,3);
                                    nove = 1;
                                    for(int p = 0; p < cislo; p++){
                                        if(sort[0] == zaz[p].a && sort[1] == zaz[p].b && sort[2] == zaz[p].c && sort[3] == zaz[p].d){
                                            nove = 0;
                                            break;
                                        }
                                    }
                                    if(nove){
                                       zaz[cislo].a = sort[0];
                                       zaz[cislo].b = sort[1];
                                       zaz[cislo].c = sort[2];
                                       zaz[cislo++].d = sort[3];
                                       num++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    printf("%d\n",num);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

似乎没有人回答这个问题,所以我会对此采取行动。不确定你的代码是如何做到的,因为它至少对我来说缺乏一些清晰度。

  1. 创建一个由4个POINT组成的QUAD结构。

    typedef struct
    {
        POINT pt1;
        POINT pt2;
        POINT pt3;
        POINT pt4;
    }QUAD;
    
  2. 创建QUAD对象数组以存储要保留的四边形。

    QUAD Quads[MAX_QUADS]
    
  3. 或者如果您使用组合公式(12拍4)计算基于输入数量的可能四边形的总数

    QUAD *Quads;
    Quads = (QUAD*)malloc(nCombos * sizeof(QUAD)); 
    

    现在,对于4点的任意组合,只会形成1个“真实”四边形。其余的一些是复杂的(因此不是凸的),其余的是线性移位,反转或两者的重复。因此,首先形成一个四边形(无论哪个循环都是这样)并将其存储在QUAD结构中,然后使用来自相邻成员点的矢量数学形成矢量计算所有角度(例如,12和23组成一组矢量, 23&amp; 34组成下一个等等。

    现在检查角度。如果全部是&lt; 90你有一个复杂的四边形,所以划伤并转到下一个组合。如果任何角度> 180它是一个真正的凸四边形,所以检查你的索引(对于前面的QUAD数组),看看你是否已经存储了任何其他的四边形,如果你迭代通过每个四边形将它与当前的一个具有以下函数进行比较:< / p>

    bool bCompareQuads(QUAD qd1, QUAD qd2)    
    {
        if(qd1.pt1 == qd2.pt1)
            counter++;
        if(qd1.pt1 == qd2.pt2)
            counter++;
        if(qd1.pt1 == qd2.pt3)
            counter++;
        if(qd1.pt1 == qd2.pt4)
            counter++;
    
        if(qd1.pt2 == qd2.pt1)
            counter++;
        if(qd1.pt2 == qd2.pt2)
            counter++;
        if(qd1.pt2 == qd2.pt3)
            counter++;
        if(qd1.pt2 == qd2.pt4)
            counter++;
    
        if(qd1.pt3 == qd2.pt1)
            counter++;
        if(qd1.pt3 == qd2.pt2)
            counter++;
        if(qd1.pt3 == qd2.pt3)
            counter++;
        if(qd1.pt3 == qd2.pt4)
            counter++;
    
        if(qd1.pt4 == qd2.pt1)
            counter++;
        if(qd1.pt4 == qd2.pt2)
            counter++;
        if(qd1.pt4 == qd2.pt3)
            counter++;
        if(qd1.pt4 == qd2.pt4)
            counter++;
    
        if(counter > 3)
            return true;
        else
            return false;
    
        return false;//shouldn't happen, but just in case
    }
    

    如果它返回true,只是在没有存储的情况下突破,但是如果它没有将新的quad存储在数组中。最后,您只需打印出存储在阵列中的所有QUADS。