刚开始做这道题的时候 想到的是两点距离公式和点积为零解方程解出两个解但是写出来是一个二元二次方程 不会解。。。
于是换成直线方程来做 铁定能解出来 但是忘记考虑了一个问题如果k很大的话 那么就没法做了 会溢出啊
不明白为什么k很大会溢出的自己推一推公式就明白了 所以直线方程法也不能用
于是只剩最后一种方法了 向量旋转法 因为这种方法以前没用过所以我刚开始的时候没有用 但是到最后不得不用了
其实向量旋转方法做是最简单的。。。。
下面是直线方程法解的 结果溢出了 没法做啊
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct Point
{
double x,y;
Point():x(0),y(0){};
}A,C;
typedef struct Point point;
double Dist(point p1,point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
int main()
{
while (scanf("%lf%lf%lf%lf",&A.x,&A.y,&C.x,&C.y)!=EOF)
{
point B,D,M;
double dis,k,l_b;
M.x = (A.x +C.x)/2;
M.y = (A.y +B.y)/2;
if(A.x == C.x || A.y ==C.y)
{
if(A.x == C.x)
{
dis = fabs(A.y-C.y)/2;
D.x = B.x = M.x;
D.y = M.x + dis;
B.y = M.x - dis;
}
else
{
dis = fabs(A.x-C.x)/2;
D.y = B.y = M.y;
D.x = M.x + dis;
B.x = M.x - dis;
}
}
else
{
printf("M.x = %lf M.y = %lf\n",M.x,M.y);
k = (A.x-C.x)/(A.y-C.y);
dis = Dist(A,C)/2.0;
l_b = M.y - k*M.x;//截距 没考虑到k很大的时候会溢出 所以直线方程的方法不能用
printf("k = %lf dis = %lf l_b = %lf\n",k,dis,l_b);
double a = 1.0+k*k;
double b = -(2.0*M.x-2.0*k*l_b+2.0*M.y*k);
double c = M.x*M.x+b*b-2*M.y*l_b+M.y*M.y-dis*dis;
double dirt = sqrt(b*b-4.0*a*c);
printf("a = %lf b = %lf c = %lf\n dirt = %lf\n",a,b,c,dirt);
B.x = (dirt-b)/(2.0*a);
B.y = k*B.x +l_b;
D.x = (-b-dirt)/(2*a);
D.y = k*D.x +l_b;
}
printf("%.10lf %.10lf %.10lf %.10lf\n",D.x,D.y,B.x,B.y);
}
return 0;
}
然后换成向量旋转果断AC啊
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1e-6
using namespace std;
struct Point
{
double x,y;
Point():x(0),y(0){};
}A,C;
typedef struct Point point;
int main()
{
while (scanf("%lf%lf%lf%lf",&A.x,&A.y,&C.x,&C.y)!=EOF)
{
if(fabs(A.x-C.x)<eps&&fabs(A.y-C.y)<eps)
{
printf("Impossible.\n");
continue;
}
point B,D,M;
M.x = (A.x +C.x)/2;
M.y = (A.y +C.y)/2;
B.x = M.x - (C.y - M.y);
B.y = M.y + (C.x - M.x);
D.x = M.x - (A.y - M.y);
D.y = M.y + (A.x - M.x);
printf("%.10lf %.10lf %.10lf %.10lf\n",D.x,D.y,B.x,B.y);
}
return 0;
}