计算几何 线段的各种情况 [好题]

队内比赛又悲剧了,咱们队各种不在状态啊~ 我悲剧的计算几何就这么悲催咯~ 不过是个好题,可以用来做模板了。线段相交分为几种情况,1不相交,2,重叠,3相交端点在线上,4相交端点不在线上。

为什么还是这么弱啊~~ 和我不想编代码有关系!加油啊~狐狸


#include<stdio.h>
#include<cmath>
#include<string.h>
#define eps 1e-7

struct node
{
       int x,y;
};

struct segment
{
       node node1,node2;
}line[101];

int sign( double x )
{
    if( fabs(x)<eps )
    return 0;
    else if( x>0 )
    return 1;
    else return -1;
}

int xmult( node p,node a,node b ){
       return sign( (a.x-p.x)*(b.y-p.y) - (b.x-p.x)*(a.y-p.y) );
}

bool xmultSegment( segment a,segment b )
{
     if( (xmult( a.node1,a.node2,b.node1 )^xmult( a.node1,a.node2,b.node2 ))==-2  )
     {    
          if( (xmult( b.node1,b.node2,a.node1 )^xmult( b.node1,b.node2,a.node2 ))==-2  )
             return true;
     }
     return false;
}

double dist( node p1,node p2 )
{
       return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}

bool examine( node a,node b,node c )
{
     if( fabs(dist(a,c)+dist(c,b)-dist(a,b))<eps )
         return true;
     return false;
}
bool SamePoint( node a,node b,node c )
{
     if( a.x==c.x && a.y==c.y )
         return true;
     if( b.x==c.x && b.y==c.y )
         return true;
     return false;
}
bool exSame( segment a,segment b )
{
     int index=0;
     if( SamePoint( a.node1,a.node2,b.node1 ) )
         index++;
     if( SamePoint( a.node1,a.node2,b.node2 ) )
         index++;
     if( SamePoint( b.node1,b.node2,a.node1 ) )
         index++;
     if( SamePoint( b.node1,b.node2,a.node2 ) )
         index++;
     if( index==0 )
         return false;
     else
         return true;
}

int inLine( segment a,segment b )
{
    int index=0;
     if( xmult( a.node1,a.node2,b.node1 )==0 && examine( a.node1,a.node2,b.node1 ) )
         index++;
     if( xmult( a.node1,a.node2,b.node2 )==0 && examine( a.node1,a.node2,b.node2 ) )
         index++;
     if( xmult( b.node1,b.node2,a.node1 )==0 && examine( b.node1,b.node2,a.node1 ) )
         index++;
     if( xmult( b.node1,b.node2,a.node2 )==0 && examine( b.node1,b.node2,a.node2 ) )
         index++;
    return index;
}

int main()
{
    int T,n;
    int i,j;
    scanf( "%d",&T );
    while( T-- )
    {
           int ans[5];
           memset( ans,0,sizeof(ans) );
           scanf( "%d",&n );
           for( i=1;i<=n;i++ )
                scanf( "%d %d %d %d",&line[i].node1.x,&line[i].node1.y,&line[i].node2.x,&line[i].node2.y );           
           for( i=1;i<=n;i++ )
           for( j=i+1;j<=n;j++ )
           {
                if( xmultSegment( line[i],line[j] ) || inLine( line[i],line[j] ) )
                {
                    if( inLine( line[i],line[j] )>=2 && !exSame( line[i],line[j] ) )
                        ans[2]++;
                    else if( inLine( line[i],line[j] )>=1 )
                        ans[3]++;
                    else
                        ans[4]++;
                }
                else
                    ans[1]++;
           }
           printf( "%d\n%d\n%d\n%d\n\n",ans[1],ans[2],ans[3],ans[4] );
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值