2019 icpc nanjing K - Triangle (计算几何+乱搞)

计蒜客 - 42405

struct point {
	double x, y;
	point() {};
	point(double x, double y) : x(x), y(y) {};
	inline double dis(point b) {
		return sqrt((x - b.x) * (x - b.x) + (y - b.y) * (y - b.y));
	}
	point operator + (point b) const {
		return point(x + b.x, y + b.y);
	}
};
struct line {
	double k, b;
};
const double pi = acos(-1);
inline void add(double& l3_sita) {
	while (l3_sita >= pi / 2)	l3_sita -= pi / 2;
	while (l3_sita <= 0)	l3_sita += pi / 2;
}


signed main() {
	int t; scanf("%d", &t);
	while (t--) {
		point a, b, c, p;
		scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y, &c.x, &c.y, &p.x, &p.y);
		line l1, l2, l3;
		l1.k = (a.y - b.y) / (a.x - b.x); l1.b = a.y - l1.k * a.x;
		l2.k = (b.y - c.y) / (b.x - c.x); l2.b = b.y - l2.k * b.x;
		l3.k = (c.y - a.y) / (c.x - a.x); l3.b = c.y - l3.k * c.x;

		int posp = -1;
		if (p.x * l1.k + l1.b == p.y && p.x <= max(a.x, b.x) && p.x >= min(a.x, b.x))	posp = 1;
		if (p.x * l2.k + l2.b == p.y && p.x <= max(c.x, b.x) && p.x >= min(c.x, b.x))	posp = 2;
		if (p.x * l3.k + l3.b == p.y && p.x <= max(a.x, c.x) && p.x >= min(a.x, c.x))	posp = 3;
		if (posp == -1) {
			puts("-1"); continue;
		}

		double c1 = a.dis(b);
		double c2 = b.dis(c);
		double c3 = c.dis(a);

		double pl = (c1 + c2 + c3) / 2;
		double s = sqrt(pl * (pl - c1) * (pl - c2) * (pl - c3));
		if (posp == 1) {
			//puts("posp = 1");
			double disa = a.dis(p);
			double disb = b.dis(p);
			
			if (disa != 0) {
				double sita_a = fabs(atan(l3.k) - atan(l1.k));
				//add(sita_a);
				double tmpl = abs(s / disa / sin(sita_a));
				double l3_sita = atan(l3.k);
				//add(l3_sita);
				double cosx = abs(cos(l3_sita)), sinx = abs(sin(l3_sita));
				if (c.x < a.x)	cosx = -cosx;
				if (c.y < a.y)	sinx = -sinx;
				point ans = a + point({ tmpl * cosx, tmpl * sinx });
				if (tmpl <= c3) {
					printf("%.10lf %.10lf\n", ans.x, ans.y);
					continue;
				}
			}

			double sita_a = fabs(atan(l2.k) - atan(l1.k));
			//add(sita_a);
			double tmpl = abs(s / disb / sin(sita_a));
			double l2_sita = atan(l2.k);
			//add(l2_sita);
			double cosx = abs(cos(l2_sita)), sinx = abs(sin(l2_sita));
			if (c.x < b.x)	cosx = -cosx;
			if (c.y < b.y)	sinx = -sinx;
			point ans = b + point({ tmpl * cosx, tmpl * sinx });
			printf("%.10lf %.10lf\n", ans.x, ans.y);
		}
		else if (posp == 2) {
			//puts("posp = 2");
			double disa = b.dis(p);
			double disb = c.dis(p);

			if (disa != 0) {
				double sita_a = fabs(atan(l2.k) - atan(l1.k));
				//add(sita_a);
				double tmpl = abs(s / disa / sin(sita_a));
				double l3_sita = atan(l1.k);
				//add(l3_sita);
				double cosx = abs(cos(l3_sita)), sinx = abs(sin(l3_sita));
				if (a.x < b.x)	cosx = -cosx;
				if (a.y < b.y)	sinx = -sinx;
				point ans = b + point({ tmpl * cosx, tmpl * sinx });
				if (tmpl <= c1) {
					printf("%.10lf %.10lf\n", ans.x, ans.y);
					continue;
				}
			}

			double sita_a = fabs(atan(l2.k) - atan(l3.k));
			//add(sita_a);
			double tmpl = abs(s / disb / sin(sita_a));
			double l2_sita = atan(l3.k);
			//add(l2_sita);
			double cosx = abs(cos(l2_sita)), sinx = abs(sin(l2_sita));
			if (a.x < c.x)	cosx = -cosx;
			if (a.y < c.y)	sinx = -sinx;
			point ans = c + point({ tmpl * cosx, tmpl * sinx });
			printf("%.10lf %.10lf\n", ans.x, ans.y);
		}
		else if (posp == 3) {
			//puts("posp = 3");
			double disa = a.dis(p);
			double disb = c.dis(p);
			//printf("%lf %lf\n", disa, disb);
			if (disa != 0) {
				double sita_a = fabs(atan(l3.k) - atan(l1.k));
				//add(sita_a);
				double tmpl = abs(s / disa / sin(sita_a));
				double l3_sita = atan(l1.k);
				//add(l3_sita);
				double cosx = abs(cos(l3_sita)), sinx = abs(sin(l3_sita));
				if (b.x < a.x)	cosx = -cosx;
				if (b.y < a.y)	sinx = -sinx;
				//printf("%lf %lf\n", tmpl, tmpl * sinx);
				point ans = a + point({ tmpl * cosx, tmpl * sinx });
				if (tmpl <= c1) {
					printf("%.10lf %.10lf\n", ans.x, ans.y);
					continue;
				}
			}

			if (disb != 0) {
				double sita_a = fabs(atan(l3.k) - atan(l2.k));
				//add(sita_a);
				double tmpl = abs(s / disb / sin(sita_a));
				double l2_sita = atan(l2.k);
				//add(l2_sita);
				double cosx = abs(cos(l2_sita)), sinx = abs(sin(l2_sita));
				if (b.x < c.x)	cosx = -cosx;
				if (b.y < c.y)	sinx = -sinx;
				//printf("%lf %lf\n", tmpl, cosx);
				point ans = c + point({ tmpl * cosx, tmpl * sinx });
				printf("%.10lf %.10lf\n", ans.x, ans.y);
			}
		}
	}
}
上一篇:动态规划:路径系列


下一篇:B站小甲鱼-杨辉三角形详解