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))//如果p1、p2在线段p3p4的两侧并且p3、p4在线段p1p2的两侧
     74         return true;
     75 
     76 
     77     if((d1 == 0) && onsegment(p3, p4, p1))//p1在线段p3p4上
     78         return true;
     79     if((d2 == 0) && onsegment(p3, p4, p2))//p2在线段p3p4上
     80         return true;
     81     if((d3 == 0) && onsegment(p1, p2, p3))//p3在线段p1p2上
     82         return true;
     83     if((d4 == 0) && onsegment(p1, p2, p4))//p4在线段p1p2上
     84         return true;
     85 
     86     return  false;
     87 }
     88 
     89 //求直线p1p2与直线p3p4之间的交点,纯粹性的数学公式求解了
     90 point getIntersection(point p1, point p2, point p3, point p4)
     91 {
     92     /*根据两点式化为标准式,进而求线性方程组*/  
     93     point crossPoint;  
     94     double tempLeft,tempRight;  
     95     //求x坐标  
     96     tempLeft = (p4.x - p3.x) * (p1.y - p2.y) - (p2.x - p1.x) * (p3.y - p4.y);  
     97     tempRight = (p1.y - p3.y) * (p2.x - p1.x) * (p4.x - p3.x) + p3.x * (p4.y - p3.y) * (p2.x - p1.x) - p1.x * (p2.y - p1.y) * (p4.x - p3.x);  
     98     crossPoint.x =tempRight / tempLeft ;  
     99 
    100     //求y坐标    
    101     tempLeft = (p1.x - p2.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p3.x - p4.x);  
    102     tempRight = p2.y * (p1.x - p2.x) * (p4.y - p3.y) + (p4.x- p2.x) * (p4.y - p3.y) * (p1.y - p2.y) - p4.y * (p3.x - p4.x) * (p2.y - p1.y);  
    103     crossPoint.y = tempRight / tempLeft ;  
    104 
    105     return crossPoint;  
    106 }
    107 
    108 int main()
    109 {
    110     int n;
    111     segment seg[2];//两个线段
    112     point intersection;
    113 
    114     scanf_s("%d", &n);
    115     while(n --)//测试次数
    116     {
    117         for(int i = 1 ; i <= 2 ; i ++)
    118         {
    119             scanf_s("%lf%lf%lf%lf", &seg[i].begin.x, &seg[i].begin.y, &seg[i].end.x, &seg[i].end.y);
    120         }
    121 
    122         if(judge(seg[1].begin, seg[1].end, seg[2].begin, seg[2].end))
    123             intersection = getIntersection(seg[1].begin, seg[1].end, seg[2].begin, seg[2].end);
    124 
    125         printf_s("(%lf, %lf)
    ", intersection.x, intersection.y);
    126     }
    127 
    128     return 0;
    129 }
  • 相关阅读:
    什么叫TLD、gTLD、nTLD、ccTLD、iTLD 以及几者之间的关系
    socket
    windows下codeblocks报错undefined reference to `WSAStartup@8'|
    Codeforces 467C George and Job | DP
    51Nod 1049最大子段和 | 模板
    51Nod 最大子矩阵和 | DP
    AtomicInteger
    sun.misc.unsafe
    CAS
    java中的四种引用
  • 原文地址:https://www.cnblogs.com/yiyi-xuechen/p/3452327.html
Copyright © 2011-2022 走看看