# 叉积--求两条直线（线段）的交点

24 篇文章 0 订阅
170 篇文章 0 订阅
59 篇文章 1 订阅

<pre name="code" class="cpp"><span style="font-family:Microsoft YaHei;">#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{0,-1},{-1,0},{0,1},{1,0}};
#define N 105
const double eps = 1e-6;
const double Pi = acos(-1.0);
struct Point
{
Point() {}
Point(double x,double y):x(x),y(y) {}
double x,y;
};

struct Seg
{
Point p1,p2;
};

int sgn(double x)
{
return x<-eps ? -1 : (x>eps);
}

double Cross(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
return (p2.x-p1.x)*(p4.y-p3.y) - (p2.y-p1.y)*(p4.x-p3.x);
}

double Area(const Point& p1,const Point& p2,const Point& p3)
{
return Cross(p1,p2,p1,p3);
}

double fArea(const Point& p1,const Point& p2,const Point& p3)
{
return fabs(Area(p1,p2,p3));
}

bool Meet(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
return max(min(p1.x,p2.x),min(p3.x,p4.x)) <= min(max(p1.x,p2.x),max(p3.x,p4.x))
&& max(min(p1.y,p2.y),min(p3.y,p4.y)) <= min(max(p1.y,p2.y),max(p3.y,p4.y))
&& sgn(Cross(p3,p2,p3,p4) * Cross(p3,p4,p3,p1)) >= 0
&& sgn(Cross(p1,p4,p1,p2) * Cross(p1,p2,p1,p3)) >= 0;
}

Point Inter(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
double k = fArea(p1,p2,p3) / fArea(p1,p2,p4);
return Point((p3.x + k*p4.x)/(1+k),(p3.y + k*p4.y)/(1+k));
}
int main()
{
int T;
cin >>T;
while(T--)
{
Point a,b,c,d;
Inter(a,c, b,d).print();
}
return 0;
}
</span>

Point Inter(const Point& p1,const Point& p2,const Point& p3,const Point& p4)
{
double s1 = fArea(p1,p2,p3) , s2 = fArea(p1,p2,p4);
return Point((p4.x*s1+p3.x*s2)/(s1+s2),(p4.y*s1+p3.y*s2)/(s1+s2));
}

/*
1）先求一条线段的直线方程，判断另一条线段的两个端点是否在直线的异侧
2）再求另一条线段的直线方程，同上判断；
3）再考虑线段共线的情况，求出重合点；

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{0,-1},{-1,0},{0,1},{1,0}};
const double eps = 1e-6;
const double Pi = acos(-1.0);
double a,b,c;
double a1,b1,c1,a2,b2,c2;
typedef struct Point
{
double x;
double y;
} Point;
Point r;
double min(double a,double b)
{
if(a<b) return a;
return b;
}
double max(double a,double b)
{
if(a>b) return a;
return b;
}
void GetLine(Point p,Point q)
{
a=q.y-p.y;
b=p.x-q.x;
c=q.x*p.y-p.x*q.y;
}
int flag(Point p1,Point p2,Point q1,Point q2)
{
double m,n;
GetLine(p2,q2);
a2=a,b2=b,c2=-c;
m=a*p1.x+b*p1.y+c;
n=a*q1.x+b*q1.y+c;
if(m*n>0) return 0;
if(fabs(m)<1e-8&&fabs(n)<1e-8)
{
if(fabs(b)<1e-8)
if(((p1.y<min(p2.y,q2.y)&&q1.y<min(p2.y,q2.y))||(p1.y>max(p2.y,q2.y)&&q1.y>max(p2.y,q2.y)))) return 0;
else
{
if(p1.y==p2.y || p1.y==q2.y)r.x=p1.x,r.y=p1.y;
else r.x=q1.x,r.y=q1.y;
return 1;
}
if(((p1.x<min(p2.x,q2.x)&&q1.x<min(p2.x,q2.x))||(p1.x>max(p2.x,q2.x)&&q1.x>max(p2.x,q2.x)))) return 0;
else
{
if(p1.x==p2.x || p1.x==q2.x) r.x=p1.x,r.y=p1.y;
else r.x=q1.x,r.y=q1.y;
return 1;
}
}
GetLine(p1,q1);
a1=a,b1=b,c1=-c;
m=a*p2.x+b*p2.y+c;
n=a*q2.x+b*q2.y+c;
if(m*n>0) return 0;
r.x=(c1*b2-c2*b1)/(a1*b2-a2*b1);
r.y=(a1*c2-a2*c1)/(a1*b2-a2*b1);
return 1;
}
int main()
{
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
int n;
Point a,b,c,d;
scanf("%d",&n);
while(n--)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&c.x,&c.y,&b.x,&b.y,&d.x,&d.y);
{
if(flag(a,b,c,d)) printf("yes %.1lf %.1lf\n",r.x,r.y);
else printf("no\n");
}
}
return 0;
}        
Ps：

1、求交点之前，要保证两条直线不共线。

2、如果是求两条线段的交点，先判断两条线段是否相交。

若相交，则问题可转化成两条直线求交点。

• 2
点赞
• 8
收藏
• 0
评论
09-11
05-20 1万+
04-27 2710
09-07 54
04-29 272
12-29 292
08-20 286
12-15 1万+
05-06 894
09-06 1857
04-01 3528

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助