关闭

hdu 1086 计算几何 线段求交

262人阅读 评论(0) 收藏 举报
分类:

原文链接

  我们分两步确定两条线段是否相交:

  (1)快速排斥试验

    设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。

  (2)跨立试验

    如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。具体情况如下图所示:

    

  在相同的原理下,对此算法的具体的实现细节可能会与此有所不同,除了这种过程外,大家也可以参考《算法导论》上的实现。

关于计算几何算法概述网站 http://dev.gameres.com/Program/Abstract/Geometry.htm 一个挺好的网站


#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
#define EPS 1e-8


struct Point
{
    double x;
    double y;
};

struct Line
{
    Point f;  //first
    Point e;  //end
}l[105];

double Area2(Point p2, Point p3, Point p1)
{
    double temp = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
    return temp;
}

bool on_segment( Point p1,Point p2 ,Point p )
{
    double max1=p1.x > p2.x ? p1.x : p2.x ;
    double min1 =p1.x < p2.x ? p1.x : p2.x ;

    if( p.x >=min1 && p.x <=max1 )
        return true;
    else
        return false;
}

bool segInsert(Point p1, Point p2, Point p3, Point p4)
{
    double d1, d2, d3, d4;
    d1 = Area2(p1, p2, p3);
    d2 = Area2(p1, p2, p4);
    d3 = Area2(p3, p4, p1);
    d4 = Area2(p3, p4, p2);
    if ((d1 * d2 < -EPS) && (d3 * d4 < -EPS))
    {
       return true;
    }
    else if( fabs(d1) <= EPS && on_segment( p1,p2,p3 ) )
        return true;
    else if( fabs(d2) <= EPS&& on_segment( p1,p2,p4 ) )
        return true;
    else if( fabs(d3) <= EPS && on_segment( p3,p4,p1 ) )
        return true;
    else if( fabs(d4) <= EPS && on_segment( p3,p4,p2 ) )
        return true;
    return false;
}


int main()
{
  // freopen("E:\input.txt", "r", stdin);
    int n;
    int num;
    int i, j;
    while ((scanf("%d", &n)) && n != 0)
    {
        num = 0;
        for (i = 0; i < n; i++)
        {
            //scanf("%lf%lf%lf%lf",&l[i].f.x ,&l[i].f.y ,&l[i].e.x ,&l[i].e.y );
            cin >> l[i].f.x >> l[i].f.y >> l[i].e.x >> l[i].e.y;
        }
        for (i = 0; i < n; i++)
        {
            for (j = i + 1; j < n; j++)
            {
                if (segInsert(l[i].f, l[i].e, l[j].f, l[j].e))
                {
                    num++;
                }
            }
        }
        cout << num << endl;
    }

    return 0;
}

参考博客



0
0
查看评论

计算几何之线段性质(二):求线段交点

求线段的交点即求线段交点的坐标。若已确定两线段相交,可以通过解析几何中的直线方程来求解交点,这里介绍另外的一种方法。叉积multi(p1,p2,p0)可以看做是由点P1,P2,P0和P1+P2,这四个点围成的平行四边形的面积(如下图所示),及三角形P0P1P2的面积S=1/2 multi(P1,P2...
  • AC_Gibson
  • AC_Gibson
  • 2015-02-02 09:36
  • 1168

计算几何——线段求交

计算几何,线段求交 数据结构:AVLTree 方法:扫描线法
  • yfdyyy
  • yfdyyy
  • 2013-11-21 11:27
  • 832

ZJU2102 Tables - 计算几何 线段与圆相交

题目大意:输入n个圆形桌子的圆心和半径(从俯视的角度看),给出一根木棍两端点的坐标,问木棍会不会掉到地上。(n分析: 设木棍端点为a,b,因为木棍质量分布均匀,所以重心c一定在(a+b)/2处。1、若重心c点被包放在任何一个桌子上,则木棍不会掉;2、否则,若重心c两侧分别有一部分放在桌子上...
  • tiaotiaoyly
  • tiaotiaoyly
  • 2008-03-28 18:14
  • 2752

计算几何之相交直线交点的求法

假设交点为p0(x0,y0)。则有: (p1-p0)X(p2-p0)=0 (p3-p0)X(p2-p0)=0 展开后即是 (y1-y2)x0+(x2-x1)y0+x1y2-x2y1=0 (y3-y4)x0+(x4-x3)y0+x3y4-x4y3=0 将x0,y0作为变量求解二元一次方程组...
  • YCQ_Lancet
  • YCQ_Lancet
  • 2017-08-15 10:45
  • 316

计算几何:线段判交模板--ACM

线段判交--ACM 给定两个点: typedef  struct {   double  x, y; } Point; Point A1,A2,B1,B2; 首先引入两个实验: a.快速排斥实验 设以线段A1A2和...
  • Enjoying_Science
  • Enjoying_Science
  • 2015-07-04 17:37
  • 736

[从头学数学] 第265节 [计算几何] 多线段求交点(扫描线法)

剧情提要: 阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇 它里面讲了些什么,就来看看啦。 正剧开始: 星历2016年09月19日 11:58:08, 银河系厄尔斯星球中华帝国江南行省。 [工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。...
  • mwsister
  • mwsister
  • 2016-09-19 12:32
  • 579

计算几何-求线段交点算法和代码(C++语言)

问题描述:已知两条线段P1P2和Q1Q2,判断P1P2和Q1Q2是否相交,若相交,求出交点。 两条线段的位置关系可以分为三类:有重合部分、无重合部分但有交点、无交点。 算法核心 算法的步骤如下: 1.快速排斥实验。 设以线段P1P2为对角线的矩形为R,设以线段Q1Q2为对角线的矩形为...
  • tengchongwei
  • tengchongwei
  • 2017-06-08 16:17
  • 1105

计算几何入门一:点,线段,直线,向量

知识都是高中或大一高数知识,自行回顾,模板已给出!!!涉及点,直线,线段,向量,交点坐标的求法以下模板都可以直接复制粘贴使用 模板如下:#include <iostream> #include<cmath> #include<algorithm> using n...
  • qq_36172505
  • qq_36172505
  • 2017-08-07 16:21
  • 151

HDU 1086 (平面几何 线段求交)

题目链接:点击这里题意:求n条线段的所有交点个数. 题目保证线段不会有重合部分.直接求交点, 把所有的交点扔进一个集合统计一下就行了.#include <cstdio> #include <cmath> #include <algorithm> #include ...
  • morejarphone
  • morejarphone
  • 2016-06-22 00:18
  • 111

计算几何----判断线段相交(一)

判断线段相交: 两个线段的交点个数可能有0个 1个或者无数个 判断两个线段相交,可以按照如下步骤: 判断A点B点是否在线段CD的两侧,即计算叉积时异号 判断C点和D点是否在线段AB的两侧,即计算叉积时异号 然后在处理特殊情况,即ABCD四个点有至少三个点共线的情况,即出现叉积为零的情况,...
  • liangzhaoyang1
  • liangzhaoyang1
  • 2016-04-07 22:54
  • 1151
    个人资料
    • 访问:93353次
    • 积分:1941
    • 等级:
    • 排名:千里之外
    • 原创:117篇
    • 转载:12篇
    • 译文:0篇
    • 评论:19条
    博客专栏
    最新评论