HDU1086-线段相交点个数

向量基础知识:

已知两向量 a=(p2.x-p1.x,p2.y-p1.y)   b=(p3.y-p1.y,p3.x-p1.x)

向量积 :(p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x) 根据右手定则可判方向!(可应用于判点是否在直线两侧)

数量积:(p2.x-p1.x)*(p3.x-p1.x) + (p2.y-p1.y)*(p3.y-p1.y)  (可判点是否在线段上!)

题解:向量积判断 点 是否在线段的两侧。

           当端点在直线上时,用数量积判断点是否在 线段上!!

# include<stdio.h>
# include<string.h>
struct Node{
    double x,y;
}point1[105],point2[105];
double Cross(Node p1,Node p2,Node p3) 
{
    return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x);  //向量积 判定方向 点是不是在直线的两边 
}
double Point(Node p1,Node p2,Node p3)
{
    return (p2.x-p1.x)*(p3.x-p1.x) + (p2.y-p1.y)*(p3.y-p1.y);//当点在这个直线上时,数量积判断它是不是在线段上。
}
int Segments_intersect(Node p1_start,Node p1_end,Node p2_start,Node p2_end)
{
    double d1,d2,d3,d4;
                d1=Cross(p1_start,p1_end,p2_start);
                d2=Cross(p1_start,p1_end,p2_end);
                d3=Cross(p2_start,p2_end,p1_start);
                d4=Cross(p2_start,p2_end,p1_end);
                if(d1*d2<0 && d3*d4<0) return 1;   //同时满足四个点都在另一线段的 两侧则相交。
                else if(d1==0 && Point(p1_start,p1_end,p2_start)>=0) return 1; //或者一个线段端点在另一个线段上!
                else if(d2==0 && Point(p1_start,p1_end,p2_end)>=0) return 1;
                else if(d3==0 && Point(p2_start,p2_end,p1_start)>=0) return 1;
                else if(d4==0 && Point(p2_start,p2_end,p1_end)>=0) return 1;
                else return 0;
}
int main()
{
    int n,i,j,count,ans;
    while(scanf("%d",&n)!=EOF && n)
    {
        for(i=1;i<=n;i++)
            scanf("%lf%lf%lf%lf",&point1[i].x,&point1[i].y,&point2[i].x,&point2[i].y);
        count=0;
        for(i=1;i<n;i++)
        {
            for(j=i+1;j<=n;j++)
            {
                ans=Segments_intersect(point1[i],point2[i],point1[j],point2[j]);
                if(ans==1) count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值