zoukankan      html  css  js  c++  java
  • Algorithm Design——判断线段是否相交

      1 /**
      2 给出线段AB以及线段CD,只要判断A、B两点在直线CD的两端,并且C、D两点在直线AB的两端即可。
      3 用叉乘进行判断。
      4 
      5 问题描述
      6 下面给出的是一个判断线段相交的次数
      7 
      8 输入:
      9 n:线段的个数
     10 seg.begin.x,seg.begin.y,seg.end.x,seg.end.y:分别表示线段p1p2的点坐标
     11 
     12 输出:
     13 n个线段中两两相交的次数
     14 
     15 样例输入
     16 2
     17 1 0 0 0
     18 0 1 0 0
     19 样例输出:
     20 1
     21 */
     22 
     23 #include<cstdio>
     24 using namespace std;
     25 
     26 struct point
     27 {
     28     double x, y;
     29 };
     30 
     31 struct segment
     32 {
     33     point begin, end;
     34 };
     35 
     36 double min(double x, double y)
     37 {
     38     return (x < y) ? x : y;
     39 }
     40 
     41 double max(double x, double y)
     42 {
     43     return (x > y) ? x : y;
     44 }
     45 
     46 //判断pk是否在线段<pi, pj>上
     47 bool onsegment(point pi, point pj, point pk)
     48 {
     49     if(min(pi.x, pj.x) <= pk.x && pk.x <= max(pi.x, pj.x))
     50     {
     51         if(min(pi.y, pj.y) <= pk.y && pk.y <= max(pi.y, pj.y))
     52         {
     53             return true;
     54         }
     55     }
     56     return false;
     57 }
     58 
     59 //计算向量<pk, pi>与向量<pj, pi>的叉乘
     60 double direction(point pi, point pj, point pk)
     61 {
     62     return (pi.x - pk.x) * (pi.y - pk.y) - (pi.x - pj.x) * (pi.y - pk.y);
     63 }
     64 
     65 //判断p1p2以及p3p4是否相交
     66 bool judge(point p1, point p2, point p3, point p4)
     67 {
     68     double d1 = direction(p3, p4, p1);
     69     double d2 = direction(p3, p4, p2);
     70     double d3 = direction(p1, p2, p3);
     71     double d4 = direction(p1, p2, p4);
     72 
     73     if((d1 * d2 < 0) && (d3 * d4 < 0))
     74         return true;
     75 
     76     //判断点是否在另一个线段上(包罗万象)
     77     if((d1 == 0) && onsegment(p3, p4, p1))
     78         return true;
     79     if((d2 == 0) && onsegment(p3, p4, p2))
     80         return true;
     81     if((d3 == 0) && onsegment(p1, p2, p3))
     82         return true;
     83     if((d4 == 0) && onsegment(p1, p2, p4))
     84         return true;
     85 
     86     return  false;
     87 }
     88 
     89 int main()
     90 {
     91     int n, count;
     92     segment seg[101];
     93     while(scanf_s("%d", &n, 1) != EOF && n != 0)
     94     {
     95         count = 0;
     96         for(int i = 1 ; i <= n ; i ++)
     97         {
     98             scanf_s("%d%d%d%d", &seg[i].begin.x, &seg[i].begin.y, &seg[i].end.x, &seg[i].end.y);
     99         }
    100 
    101         for(int i = 1 ; i < n ; i ++)
    102         {
    103             for(int j = i + 1 ; j <= n ; j ++)
    104             {
    105                 if(judge(seg[i].begin, seg[i].end, seg[j].begin, seg[j].end))
    106                     count ++;
    107             }
    108         }
    109 
    110         printf_s("%d
    ", count);
    111     }
    112 
    113     return 0;
    114 }
  • 相关阅读:
    函数的命名空间和作用域
    python 各个地方导航(方便查询,持续更新!)
    零基础学虚幻4(UE4):蓝图+VR 丁树凯教程
    UE4打包后的游戏,无法打卡其他关卡的解决办法
    【精辟】进制转换
    Git仓库的初始化
    【编程】杂碎知识点
    MFC制作带界面的DLL库
    StartImage.DLL使用说明
    MFC对话框程序:实现程序启动画面
  • 原文地址:https://www.cnblogs.com/yiyi-xuechen/p/3452316.html
Copyright © 2011-2022 走看看