#include <bits/stdc++.h>
using namespace std;
struct point {
double x, y;
point(double A, double B) {
x = A, y = B;
}
point() = default;
};
struct line {
point point_A, point_B;
line(point A, point B) {
point_A = A, point_B = B;
}
line() = default;
};
point findMeetingPoint(line line_A, line line_B) {
//方法一:参数方程+叉积
/*double ax=line_A.point_A.x,ay=line_A.point_A.y;
double bx=line_A.point_B.x,by=line_A.point_B.y;
double cx=line_B.point_A.x,cy=line_B.point_A.y;
double dx=line_B.point_B.x,dy=line_B.point_B.y;
double den=(bx-ax)*(dy-cy)-(by-ay)*(dx-cx);
if(abs(den)<1e-9)return point(-1,-1);
double t=((cx-ax)*(dy-cy)-(cy-ay)*(dx-cx))/den;
return point (ax+t*(bx-ax),ay+t*(by-ay));*/
//方法二,二阶行列式解方程
double ax=line_A.point_A.x,ay=line_A.point_A.y;//单设方便使用
double bx=line_A.point_B.x,by=line_A.point_B.y;
double cx=line_B.point_A.x,cy=line_B.point_A.y;
double dx=line_B.point_B.x,dy=line_B.point_B.y;
double a1=by-ay,b1=ax-bx,c1=(bx*ay-ax*by)*-1;//直线1的一般方程式参数
double a2=dy-cy,b2=cx-dx,c2=(dx*cy-cx*dy)*-1;//直线2的一般方程式参数
//我设c1,c2时它作为一般式的常数项在等式左边,我使用克莱姆法则时将c1,c2移到了等式右侧
//所以c1,c2要移项操作乘以-1
double D=a1*b2-a2*b1;
if(abs(D)<1e-9)return point(-1,-1);
//double有误差,所以不能直接判断是否等于零,需要一个够小的数
//若D的绝对值小于le-9,可以看做零函数误解或无数解
double Dx=c1*b2-c2*b1,Dy=a1*c2-a2*c1;//先判断再运算否则浪费算力
return point(Dx/D,Dy/D);
}
int main() {
point A, B, C, D;
cin >> A.x >> A.y >> B.x >> B.y >> C.x >> C.y >> D.x >> D.y;
line AB = line(A, B);
line CD = line(C, D);
point ans = findMeetingPoint(AB, CD);
cout << fixed << setprecision(12) << ans.x << " " << ans.y;
return 0;
}
方法一:含参方程+叉积
//设点p1(x1,y1),p2(x2,y2),p1和p2叉积运算=x1*y2-y1*x2(可以看做二阶行列式),注意叉积满足反交换律,所以理清顺序
设直线L1:a+t*(b-a) 设直线L2: c+u*(d-c) //a,b,c,d都是点,t是任意实数,这样可以表示出直线(每一个确定t使式子对应一点)
所以在交点处有 a+t*(b-a)=c+u*(d-c) //可以使用叉积运算,如下
t*(b-a)=c-a+u*(d-c) //移项
t*(b-a) x (d-c)=(c-a) x (d-c) //x表示叉积运算,对每项右叉(d-c),自身叉积为0,即(d-c) x (d-c)=0,于是将u消掉
t=(c-a) x (d-c)/(b-a) x (d-c) //于是表示出t
先运算t的分母,分母为零则无解或无数解 //由于double有误差,若分母绝对值小于一个足够小的数可视为零
若分母不为零,将t带回 a+t*(b-a)可得点 //运算两次分别求该点的x和y
方法二:二阶行列式解方程
设直线上两点 p1(x1,y1),p2(x2,y2)
对于该直线一般式Ax+By+C=0有 A=y2-y1,B=x1-x2,C=x2*y1-x1*y2 即(p2叉p1)
或者 A=y1-y2,B=x2-x1,C=x1*y2-x2*y1 即(p1叉p2)
可以列方程组了 //注意我这里列的方程中C移项了,所以要*-1
(1) a1x+b1y=c1
(2) a2x+b2y=c2
于是有x=Dx/D,y=Dy/D;
D=a1*b2-a2*b1,Dx=c1*b2-c2*b1,Dy=a1*c2-a2*c1
当然,要先判断D,若D=0则无解或无数解 //同样,需要比较D的绝对值和一个足够小的值判断是否忽略误差
若D不等于零,于是可求出想x,y得点(x,y)为交点

京公网安备 11010502036488号