题目在这里1059
这道题的思路挺简单的,根据题目的意思,模拟就可以。不过需要一点数学知识,可以参考这里向量旋转。
因为题目说:给的测试数据能保证不会出现三点在一条线上的情况,所以那三条线必然相交,那么只要任选两条线,计算出他们的k和b,然后直接就能算出来交点,同时,这个交点也必然在第三条线上,所以可以任选两条线计算交点即可。
然后,需要注意的是在判断旋转的角度的时候。因为这里的角度只有-90和90,而cos(90) = cos(-90) = 0,所以在向量旋转的公式里,我把cos的项删除了,反正是0。然后,sin被我改了一下,因为sin只有两个值1或-1,所以自己写了一个函数代替了c++里math.h的sin。好吧,继续说判断角度的问题。这里,当选定了两个顶点作为旋转的边的时候,就要根据三角形第三个顶点相对于这条边的位置来判断角度。此时,可以利用高中学的知识“判断一个点和一条线的关系,只要把这个点的坐标,带入这条线的公式(y=kx+b),如果左边大于右边,那么这个点在这条直线的上方;如果等于,则在这条直线上;如果小于,那么在下方”。有了这个依据,在注意一下正负号,就很容易得到角度了。
下面是我的代码,仅供参考:
#include<iostream>
#include<vector>
#include<stdio.h>
using namespace std;
#define EPS 1e-7
#define INF 1e+15
int dcmp(double a, double b)
{
if (a - b < -EPS)
return -1;
if (a - b > EPS)
return 1;
return 0;
}
struct Vector
{
double x;
double y;
Vector(double x, double y)
{
this->x = x;
this->y = y;
}
};
struct Point
{
double x;
double y;
Point(double x, double y)
{
this->x = x;
this->y = y;
}
Point(Vector v, Point p)
{
this->x = v.x + p.x;
this->y = v.y + p.y;
}
};
Vector getVector(Point p1, Point p2)
{
return Vector(p2.x - p1.x, p2.y - p1.y);
}
struct Line
{
double k;
double b;
Line(double k, double b)
{
this->k = k;
this->b = b;
}
Line(Point p1, Point p2)
{
if (dcmp(p1.x, p2.x) == 0)
{
this->k = INF;
this->b = p1.x;
}
else
{
double k = (p2.y - p1.y) / (p2.x - p1.x);
double b = p1.y - k * p1.x;
this->k = k;
this->b = b;
}
}
};
int s(int angel)
{
return angel / 90;
}
Vector rotate(Vector v, int angel)
{
return Vector(-v.y * s(angel), v.x * s(angel));
}
int getAngel(Point start, Point end, Point ref)
{
if (dcmp(start.x, end.x) == 0)
{
if (dcmp(ref.x, start.x) < 0)
return dcmp(start.y, end.y) * 90;
else
return dcmp(start.y, end.y) * (-90);
}
else
{
Line l = Line(start, end);
if (dcmp(ref.y, ref.x * l.k + l.b) < 0)
return dcmp(start.x, end.x) * (-90);
else
return dcmp(start.x, end.x) * (90);
}
}
Point getRotatePoint(Point start, Point end, Point ref)
{
int angel = getAngel(start, end, ref);
Vector v = getVector(start, end);
Vector vv = rotate(v, angel);
return Point(vv, start);
}
Line getLine(Point start, Point end1, Point end2)
{
Point p1 = getRotatePoint(start, end1, end2);
Point p2 = getRotatePoint(start, end2, end1);
Point mid = Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
return Line(mid, start);
}
Point ans(Line l1, Line l2)
{
if (dcmp(l1.k, INF) == 0 && dcmp(l2.k, INF) != 0)
{
return Point(l1.b, l2.k * l1.b + l2.b);
}
if (dcmp(l1.k, INF) != 0 && dcmp(l2.k, INF) == 0)
{
return Point(l2.b, l1.k * l2.b + l1.b);
}
return Point((l2.b - l1.b) / (l1.k - l2.k), (l1.k * l2.b - l2.k * l1.b) / (l1.k - l2.k));
}
int main()
{
int n;
vector<Point> p;
double x, y;
cin >> n;
while (n--)
{
for (int i = 0; i < 3; i++)
{
cin >> x >> y;
p.push_back(Point(x, y));
}
Line l1 = getLine(p[0], p[1], p[2]);
Line l2 = getLine(p[1], p[0], p[2]);
Point cross = ans(l1, l2);
if (cross.x == -0.0)
cross.x = 0.0;
if (cross.y == -0.0)
cross.y = 0.0;
printf("%.4lf %.4lf\n", cross.x, cross.y);
p.clear();
}
//system("pause");
return 0;
}
另外,很奇怪的是,当我没有加下面这段语句的时候,在运行测试用例
0.0 0.0
3.0 4.0
-4.0 3.0
时候,结果居然是-0.0000 0.0000。我瞬间无语了,这是怎么了?为什么会出现这种情况?
if (cross.x == -0.0)
cross.x = 0.0;
if (cross.y == -0.0)
cross.y = 0.0;