微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何检查直线多边形是否相交

如何解决如何检查直线多边形是否相交

我正在尝试用 C 创建一个程序来检查直线多边形的线是否在任何点相交。
我只需要在任何点都不相交的简单直线多边形。可以逆时针或顺时针。

方向值将小于 10。NS 方向必须与 WE 方向交替,反之亦然。

正在传递的输入采用来自输入文件的指示形式,例如;并在图片显示

S 2 E 4 S 2 E 4 N 2 W 4 N 2 W 4

EXAMPLE Images

我尝试将点存储在二维数组中,每个点都被检查为真,但我无法弄清楚如何在逆时针方向移动,因为这些点可能是 N4 E6 或 S4 W6。在这种情况下,如果我在值为 N-4 (x,y) = (0,4) 时添加并在 S-4 (x,-4) 时减去,则将其用作数组中的索引。

int arr[10][10];
int xPrime = 0,yPrime = 0;

bool checkContinuity(int y,const char * dir ){

    if(strcmp(dir,"S")==0){
        y = -y;
        cols = y;
        int j;
        for(j = cols; j >= 0; j--){
            if(arr[xPrime][j] == 1 && j != yPrime){
                return false;
            }
            arr[xPrime][j] = 1;             
            printf(" %d ",j);
        }
        yPrime -= y;
        if(yPrime < 0)
            yPrime = -yPrime;
    }
    else if(strcmp(dir,"W")==0){
        y = -y;
        cols = y;       
        int j;
        for(j = cols; j >= 0; j--){
            if(arr[j][yPrime] == 1 && j != xPrime && (j != 0 && yPrime != 0)){
                return false;
            }
            arr[j][yPrime] = 1;
            printf(" %d ",j);  
        }
        xPrime -= y;
        if(xPrime < 0)
            xPrime = -xPrime;
    }
    else if(strcmp(dir,"N")==0){
        cols = y;
        int j;
        for(j = 0; j <= cols; j++){
            if(arr[xPrime][j] == 1)
                return false;
            arr[xPrime][j] = 1; 
            printf(" %d ",j);
        }
        yPrime += y;
    }
    else if(strcmp(dir,"E")==0){
        cols = y;
        int j;
        for(j = 0; j <= cols; j++){
            if(arr[j][yPrime] == 1 && j != xPrime)
                return false;
            arr[j][yPrime] = 1;
            printf(" %d ",j);  
        }
        xPrime += y;
    }
    else
        return false;
            
    return true;
}

解决方法

存储实际多边形可能比存储所有可能的多边形更容易 平面的点。这样我们就不受选择的限制 点数组(代码中的 arr )。请参阅此工作示例:

  • 多边形存储在整数数组中 P = {0,x1,y1,x2,y2,...}

  • 线段是两点多边形。函数 'intersection' 检查是否 两个这样的线段 Q 和 P 相交; 如果是,则返回交点坐标。

  • 它使用辅助函数“between”来检查一个数字是否在其他两个数字之间。

  • 函数'next'计算多边形的下一个点,假设 输入作为字符字符串提供(例如:“S2E4S2E4N2W4N2W4”)

  • 在函数 main 中,我们现在遍历所有段,并检查它们是否与 任何以前的。

    当然,应该在某个时候检查输入的完整性等

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


void
next(           const char *s,int *v          )
{
        v[2] = v[0]; 
        v[3] = v[1];
        int step = s[1] - '0';
        switch(s[0]) {
        case 'S': v[3] -= step; break;
        case 'N': v[3] += step; break;
        case 'W': v[2] -= step; break;
        case 'E': v[2] += step; break;
        }
}


int
between(        int x,int a,int b           )
{
        return a < b ? x >= a && x <= b : x >= b && x <= a;
}

int
intersection(   int *P,int *Q,int *R          )
{
        if(P[0] == P[2] && Q[1] == Q[3]){  // P vertical,Q horizontal (w.l.o.g.)
                if(between(P[0],Q[0],Q[2]) && between(Q[1],P[1],P[3])){
                        R[0] = P[0]; 
                        R[1] = Q[1]; 
                        return 1;
                } else
                        return 0;
        }else if(Q[0] == Q[2] && P[1] == P[3])
                return intersection(Q,P,R);
        else return 0;
}

int
main() {
        char *s = "S2E4S2E4N2W4N2W4";
        
        int n = strlen(s) / 2,// number of steps
                *P = calloc((n + 1) * 2,sizeof(int)),// polygon
                R[2];                                           // intersection
        if(!P) exit(137);
        
        for(int k = 0; k < n; k++){
                next(s + 2 * k,P + 2 * k);
                for(int j = 0; j < k - 1; j++) {
                        if(intersection(P + k * 2,P + j * 2,R)) {
                                printf("Intersection at: %d,%d\n",R[0],R[1]);
                                exit(0);
                        }
                }
        }
        printf("No intersection\n");
}
        

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。