【計算幾何】判斷線段相交

/*
(A1-B1) × (B2-B1) * (B2-B1) × (A2-A1) >= 0
(B1-A1) × (A2-A1) * (A2-A1) × (B2-A1) >= 0
*/

#include<stdio.h>
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
typedef struct {
double x,y;
}Point;
Point A1,A2,B1,B2;
Point  A1B1, B2B1, A2A1, B2A1;
double xx(Point &s,Point &t)
{
    return (s.x*t.y+s.y*t.x);
}
int kua()                           //跨立實驗
{
    A1B1.x=A1.x-B1.x;  A1B1.y=A1.y-B1.y;
    B2B1.x=B2.x-B1.x;  B2B1.y=B2.y-B1.y;
    A2A1.x=A2.x-A1.x;  A2A1.y=A2.y-A1.y;
    B2A1.x=B2.x-A1.x;  B2A1.y=B2.y-A1.y;
    if(xx(A1B1,B2B1)*xx(B2B1,A2A1)>=0)
    {
        A1B1.y=-A1B1.y;A1B1.x=-A1B1.x;
        if(xx(A1B1,A2A1)*xx(A2A1,B2A1)>=0)
            return 1;
        else
            return 0;
    }
    else
        return 0;
}
int main()
{
    Point A1,A2,B1,B2;
    int flag=1,i,j,a,b,c,d,e,f;
    while(1)
    {
        scanf("%lf%lf%lf%lf",&A1.x,&A1.y,&A2.x,&A2.y);
        scanf("%lf%lf%lf%lf",&B1.x,&B1.y,&B2.x,&B2.y);
        if( min(A1.x,A2.x) <= max(B1.x,B2.x) &&
            min(B1.x,B2.x) <= max(A1.x,A2.x) &&
            min(A1.y,A2.y) <= max(B1.y,B2.y) &&
            min(B1.y,B2.y) <= max(A1.y,A2.y)   )   //快速排斥實驗
        {
            if(kua())
                printf("線段相交\n");
            else
                printf("線段不相交\n");
        }
        else
            printf("線段不相交\n");

    }
    return 0;
}
轉載自:http://blog.csdn.net/chenbang110/article/details/7742535



附例題:Jack Straws

#include <stdio.h>
#include <math.h>
int f[100];

struct Point
{
    double x,y;
};

struct Line
{
    Point a,b;
}L[20];
 
double min(double a,double b)
{
	if(a<b)
		return a;
	else
		return b;
}

double max(double a,double b)
{
	return a>b?a:b;
}

double mult(Point a, Point b, Point c) 
{ 
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); 
} 

int kua(Line x,Line y)
{
	double temp1,temp2;
	temp1=mult(y.a, x.b, x.a)*mult(x.b, y.b, x.a);
	temp2=mult(x.a, y.b, y.a)*mult(y.b, x.b, y.a);
	if(temp1>=0 && temp2>=0)
		return 1;
	else
		return 0;
	
}
int find(int x) 
{
    if(x==f[x])
		return x;
	else
		return f[x]=find(f[x]);
}
 
void unionSet(int x, int y) 
{
    x = find(x);
    y = find(y);
    if(x != y)
	{
        f[x] = y;
    }
}
 
int main()
{
    int n;
	int i,j;
    while(~scanf("%d", &n) && n)
	{
        for(i = 1; i <= n; ++i) 
		{
            f[i] = i;
        }
        for(i = 1; i <= n; ++i) 
		{
            scanf("%lf %lf %lf %lf", &L[i].a.x, &L[i].a.y, &L[i].b.x, &L[i].b.y);
        }
        int p, q;
        for(i = 1; i <= n; ++i)
		{
            for(j = 1; j <= n; ++j)
			{
				if(min(L[i].a.x,L[i].b.x)<=max(L[j].a.x,L[j].b.x) &&
				   min(L[j].a.x,L[j].b.x)<=max(L[i].a.x,L[i].b.x) &&
				   min(L[i].a.y,L[i].b.y)<=max(L[j].a.y,L[j].b.y) &&
				   min(L[j].a.y,L[j].b.y)<=max(L[i].a.y,L[i].b.y))
				{
					if(kua(L[i],L[j]))
						unionSet(i,j);
				}
				else
					continue;
				
            }
        }
        while(scanf("%d%d", &p, &q) && (p||q))
		{
            if(find(q) == find(p))
			{
                puts("CONNECTED");
            }
            else
			{
                puts("NOT CONNECTED");
            }
        }
    }
 
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章