hdu 1086 计算几何

本文介绍了一种通过遍历线段并构造矩形来判断线段是否有交点的方法。通过对比线段端点坐标确定矩形重叠,再利用叉积判断线段是否交叉,最终统计所有线段组合中交点的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

计算几何 经典题,求线段交点个数

首先大体思路,遍历的方式去寻找交点,如果有交点,计数+1

for(int i=0;i<n-1;i++)
    for(int j=i+1;j<n;j++)

接下来就是判断线段是否有交点了
首先以线段作为对角线,构造矩形,先判断两个矩形是否有重叠,如果有重叠,则线段可能有交点,否则不可能有交点。

判断矩形有重叠部分

对于线段1 P1 (x1,y1) ,P2(x2,y2) 和线段2 P3(x3,y3), P4(x4,y4).
矩形重叠的条件是 x方向上
(max(x1,x2)>=min(x3,x4)&&min(x1,x2)<=max(x3,x4))

在y方向上同理。 只需把上式x替换成y即可。

接下来就是判断两条线段是否相交,
如果线段1和线段2有交叉,
则向量 (P1,P3)和(P1,P4) 肯定在(P1,P2)两侧,
根据叉积 ,他们和(P1,P2)的叉肯定异号,即叉积之积<=0
同时,以(P3,P4)作为基准线,(p1,p3),(p2,p3)与(p3,p4)的叉积之积也是异号,<=0

详细分析参考博客 http://www.cnblogs.com/–ZHIYUAN/p/6074676.html

#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

#define MAX 105

double nodex1[MAX],nodey1[MAX];
double nodex2[MAX],nodey2[MAX];


int main()
{
    int n;
    int ans;
    double x1,x2,y1,y2;
    while(cin>>n){

        if(n==0)break;

        ans=0;
        for(int i=0;i<n;i++){

            scanf("%lf%lf%lf%lf",&nodex1[i],&nodey1[i],&nodex2[i],&nodey2[i]);

        }
        // serach
        for(int i=0;i<n-1;i++){

            for(int j=i+1;j<n;j++){

                //rectangel charge

                if(!(max(nodex1[i],nodex2[i])>=min(nodex1[j],nodex2[j])&&
                     min(nodex1[i],nodex2[i])<=max(nodex1[j],nodex2[j])&&
                     max(nodey1[i],nodey2[i])>=min(nodey1[j],nodey2[j])&&
                     min(nodey1[i],nodey2[i])<=max(nodey1[j],nodey2[j])
                     ))
                   continue;

                x1=nodex2[i]-nodex1[i];
                y1=nodey2[i]-nodey1[i];

                x2=nodex2[j]-nodex1[i];
                y2=nodey2[j]-nodey1[i];

                double tem1=x2*y1-x1*y2;

                x2=nodex1[j]-nodex1[i];
                y2=nodey1[j]-nodey1[i];
                double tem2=x2*y1-x1*y2;

                //

                x1=nodex2[j]-nodex1[j];
                y1=nodey2[j]-nodey1[j];

                x2=nodex2[i]-nodex1[j];
                y2=nodey2[i]-nodey1[j];
                double tem3=x2*y1-x1*y2;

                x2=nodex1[i]-nodex1[j];
                y2=nodey1[i]-nodey1[j];
                double tem4=x2*y1-x1*y2;

                if(tem1*tem2<=0&&tem3*tem4<=0)ans++;
            }
        }

        cout<<ans<<endl;

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值