传送门
计算几何基础题——第三题
这个题就是直线判重合,直线判平行,直线求交
以下假设Line1(P1,P2),Line2(P3,P4)
判重合:
我们只需要判断Cross(P1-P3,P2-P3)和Cross(P1-P4,P2-P4)都为0
也就是P1,P2,P3共线且P1,P2,P4共线
判平行:
只要Cross(P1-P2,P3-P4)为0就好了
也就是平移到同一点,然后判共线
判这个之前先判重合就好了
求交:
利用叉积即可,我们设交点为P0
那么P0,P1,P2共线,P0,P3,P4共线
即Cross(P1-P0,P2-P0)=0,且Cross(P3-P0,P4-P0)=0
用这两个式子来列方程,然后用行列式求解就好了。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
inline int read(){
int x=0;char ch=' ';int f=1;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
const double eps=1e-8;
struct Point{
double x,y;
Point(){}
Point(double _x,double _y):x(_x),y(_y){}
inline void Read(){x=read();y=read();}
inline Point operator - (const Point& b) const {return Point(x-b.x,y-b.y);}
inline double operator * (const Point& b) const {return x*b.y-y*b.x;}
};
struct Line{
Point s,t;
Line(){}
Line(Point _s,Point _t):s(_s),t(_t){}
};
inline int dcmp(double x){
if(fabs(x)<eps)return 0;
return x>eps?1:-1;
}
inline bool check_none(const Line& a,const Line& b){
return !dcmp((a.t-a.s)*(b.t-b.s));
}
inline bool check_line(const Line& a,const Line& b){
return !dcmp((a.s-b.s)*(a.t-b.s))&&!dcmp((a.s-b.t)*(a.t-b.t));
}
inline Point solve(double a1,double b1,double c1,double a2,double b2,double c2){
Point p;
p.x=(b2*c1-b1*c2)/(a1*b2-a2*b1);
p.y=(a1*c2-a2*c1)/(a1*b2-a2*b1);
return p;
}
inline void check(const Line& a,const Line& b){
if(check_line(a,b))puts("LINE");
else if(check_none(a,b))puts("NONE");
else{
Point p1,p2,p3,p4;
p1=a.s;p2=a.t;p3=b.s;p4=b.t;
double a1=p1.y-p2.y,b1=p2.x-p1.x,c1=p2*p1;
double a2=p3.y-p4.y,b2=p4.x-p3.x,c2=p4*p3;
Point ans=solve(a1,b1,c1,a2,b2,c2);
printf("POINT %.2lf %.2lf\n",ans.x,ans.y);
}
}
int n;
Line a,b;
int main(){
n=read();
puts("INTERSECTING LINES OUTPUT");
while(n--){
a.s.Read();a.t.Read();b.s.Read();b.t.Read();
check(a,b);
}
puts("END OF OUTPUT");
return 0;
}