面试题 16.03. 交点
给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值。
要求浮点型误差不超过10^-6。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。
示例 1:
输入:
line1 = {0, 0}, {1, 0}
line2 = {1, 1}, {0, -1}
输出: {0.5, 0}
示例 2:
输入:
line1 = {0, 0}, {3, 3}
line2 = {1, 1}, {2, 2}
输出: {1, 1}
示例 3:
输入:
line1 = {0, 0}, {1, 1}
line2 = {1, 0}, {2, 1}
输出: {},两条线段没有交点
提示:
坐标绝对值不会超过 2^7
输入的坐标均是有效的二维坐标
题目不难,先把线段看成直线,那么直线无非两种情况:平行或者相交。
如果两条线段所在的直线是平行的,那么直接返回空,如果不平行,需要判断是否是在同一条直接,如果在同一条直线,并且相交了,就是有多个交点。如果所在的直线是相交的,直接算出相交的点,判断这个点是否同时在两条线段上,就得到了答案。
感觉我的代码写的比较冗余,思路能理解就好。
AC代码
class Solution {
public:
typedef long long ll;
vector <double>fun(double x1,double y1,double x2,double y2)//计算直线的k和b
{
double k=(y1-y2)/(x1-x2);
double b=y1-k*x1;
vector<double>q;
q.push_back(k);
q.push_back(b);
return q;
}
vector<double> intersection(vector<int>& start1, vector<int>& end1, vector<int>& start2, vector<int>& end2) {
ll ans1=(start1[0]-end1[0])*(start2[1]-end2[1]);
ll ans2=(start2[0]-end2[0])*(start1[1]-end1[1]);
if(ans1==ans2)//两条直线斜率一样
{
ll ans3=(start1[0]-end1[0])*(start1[1]-start2[1]);
ll ans4=(start1[0]-start2[0])*(start1[1]-end1[1]);
if(ans3==ans4)//说明两条线段属于同一条直线
{
int mix=min(start2[0],end2[0]);
int mxx=max(start2[0],end2[0]);
int miy=min(start2[1],end2[1]);
int mxy=max(start2[1],end2[1]);
double x=1e9,y=1e9;
if(start1[0]>=mix&&start1[0]<=mxx&&start1[1]>=miy&&start1[1]<=mxy)
{
if(start1[0]<x)
{
x=start1[0];
y=start1[1];
}
}
if(end1[0]>=mix&&end1[0]<=mxx&&end1[1]>=miy&&end1[1]<=mxy)
{
if(end1[0]<x)
{
x=end1[0];
y=end1[1];
}
}
mix=min(start1[0],end1[0]);
mxx=max(start1[0],end1[0]);
miy=min(start1[1],end1[1]);
mxy=max(start1[1],end1[1]);
if(start2[0]>=mix&&start2[0]<=mxx&&start2[1]>=miy&&start2[1]<=mxy)
{
if(start2[0]<x)
{
x=start2[0];
y=start2[1];
}
}
if(end2[0]>=mix&&end2[0]<=mxx&&end2[1]>=miy&&end2[1]<=mxy)
{
if(end2[0]<x)
{
x=start2[0];
y=start2[1];
}
}
vector<double>q;
if(x>1e8)return q;//说明这两条线段没有交点
q.push_back(x);
q.push_back(y);
return q;
}
else//说明两条线段平行
{
vector<double>q;
return q;
}
}
else//直线不平行必然相交
{
double x1,x2,y1,y2,x3,x4,y3,y4;
if(start2[0]==end2[0])
{
swap(start1,start2);
swap(end1,end2);
}
x1=min(start1[0],end1[0]);
x2=max(start1[0],end1[0]);
y1=min(start1[1],end1[1]);
y2=max(start1[1],end1[1]);
x3=min(start2[0],end2[0]);
x4=max(start2[0],end2[0]);
y3=min(start2[1],end2[1]);
y4=max(start2[1],end2[1]);
if(start1[0]==end1[0])
{
vector<double>q;
double x=start1[0];
double y=double((end2[0]-x)*start2[1]+(x-start2[0])*end2[1])/double(end2[0]-start2[0]);
if(x>=x1&&x<=x2&&x>=x3&&x<=x4&&y>=y1&&y<=y2&&y>=y3&&y<=y4)
{
q.push_back(x);
q.push_back(y);
return q;
}
else
{
return q;
}
}
else
{
vector<double>f1=fun(start1[0],start1[1],end1[0],end1[1]);
vector<double>f2=fun(start2[0],start2[1],end2[0],end2[1]);
double x=(f2[1]-f1[1])/(f1[0]-f2[0]);
double y=f1[0]*x+f1[1];
vector<double>q;
if(x>=x1&&x<=x2&&x>=x3&&x<=x4&&y>=y1&&y<=y2&&y>=y3&&y<=y4)
{
q.push_back(x);
q.push_back(y);
return q;
}
else
{
return q;
}
}
}
vector<double>q;
return q;
}
};