题解:枚举每条边,每条边考虑三种情况,当前边(重合于x轴,重合于y轴,倾斜x轴某一角度A)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int mod = 998244353;
const int MX = 1e5+7;
const double eps = 1e-12;
const double PI = acos(-1.0);
struct Point {
double x, y;
Point() {}
Point(double x,double y):x(x),y(y) {}
};
typedef Point Vector;
int dcmp(double x) { //返回x的正负
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
Vector operator-(Vector A,Vector B) {return Vector(A.x - B.x, A.y - B.y);}
Vector operator+(Vector A,Vector B) {return Vector(A.x + B.x, A.y + B.y);}
Vector operator*(Vector A,double p) {return Vector(A.x*p, A.y*p);}
Vector operator/(Vector A,double p) {return Vector(A.x/p, A.y/p);}
bool operator<(const Point&a,const Point&b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool operator==(const Point&a,const Point&b) {return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}
double Dot(Vector A,Vector B) { //点积
return A.x*B.x+A.y*B.y;//如果改成整形记得加LL
}
double Cross(Vector A,Vector B) { //叉积
return A.x*B.y-A.y*B.x;//如果改成整形记得加LL
}
//向量长度
double Length(Vector A) {
return sqrt(Dot(A,A));
}
//2个向量之间的夹角
double Angle(Vector A,Vector B) {
return acos(Dot(A,B)/Length(A)/Length(B));
}
//向量的极角
double angle(Vector v) {
return atan2(v.y,v.x);
}
//计算ABC的有向面积
double Area(Point A,Point B,Point C) {
return Cross(B-A,C-A)/2;
}
//将A向量逆时针旋转rad
Vector Rotate( Vector A,double rad) {
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
//返回A的逆时针旋转90度的单位法向量
Vector Normal(Vector A) {
double L=Length(A);
return Vector(-A.y/L,A.x/L);
}
int main() {
#ifdef LOCAL
freopen ("input.txt", "r", stdin);
#endif
int T;
Point p[5];
double len[5];
double ang[5];
double w;
for(scanf("%d",&T); T; T--){
for(int i = 0; i < 3; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
scanf("%lf",&w);
len[0] = Length(p[0]-p[1]); len[1] = Length(p[1]-p[2]); len[2] = Length(p[2]-p[0]);
ang[0] = Angle(p[0]-p[2],p[1]-p[2]);
ang[1] = Angle(p[1]-p[0],p[2]-p[0]);
ang[2] = Angle(p[2]-p[1],p[0]-p[1]);
int n = 3;
double ans = 100000;
for(int i = 0; i < 3; i++){
double minang = ang[(i-1+3)%3], maxang = ang[(i+1)%3];
if(minang > maxang) swap(minang,maxang);
double minlen = len[(i-1+3)%3], maxlen = len[(i+1)%3];
if(minlen > maxlen) swap(minlen,maxlen);
Point dot = Point(0,0);
Vector v = Point(1,0);
//平躺
if(dcmp(len[i] - w) <= 0){
dot = Point(Rotate(v*maxlen, minang));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,dot.y);
dot = Point(Rotate(v*minlen, maxang));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,dot.y);
}
//竖直
double minang2 = PI/2 - minang, maxang2 = PI/2 - maxang;
dot = Point(Rotate(v*maxlen, minang2));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,max(dot.y,len[i]) );
dot = Point(Rotate(v*minlen, maxang2));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,max(dot.y,len[i]) );
//斜着
if(len[i] > w){
double A = acos(w/len[i]);
Vector d = Point(Rotate(v*len[i], A));
dot = Point(Rotate(v*maxlen, A-minang));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,max(dot.y,d.y));
dot = Point(Rotate(v*maxlen, A+minang));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,max(dot.y,d.y));
dot = Point(Rotate(v*minlen, A-maxang));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,max(dot.y,d.y));
dot = Point(Rotate(v*minlen, A+maxang));
if(dcmp(dot.x) >= 0 && dcmp(dot.x - w) <= 0 && dot.y > 0) ans = min(ans,max(dot.y,d.y));
}
}
if(dcmp(ans-100000) == 0) puts("impossible");
else printf("%.8f\n",ans);
}
return 0;
}