天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 411|回复: 2

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

[复制链接]
  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    115

    主题

    11

    回帖

    1393

    积分

    管理员

    积分
    1393
    QQ
    发表于 2024-6-21 17:02:47 | 显示全部楼层 |阅读模式
    1. //跨立判断
    2. bool isLineSegmentCross(const Point &P1,const Point &P2,const Point &Q1,const Point &Q2)
    3. {
    4.     if(
    5.         ((Q1.x-P1.x)*(Q1.y-Q2.y)-(Q1.y-P1.y)*( Q1.x-Q2.x)) * ((Q1.x-P2.x)*(Q1.y-Q2.y)-(Q1.y-P2.y)*(Q1.x-Q2.x)) < 0 &&
    6.         ((P1.x-Q1.x)*(P1.y-P2.y)-(P1.y-Q1.y)*(P1.x-P2.x)) * ((P1.x-Q2.x)*(P1.y-P2.y)-(P1.y-Q2.y)*( P1.x-P2.x)) < 0
    7.     )
    8.         return true;
    9.     else
    10.        return false;
    11. }
    复制代码

    1. #include<stdio.h>
    2. #define N 10002
    3. /**
    4. 算法适用于整形点,不适用于浮点型
    5. **/
    6. typedef struct Point
    7. {
    8.     int x;
    9.     int y;
    10. }Point;
    11. double min(int x, int y)
    12. {
    13.     return x<y?x:y;
    14. }
    15. double max(int x, int y)
    16. {
    17.     return x>y?x:y;
    18. }
    19. //排斥实验
    20. bool IsRectCross(const Point &p1,const Point &p2,const Point &q1,const Point &q2)
    21. {
    22.     bool ret = min(p1.x,p2.x) <= max(q1.x,q2.x)    &&
    23.                 min(q1.x,q2.x) <= max(p1.x,p2.x) &&
    24.                 min(p1.y,p2.y) <= max(q1.y,q2.y) &&
    25.                 min(q1.y,q2.y) <= max(p1.y,p2.y);
    26.     return ret;
    27. }
    28. /**这段代码不能得到正确答案,故注释
    29. //跨立判断
    30. bool IsLineSegmentCross(const Point &pFirst1,const Point &pFirst2,const Point &pSecond1,const Point &pSecond2)
    31. {
    32.     long line1,line2;
    33.     line1 = pFirst1.x * (pSecond1.y - pFirst2.y) +
    34.         pFirst2.x * (pFirst1.y - pSecond1.y) +
    35.         pSecond1.x * (pFirst2.y - pFirst1.y);
    36.     line2 = pFirst1.x * (pSecond2.y - pFirst2.y) +
    37.         pFirst2.x * (pFirst1.y - pSecond2.y) +
    38.         pSecond2.x * (pFirst2.y - pFirst1.y);
    39.     if (((line1 ^ line2) >= 0) && !(line1 == 0 && line2 == 0))
    40.         return false;
    41.     line1 = pSecond1.x * (pFirst1.y - pSecond2.y) +
    42.         pSecond2.x * (pSecond1.y - pFirst1.y) +
    43.         pFirst1.x * (pSecond2.y - pSecond1.y);
    44.     line2 = pSecond1.x * (pFirst2.y - pSecond2.y) +
    45.         pSecond2.x * (pSecond1.y - pFirst2.y) +
    46.         pFirst2.x * (pSecond2.y - pSecond1.y);
    47.     if (((line1 ^ line2) >= 0) && !(line1 == 0 && line2 == 0))
    48.         return false;
    49.     return true;
    50. }
    51. **/
    52. //跨立判断
    53. bool IsLineSegmentCross(const Point &P1,const Point &P2,const Point &Q1,const Point &Q2)
    54. {
    55.     if(
    56.         ((Q1.x-P1.x)*(Q1.y-Q2.y)-(Q1.y-P1.y)*( Q1.x-Q2.x)) * ((Q1.x-P2.x)*(Q1.y-Q2.y)-(Q1.y-P2.y)*(Q1.x-Q2.x)) < 0 ||
    57.         ((P1.x-Q1.x)*(P1.y-P2.y)-(P1.y-Q1.y)*(P1.x-P2.x)) * ((P1.x-Q2.x)*(P1.y-P2.y)-(P1.y-Q2.y)*( P1.x-P2.x)) < 0
    58.     )
    59.         return true;
    60.     else
    61.        return false;
    62. }
    63. /**
    64. 求线段P1P2与Q1Q2的交点。
    65. 先进行快速排斥实验和跨立实验确定有交点再进行计算。
    66. 交点(x,y)使用引用返回。
    67. 没有验证过
    68. **/
    69. bool GetCrossPoint(const Point &p1,const Point &p2,const Point &q1,const Point &q2,long &x,long &y)
    70. {
    71.     if(IsRectCross(p1,p2,q1,q2))
    72.     {
    73.         if (IsLineSegmentCross(p1,p2,q1,q2))
    74.         {
    75.             //求交点
    76.             long tmpLeft,tmpRight;
    77.             tmpLeft = (q2.x - q1.x) * (p1.y - p2.y) - (p2.x - p1.x) * (q1.y - q2.y);
    78.             tmpRight = (p1.y - q1.y) * (p2.x - p1.x) * (q2.x - q1.x) + q1.x * (q2.y - q1.y) * (p2.x - p1.x) - p1.x * (p2.y - p1.y) * (q2.x - q1.x);
    79.             x = (int)((double)tmpRight/(double)tmpLeft);
    80.             tmpLeft = (p1.x - p2.x) * (q2.y - q1.y) - (p2.y - p1.y) * (q1.x - q2.x);
    81.             tmpRight = p2.y * (p1.x - p2.x) * (q2.y - q1.y) + (q2.x- p2.x) * (q2.y - q1.y) * (p1.y - p2.y) - q2.y * (q1.x - q2.x) * (p2.y - p1.y);
    82.             y = (int)((double)tmpRight/(double)tmpLeft);
    83.             return true;
    84.         }
    85.     }
    86.     return false;
    87. }
    复制代码


    1. #include <stdio.h>
    2. #include <math.h>
    3. const int N = 100010;
    4. int mark[N];
    5. struct Point
    6. {
    7.     double x,y;
    8. };
    9. struct stline
    10. {
    11.     Point a,b;
    12. } line1,line2, p[N];
    13. int dblcmp(double a,double b)
    14. {
    15.     if (fabs(a-b)<=1E-6) return 0;
    16.     if (a>b) return 1;
    17.     else return -1;
    18. }
    19. //***************点积判点是否在线段上***************
    20. double dot(double x1,double y1,double x2,double y2) //点积
    21. {
    22.     return x1*x2+y1*y2;
    23. }
    24. int point采用on采用line(Point a,Point b,Point c) //求a点是不是在线段bc上,>0不在,=0与端点重合,<0在。
    25. {
    26.     return dblcmp(dot(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y),0);
    27. }
    28. //**************************************************
    29. double cross(double x1,double y1,double x2,double y2)
    30. {
    31.     return x1*y2-x2*y1;
    32. }
    33. double ab采用cross采用ac(Point a,Point b,Point c) //ab与ac的叉积
    34. {
    35.     return cross(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
    36. }
    37. int ab采用cross采用cd (Point a,Point b,Point c,Point d) //求ab是否与cd相交,交点为p。1规范相交,0交点是一线段的端点,-1不相交。
    38. {
    39.     double s1,s2,s3,s4;
    40.     int d1,d2,d3,d4;
    41.     Point p;
    42.     d1=dblcmp(s1=ab采用cross采用ac(a,b,c),0);
    43.     d2=dblcmp(s2=ab采用cross采用ac(a,b,d),0);
    44.     d3=dblcmp(s3=ab采用cross采用ac(c,d,a),0);
    45.     d4=dblcmp(s4=ab采用cross采用ac(c,d,b),0);
    46. //如果规范相交则求交点
    47.     if ((d1^d2)==-2 && (d3^d4)==-2)
    48.     {
    49.         p.x=(c.x*s2-d.x*s1)/(s2-s1);
    50.         p.y=(c.y*s2-d.y*s1)/(s2-s1);
    51.         return 1;
    52.     }
    53. //如果不规范相交
    54.     if (d1==0 && point采用on采用line(c,a,b)<=0)
    55.     {
    56.         p=c;
    57.         return 0;
    58.     }
    59.     if (d2==0 && point采用on采用line(d,a,b)<=0)
    60.     {
    61.         p=d;
    62.         return 0;
    63.     }
    64.     if (d3==0 && point采用on采用line(a,c,d)<=0)
    65.     {
    66.         p=a;
    67.         return 0;
    68.     }
    69.     if (d4==0 && point采用on采用line(b,c,d)<=0)
    70.     {
    71.         p=b;
    72.         return 0;
    73.     }
    74. //如果不相交
    75.     return -1;
    76. }
    复制代码

     

     

     

     

    计算几何-求线段交点算法和代码(C++语言)
  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    115

    主题

    11

    回帖

    1393

    积分

    管理员

    积分
    1393
    QQ
     楼主| 发表于 2024-6-21 17:03:24 | 显示全部楼层
    1. Point getCrossPoint(Segment s1, Segment s2) {
    2.     Vector base = s2.p2 - s2.p1;
    3.     double d1 = abs(cross(base, s1.p1 - s2.p1));
    4.     double d2 = abs(cross(base, s1.p2 - s2.p1));
    5.     double t = d1 / (d1 + d2);
    6.     return s1.p1 + (s1.p2 - s1.p1) * t;
    7. }
    复制代码

     

     

     

     

    计算几何-求线段交点算法和代码(C++语言)
  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    115

    主题

    11

    回帖

    1393

    积分

    管理员

    积分
    1393
    QQ
     楼主| 发表于 2024-6-21 17:03:33 | 显示全部楼层
    1. #include<stdio.h>
    2. #include<iostream>
    3. #include<cmath>
    4. using namespace std;
    5. #define EPS (1e-10)
    6. #define equals(a, b) (fabs((a) - (b)) < EPS)
    7. class Point {//Point类,点
    8.     public:
    9.         double x, y;
    10.         
    11.         Point(double x = 0, double y = 0): x(x), y(y) {}
    12.         Point operator + (Point p) { return Point(x + p.x, y + p.y); }
    13.         Point operator - (Point p) { return Point(x - p.x, y - p.y); }
    14.         Point operator * (double a) { return Point(a * x, a * y); }
    15.         Point operator / (double a) { return Point(x / a, y / a); }
    16.         double abs() { return sqrt(norm()); }
    17.         double norm() { return x * x + y * y; }
    18.         
    19.         bool operator < (const Point &p) const {
    20.             return x != p.x ? x < p.x : y < p.y;
    21.         }
    22.         bool operator == (const Point &p) const {
    23.             return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
    24.         }
    25. };
    26. typedef Point Vector;//Vector类,向量
    27. struct Segment{//Segment 线段
    28.     Point p1, p2;
    29. };
    30. double dot(Vector a, Vector b) {//内积
    31.     return a.x * b.x + a.y * b.y;
    32. }
    33. double cross(Vector a, Vector b) {//外积
    34.     return a.x*b.y - a.y*b.x;
    35. }
    36. Point getCrossPoint(Segment s1, Segment s2) {
    37.     Vector base = s2.p2 - s2.p1;
    38.     double d1 = abs(cross(base, s1.p1 - s2.p1));
    39.     double d2 = abs(cross(base, s1.p2 - s2.p1));
    40.     double t = d1 / (d1 + d2);
    41.     return s1.p1 + (s1.p2 - s1.p1) * t;
    42. }
    43. int main(){
    44.     int q;
    45.     cin>>q;
    46.    
    47.     Segment s1, s2;
    48.     Point p;
    49.    
    50.     while(q--){
    51.         cin>>s1.p1.x>>s1.p1.y>>s1.p2.x>>s1.p2.y>>s2.p1.x>>s2.p1.y>>s2.p2.x>>s2.p2.y;
    52.         p = getCrossPoint(s1, s2);
    53.         printf("%.10f %.10f\n", p.x, p.y);
    54.     }
    55. }
    复制代码

     

     

     

     

    计算几何-求线段交点算法和代码(C++语言)
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-11-5 12:32 , Processed in 0.155660 second(s), 27 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表