圆与三角形

Problem Description

在几何的世界里,有一个圆和一个三角形,现在分别告诉他们的位置,请编程判断他们之间的位置关系,是不是很简单呢?祝你好运吧~

Input

多组测试数据,第一行有一个整数t(1<=t<=100)代表case数量,对于每个case,第一行有三个整数x,y,r分别代表圆心的位置和半径,第二行有6个整数分别代表三角形的三个点(对于所有坐标绝对值小于1000,0<r<1000)

Output

每个case形如"Case #K: M",K代表case数,从1开始,M代表它们之间的关系。(如果相离或者相切输出"OO",如果三角形包含圆或者圆包含三角形输出"II",部分相交则输出"XX")

Sample Input

3
0 0 1
-5 -5 0 5 5 0
0 0 1
-2 -1 0 1 2 1
0 0 1
5 5 6 5 6 6

Sample Output

Case #1: II
Case #2: XX
Case #3: OO

#include <cstdio>
#include <iostream>
#include <math.h>
using namespace std;
#define PI 3.1415926535898

double juli(double rx, double ry, double x1, double y1, double x2, double y2) {
	double d;
	d = fabs((y2 - y1)*rx + (x2 - x1)*ry + x1*(y2 - y1) + y1*(x2 - x1)) / (sqrt((y2 - y1)*(y2 - y1) + (x2 - x1)*(x2 - x1)));
	return d;
}

double PointToSegDist(double x, double y, double x1, double y1, double x2, double y2) {
	double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
	if (cross <= 0)
		return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
	double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
	if (cross >= d2)
		return sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
	double r = cross / d2;
	double px = x1 + (x2 - x1) * r;
	double py = y1 + (y2 - y1) * r;
	return sqrt((x - px)*(x - px) + (py - y)*(py - y));
}


double ddjl(double x1, double y1, double x2, double y2) {
	double d;
	d = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
	return d;
}

double trianglearea(double x1, double y1, double x2, double y2, double x3, double y3) {
	return fabs((1.0 / 2.0)*(x1*y2 + x2*y3 + x3*y1 - x1*y3 - x2*y1 - x3*y2));
}

int tfpointintriangle(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3) {
	double area = 0;
	double triangle_area2 = trianglearea(x1, y1, x2, y2, x3, y3);
	area += trianglearea(x, y, x2, y2, x3, y3);
	area += trianglearea(x1, y1, x, y, x3, y3);
	area += trianglearea(x1, y1, x2, y2, x, y);
	if (area == triangle_area2)
		return 1;
	return 0;
}

int main() {
	int n;
	while (~scanf("%d", &n)) {
		for (int i = 1; i <= n; i++) {
			int round_x, round_y, round_r;
			double round_area = 0.0;
			int triangle_1_x, triangle_1_y;
			int triangle_2_x, triangle_2_y;
			int triangle_3_x, triangle_3_y;
			double triangle_area = 0.0;
			scanf("%d%d%d", &round_x, &round_y, &round_r);
			scanf("%d%d", &triangle_1_x, &triangle_1_y);
			scanf("%d%d", &triangle_2_x, &triangle_2_y);
			scanf("%d%d", &triangle_3_x, &triangle_3_y);

			round_area = PI*(double)round_r*(double)round_r;
			triangle_area = fabs((1.0 / 2.0)* \
				(triangle_1_x*triangle_2_y + triangle_2_x*triangle_3_y \
					+ triangle_3_x*triangle_1_y - triangle_1_x*triangle_3_y \
					- triangle_2_x*triangle_1_y - triangle_3_x*triangle_2_y));

			double d1, d2, d3;
			//d1 = juli(round_x, round_y, triangle_1_x, triangle_1_y, triangle_2_x, triangle_2_y);
			//d2 = juli(round_x, round_y, triangle_1_x, triangle_1_y, triangle_3_x, triangle_3_y);
			//d3 = juli(round_x, round_y, triangle_3_x, triangle_3_y, triangle_2_x, triangle_2_y);

			d1 = PointToSegDist(round_x, round_y, triangle_1_x, triangle_1_y, triangle_2_x, triangle_2_y);
			d2 = PointToSegDist(round_x, round_y, triangle_1_x, triangle_1_y, triangle_3_x, triangle_3_y);
			d3 = PointToSegDist(round_x, round_y, triangle_3_x, triangle_3_y, triangle_2_x, triangle_2_y);

			double d4, d5, d6;
			d4 = ddjl(round_x, round_y, triangle_1_x, triangle_1_y);
			d5 = ddjl(round_x, round_y, triangle_2_x, triangle_2_y);
			d6 = ddjl(round_x, round_y, triangle_3_x, triangle_3_y);

			double min = d1;
			if (min > d2)
				min = d2;
			if (min > d3)
				min = d3;

			double max = d4;
			if (min < d5)
				min = d5;
			if (min < d6)
				min = d6;

			int flag = tfpointintriangle(round_x, round_y, triangle_1_x, triangle_1_y, triangle_2_x, triangle_2_y, triangle_3_x, triangle_3_y);

			if (min >= round_r && flag == 0)
				printf("Case #%d: OO\n", i);
			else if ((max <= round_r && round_area > triangle_area) || (min > round_r && round_area < triangle_area))
				printf("Case #%d: II\n", i);
			else
				printf("Case #%d: XX\n", i);


			//printf("%lf  %lf\n", max, min);
			//printf("%lf  %lf  %lf\n", d1, d2, d3);
			//printf("%lf  %lf\n", round_area, triangle_area);

		}
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值