两线段相交求交点

算法一 #include #include #include struct POINT { int x; int y; }; bool IsLineSegmentCross(POINT pFirst1, POINT pFirst2, POINT pSecond1, POINT pSecond2) { //每个线段的两点都在另一个线段的左右不同侧,则能断定线段相交 //公式对于向量(x1,y1)->(x2,y2),判断点(x3,y3)在向量的左边,右边,还是线上. //p=x1(y3-y2)+x2(y1-y3)+x3(y2-y1).p0 右侧 long Linep1,Linep2; //判断pSecond1和pSecond2是否在pFirst1->pFirst2两侧 Linep1 = pFirst1.x * (pSecond1.y - pFirst2.y) + pFirst2.x * (pFirst1.y - pSecond1.y) + pSecond1.x * (pFirst2.y -pFirst1.y); Linep2 = pFirst1.x * (pSecond2.y - pFirst2.y) + pFirst2.x * (pFirst1.y - pSecond2.y) + pSecond2.x * (pFirst2.y - pFirst1.y); if ( ((Linep1 ^ Linep2) >= 0 ) && !(Linep1==0 && Linep2==0))//符号位异或为0:pSecond1和pSecond2在pFirst1->pFirst2同侧 { return false; } //判断pFirst1和pFirst2是否在pSecond1->pSecond2两侧 Linep1 = pSecond1.x * (pFirst1.y - pSecond2.y) +pSecond2.x * (pSecond1.y - pFirst1.y) + pFirst1.x * (pSecond2.y -pSecond1.y); Linep2 = pSecond1.x * (pFirst2.y - pSecond2.y) + pSecond2.x * (pSecond1.y - pFirst2.y) + pFirst2.x * (pSecond2.y - pSecond1.y); if ( ((Linep1 ^ Linep2) >= 0 ) && !(Linep1==0 && Linep2==0))//符号位异或为0:pFirst1和pFirst2在pSecond1->pSecond2同侧 { return false; } //否则判为相交 return true; } POINT GetCrossPoint(POINT p1, POINT p2, POINT q1, POINT q2) { //必须相交求出的才是线段的交点,但是下面的程序段是通用的assert(IsLineSegmentCross(p1,p2,q1,q2)); POINT crossPoint; long tempLeft,tempRight; //求x坐标 tempLeft = (q2.x - q1.x) * (p1.y - p2.y) - (p2.x - p1.x) * (q1.y - q2.y); tempRight = (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); crossPoint.x =(int)( (double)tempRight / (double)tempLeft ); //求y坐标 tempLeft = (p1.x - p2.x) * (q2.y - q1.y) - (p2.y - p1.y) * (q1.x - q2.x); tempRight = 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); crossPoint.y =(int)( (double)tempRight / (double)tempLeft ); return crossPoint; } int main(void) { POINT pointA,pointB,pointC,pointD; POINT pointCross; bool bCross(false); pointA.x = 400;pointA.y=440; pointB.x = 300;pointB.y = 440; pointC.x = 350;pointC.y = 500; pointD.x = 350;pointD.y = 400; bCross = IsLineSegmentCross(pointA,pointB,pointC,pointD); if (bCross) { pointCross = GetCrossPoint(pointA,pointB,pointC,pointD); printf("交点坐标x=%d,y=%d\n",pointCross.x,pointCross.y); } else { printf("They are not crossed!"); } return 0; } 算法二 定义:平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量: |x1 x2 x3| S(P1,P2,P3) = |y1 y2 y3| = (x1-x3)*(y2-y3) - (y1-y3)(x2-x3) |1 1 1| 已知一条线段的两个端点为A(x1,y1),B(x2,y2),另一条线段的两个端点为C(x3,y3),D(x4,y4),要判断AB与CD是否有交点,若有求出. 首先判断d = (y2-y1)(x4-x3)-(y4-y3)(x2-x1), 若d=0,则直线AB与CD平行或重合, 若d!=0,则直线AB与CD有交点,设交点为E(x0,y0): 则有:CE/ED = S(A,C,B) / S(A,B,D) 所以:CE/CD = S(A,C,B) / (S(A,C,B) + S(A,B,D)) 故 x0 = C.x + (D.x - C.x) * S(A,C,B) / (S(A,C,B) + S(A,B,D)); y0 = C.y + (D.y - C.y) * S(A,C,B) / (S(A,C,B) + S(A,B,D)); 也可以直接求 x0 = [(x2-x1)*(x4-x3)*(y3-y1)+(y2-y1)*(x4-x3)*x1-(y4-y3)*(x2-x1)*x3]/d y0 = [(y2-y1)*(y4-y3)*(x3-x1)+(x2-x1)*(y4-y3)*y1-(x4-x3)*(y2-y1)*y3]/(-d) 求出交点后在判断交点是否在线段上,即判断以下的式子: (x0-x1)*(x0-x2)

时间: 2024-10-11 10:56:56

两线段相交求交点的相关文章

fzu 1015 土地划分(判断线段相交+求出交点+找规律)

链接:http://acm.fzu.edu.cn/problem.php?pid=1015  Problem 1015 土地划分 Accept: 714    Submit: 1675Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description 在Dukeswood这块土地上生活着一个富有的农庄主和他的几个孩子.在他临终时,他想把他的土地分给他的孩子.他有许多农场,每个农场都是一块矩形土地.他在农场地图上划上一些直线将

ACM1558两线段相交判断和并查集

Segment set Problem Description A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set. Input In the first line ther

You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6837 Accepted Submission(s): 3303 Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. A

uva11343 - Isolated Segments(两线段相交)

题意:给你一些线段,求没有和其他线段相交的线段数量 公式:p1*p2=(x1*x2,y1*y2)(内积),p1xp2=(x1*y2,x2*y1)(外积) 判断q是否在线段p1-p2上面,根据(p1-q)x(p2-q)=0来判断q是否在直线p1-p2上. 利用内积(p1-q)*(p2-q)<0判断q是否在p1-p2之间. p1-p2,q1-q2的交点: (x,y)=p1+(p2-p1)*((q2-q1)x(q1-p1)/((q2-q1)x(p2-p1))): 推理:把p1-p2直线写成点p1+t(

poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are

BNUOJ33566 Cycling Roads(并查集+判断两线段相交)

Cycling Roads Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on Ural. Original ID: 1966 64-bit integer IO format: %lld      Java class name: (Any) Prev Submit Status Statistics Discuss Next Font Size:  +   - Type:   None Graph T

链表相交问题:判断两个链表是否相交,若相交求交点

默认为不带环链表,若带环则延伸为判断链表是否带环,若带环,求入口点 看看两个链表相交到底是怎么回事吧,有这样的的几个事实:(假设链表中不存在环) (1)一旦两个链表相交,那么两个链表中的节点一定有相同地址. (2)一旦两个链表相交,那么两个链表从相交节点开始到尾节点一定都是相同的节点. #include<iostream> #include<assert.h> using namespace std; template<class T> struct LinkNode

判断两个单链表是否相交?若相交求交点

思想: 如果它们相交,则最后一个节点一定是共有的. ListNode* IsIntersect(ListNode * list1, ListNode* list2 ) {                  assert(list1 && list2);                  ListNode* l1 = list1 ;                  ListNode* l2 = list2 ;                  int cout1 = 0;         

[poj] 2074 Line of Sight || 直线相交求交点

原题 给出一个房子(线段)的端点坐标,和一条路的两端坐标,给出一些障碍物(线段)的两端坐标.问在路上能看到完整房子的最大连续长度是多长. 将障碍物按左端点坐标排序,然后用房子的右端与障碍物的左端连线,房子的左端和前一障碍物的右端比较,得出在道路上的能看到的长度取Max即可 #include<cstdio> #include<algorithm> using namespace std; double a,b,c,l,lmx,ans; int n,pos; struct point