被精度以及向量的方向逼疯了
判断点在哪一条线段上,去另外两条线上二分答案,计算分出来的三角形面积是否为总面积的一半,需要注意的是二分时l和r不同端点缩的时候也不一样,这个其他二分题解都没有提,个人感觉这是个BUG,我是把l和r更换后再二分了一次
#include <bits/stdc++.h>
#define double long double
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define endl '\n'
using namespace std;
const double eps=1e-10;
struct Point {
double x,y;
};
struct Line {
Point p1,p2;
};
int dcmp(double a,double b){
if(fabs(a-b)<eps) return 0;
return a>b?1:-1;
}
Point operator-(Point a,Point b){
return {a.x-b.x,a.y-b.y};
}
bool operator==(Point a,Point b){
return !dcmp(a.x,b.x) && !dcmp(a.y,b.y);
}
Point operator+(Point a,Point b){
return {a.x+b.x,a.y+b.y};
}
Point operator/(Point a,double b){
return {a.x/b,a.y/b};
}
int sign(double a){
if(fabs(a)<eps) return 0;
else if(a>0) return 1;
else return -1;
}
double cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
double dot(Point a, Point b) {
return a.x*b.x+a.y*b.y;
}
int T;
Point p[4],o1;
double S;
bool on_segment(Point p, Line l){
Point a=l.p1;
Point b=l.p2;
return sign(cross(p - a, p - b)) == 0 && sign(dot(p - a, p - b)) <= 0;
}
double getdis(Point a,Point b){
return hypot(a.x-b.x,a.y-b.y);
}
double getarea(double d,double h){
return d*h/2;
}
double PLdis(Point a,Line s) {
double A=s.p1.y-s.p2.y;
double B=s.p2.x-s.p1.x;
double C=(s.p1.x-s.p2.x)*s.p1.y-(s.p1.y-s.p2.y)*s.p1.x;
return fabs(A*a.x+B*a.y+C)/sqrt((A*A+B*B));
}
double area(Point a,Point b,Point c){
return cross(b-a,c-a);
}
Point get_line_intersection(Point p,Point v,Point q,Point w){
Point u=p-q;
double t=cross(w,u)/cross(v,w);
return {p.x+t*v.x,p.y+t*v.y};
}
Point get_line_intersection(Line &a,Line &b){
return get_line_intersection(a.p1,a.p2-a.p1,b.p1,b.p2-b.p1);
}
bool on_right(Line a,Point o) {
return sign(area(a.p1,a.p2,o))<0;
}
bool find_area(Point o,Line L){
Point l=L.p1,r=L.p2,mid=(l+r)/2;
Point c;
int cnt[4];
memset(cnt,0,sizeof cnt);
for(int i=0;i<3;i++) if(on_right({mid,o},p[i])) cnt[i]++;
for(int i=0;i<3;i++) if(cnt[i]!=cnt[(i+1)%3] && cnt[i]!=cnt[(i+2)%3]) c=p[i];
double height=PLdis(o,L);
int times=1000;
while(times--){
mid=(l+r)/2;
int flag=dcmp(S,2*getarea(getdis(c,mid),height));
if(!flag){
printf("%.10Lf %.10Lf\n",mid.x,mid.y);
// cout<<fixed<<setprecision(10)<<mid.x<<" "<<mid.y<<endl;
return 1;
}
else if(flag==1) r=mid;
else l=mid;
}
return 0;
}
int main()
{
scanf("%d",&T);
while(T--){
int flag=0;
for(int i=0;i<3;i++) {
scanf("%Lf%Lf",&p[i].x,&p[i].y);
}
scanf("%Lf%Lf",&o1.x,&o1.y);
S=getarea(getdis(p[0],p[2]),PLdis(p[1],{p[0],p[2]}));
for(int i=0;i<3;i++){
if(o1==p[i]){
Point tmp=(p[(i+1)%3]+p[(i+2)%3])/2;
printf("%.10Lf %.10Lf\n",tmp.x,tmp.y);
flag=1;
break;
}
}
if(flag) continue;
for(int i=0;i<3;i++){
if(on_segment(o1,{p[i],p[(i+1)%3]})){
if(find_area(o1,{p[i],p[(i+2)%3]}) || find_area(o1,{p[(i+1)%3],p[(i+2)%3]})\
|| find_area(o1,{p[(i+2)%3],p[i]}) || find_area(o1,{p[(i+2)%3],p[(i+1)%3]})){
flag=1;
break;
}
}
if(flag) break;
}
if(!flag) printf("-1\n");
}
return 0;
}
/*
1
0 0 -50 0 66 6 -1 0
*/