HDU 4720 Naive and Silly Muggles(计算几何, 求三角形外心)

HDU 4720


用好模板。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#define zero(x) (((x)>0?(x):-(x))<eps)
#define eps 1.0E-8
#define MAX_POINT_NUM 0

using namespace std;
int double_cmp(double a)
{
	if (zero(a))
		return 0;
	return a > 0 ? 1 : -1;
}

struct Point
{
	double	x,y;
	Point()
	{}
	Point(double x, double y):x(x), y(y)
	{}
	Point operator - (Point &a)
	{
		return Point(x - a.x, y - a.y);
	}
	Point operator + (Point &a)
	{
		return Point(x + a.x, y + a.y);
	}
	bool operator == (const Point &a) const
	{
		return zero(x - a.x) && zero(y - a.y);
	}
};

struct Line
{
	Point a, b;
	Line()
	{}
	Line(Point a, Point b):a(a), b(b)
	{}	
	bool operator == (const Line &l) const
	{
		return l.a == a && l.b == b;
	}
};

double cross_product(Point a, Point b)
{
	return a.x * b.y - b.x * a.y;
}

double cross_product(Point p0, Point p1, Point p2)
{
	return cross_product(p1 - p0, p2 - p0); //p0p1 叉乘 p0p2 
}
double vector_module(Point a)
{
	return sqrt(a.x * a.x + a.y * a.y);   //向量的模 
}
double dot_product(Point a, Point b)
{
	return a.x * b.x + a.y * b.y;  //a点乘 b 
}

double dot_product(Point p0, Point p1, Point p2)
{
	return dot_product(p1 - p0, p2 - p0);  //p0p1 点乘 p0p2 
}
double point_dist(Point a, Point b)
{
	return vector_module(a - b);  //两点间距离 
}
bool points_inline(Point p1, Point p2, Point p3)  //点p1 在直线p2p3上  即三点共线 
{
	return zero(cross_product(p1, p2, p3));
}

Point intersection_beeline(Line u,Line v){  //求两直线的交点,斜率相同的话res=u.a
    Point res = u.a;
    double t = 	cross_product(u.a - v.a, v.b - v.a) / 
				cross_product(u.a - u.b, v.b - v.a);
	Point vec = u.b - u.a;
	vec.x *= t;
	vec.y *= t;
    res = res + vec;
    return res;
}

bool point_incircle(Point o,double r,Point p) {   //点p在圆内或圆上 
	double d2 = (p.x - o.x) * (p.x - o.x) + (p.y - o.y) * (p.y-o.y); 
	double r2 = r * r; 
	return d2 < r2 || zero(d2 - r2);
} 

bool circumcentre(Point p1, Point p2, Point p3, Point &o, double &r) {  //求三角形外心 
    Line u, v;
    if(points_inline(p1, p2, p3)) return false;
    Point v12, v13, vert_v12, vert_v13;
    v12.x = p2.x - p1.x;
    v12.y = p2.y - p1.y;
    v13.x = p3.x - p1.x;
    v13.y = p3.y - p1.y;
    vert_v12.x = - v12.y;
    vert_v12.y = v12.x;
    vert_v13.x = - v13.y;
    vert_v13.y = v13.x;
    u.a.x = (p1.x + p2.x) / 2;
    u.a.y = (p1.y + p2.y) / 2;
    u.b = u.a + vert_v12;
    v.a.x=(p1.x + p3.x) / 2;
    v.a.y=(p1.y + p3.y) / 2;
    v.b = v.a + vert_v13;
    o = intersection_beeline(u,v);
    r = point_dist(p1, o);
    return true;
}

int main() {
	int T;
	scanf("%d", &T);
	int i;
	Point p1, p2, p3, p4;
	for(i = 1; i <= T; i++) {
		scanf("%lf %lf", &p1.x, &p1.y);
		scanf("%lf %lf", &p2.x, &p2.y);
		scanf("%lf %lf", &p3.x, &p3.y);
		scanf("%lf %lf", &p4.x, &p4.y);
		Point o;
		double r;
		if(dot_product(p1, p2, p3) <= 0) {  //钝角三角形和三点共线的情况。
			r = point_dist(p2, p3) / 2;
			o.x = (p2.x + p3.x) / 2;
			o.y = (p2.y + p3.y) / 2;
		}
		else if(dot_product(p2, p1, p3) <= 0) {
			r = point_dist(p1, p3) / 2;
			o.x = (p1.x + p3.x) / 2;
			o.y = (p1.y + p3.y) / 2;
		}
		else if(dot_product(p3, p1, p2) <= 0) {
			r = point_dist(p1, p2) / 2;
			o.x = (p1.x + p2.x) / 2;
			o.y = (p1.y + p2.y) / 2;
		}
		else {
			circumcentre(p1, p2, p3, o, r);
		}
		if(point_incircle(o, r, p4)) printf("Case #%d: Danger\n", i);
		else printf("Case #%d: Safe\n", i);
	}
    return 0;
}


你可能感兴趣的:(HDU 4720 Naive and Silly Muggles(计算几何, 求三角形外心))