51nod-1298 圆与三角形(计算几何超详解)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1298
给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。
Input第1行:一个数T,表示输入的测试数量(1 <= T <= 10000),之后每4行用来描述一组测试数据。
4-1:三个数,前两个数为圆心的坐标xc, yc,第3个数为圆的半径R。(-3000 <= xc, yc <= 3000, 1 <= R <= 3000)
4-2:2个数,三角形第1个点的坐标。
4-3:2个数,三角形第2个点的坐标。
4-4:2个数,三角形第3个点的坐标。(-3000 <= xi, yi <= 3000)Output共T行,对于每组输入数据,相交输出"Yes",否则输出"No"。Sample Input
2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5
Sample Output
Yes
No 基础知识回顾:
点到直线距离公式:

余弦定理:

分析:
对于给定的三角形和圆,我们考虑相交的情况:


① 三角形有一点在圆内,有一点在圆外。
② 三角形有一点在圆上。
③三角形三点都在圆外,但有一条边与圆相交或相切。
前两种情况比较好写,只需要判断三角形三个端点到圆心的距离与半径的关系即可。
对于第三种情况,我们可以先判断圆心到三角形三条边的距离,如果有一条边到圆心的直线距离小于等于半径,我们进而去判断圆心到这条边所在直线的垂足是否在这条边上。如何去判断呢?
我们可以利用余弦定理,只要圆心与这条边的两个端点所成的角均为锐角(即cosα>0),那么垂足必然落在这条边上。
以下是AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct triangle//用结构体来存三角形三点的坐标
{
double x[],y[];
};
double x,y,r;
triangle a;
//计算(x1,y1)与(x2,y2)之间的距离的平方
double point_dist(double x1,double y1,double x2,double y2)
{
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}
//计算圆心(x,y)到直线Ax+By+C=0的距离的平方
double line_dist(double A,double B,double C)
{
double ans = ( (A*x + B*y + C) * (A*x + B*y + C) ) / (A*A + B*B);
return ans > ? ans : -ans;
}
double f(double a,double b,double c)//余弦定理
{
return (b + c - a) / (2.0 * sqrt(b * c));
}
int main()
{
int i,j,t;
cin>>t;
while(t--)
{
//Input
scanf("%lf%lf%lf",&x,&y,&r);
for(i = ;i < ; i++)
scanf("%lf%lf",&a.x[i],&a.y[i]);
//Solve
double dis1[],dis2[],dis3[];
//dis1存放三角形三点到圆心距离的平方
dis1[] = point_dist(x,y,a.x[],a.y[]);
dis1[] = point_dist(x,y,a.x[],a.y[]);
dis1[] = point_dist(x,y,a.x[],a.y[]);
//dis2存放三角形三条边长的平方
dis2[] = point_dist(a.x[],a.y[],a.x[],a.y[]);
dis2[] = point_dist(a.x[],a.y[],a.x[],a.y[]);
dis2[] = point_dist(a.x[],a.y[],a.x[],a.y[]);
//dis3存放三角形三条边到圆心的直线距离的平方
dis3[] = line_dist(a.y[]-a.y[],a.x[]-a.x[],(a.x[]-a.x[])*a.y[]+(a.y[]-a.y[])*a.x[]);
dis3[] = line_dist(a.y[]-a.y[],a.x[]-a.x[],(a.x[]-a.x[])*a.y[]+(a.y[]-a.y[])*a.x[]);
dis3[] = line_dist(a.y[]-a.y[],a.x[]-a.x[],(a.x[]-a.x[])*a.y[]+(a.y[]-a.y[])*a.x[]);
double t1,t2;
t1 = min(dis1[],min(dis1[],dis1[]));//t1为三点到圆心距离最小的那个
t2 = max(dis1[],max(dis1[],dis1[]));//t2为三点到圆心距离最大的那个
if(t1 <= r*r &&t2 >= r*r)//一点在圆内,一点在圆外或有一点在圆上
cout<<"Yes"<<endl;
else if(t1 > r*r)//三点都在圆外
{
if(dis3[] <= r*r)//dis3[0]是由点1和点2连接起来的边到圆心的距离
{
if(f(dis1[],dis2[],dis1[]) > && f(dis1[],dis2[],dis1[]) > )
{
cout<<"Yes"<<endl;
continue;
}
}
if(dis3[] <= r*r)//dis3[1]是由点2和点3连接起来的边到圆心的距离
{
if(f(dis1[],dis2[],dis1[]) > && f(dis1[],dis2[],dis1[]) > )
{
cout<<"Yes"<<endl;
continue;
}
}
if(dis3[] <= r*r)//dis3[2]是由点1和点2连接起来的边到圆心的距离
{
if(f(dis1[],dis2[],dis1[]) > && f(dis1[],dis2[],dis1[]) > )
{
cout<<"Yes"<<endl;
continue;
}
}
cout<<"No"<<endl;
}
else
cout<<"No"<<endl;
}
return ;
}
代码需注意的几点:
① 计算距离时不要用sqrt函数,会导致计算误差WA
② 已知三角形一条边的两端点(x1,y1)和(x2,y2),我们将这条边的直线方程斜截式y=kx+b转换为一般式ax+by+c=0所得结果为 (y1-y2)x+(x2-x1)y+(x1-x2)y1+(y2-y1)x1=0,这也是给dis3数组赋值的依据。
51nod-1298 圆与三角形(计算几何超详解)的更多相关文章
- 51Nod 1298 圆与三角形(计算几何)
1298 圆与三角形 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交.相交输出"Yes&quo ...
- 51nod 1298 圆与三角形——计算几何
题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1298 转化成判断三条线段和圆是否
- 51nod 1298 圆与三角形 (计算几何)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1298 求出圆心到三条线段的最短距离,然后判断是否有顶点在圆外,就把全部情 ...
- 51nod 1298:圆与三角形(计算几何)
题目链接 判断圆和三角形是否相交 可以转化为 判断三条线段是否和圆相交 #include<iostream> #include<cstdio> #include< ...
- 51nod 1298 圆与三角形
给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交.相交输出"Yes",否则输出"No".(三角形的面积大于0). 输入 第1行:一个数 ...
- (图论)51NOD 1298 圆与三角形
给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交.相交输出"Yes",否则输出"No".(三角形的面积大于0). 输入 第1行:一个数T, ...
- html5的float属性超详解(display,position, float)(文本流)
html5的float属性超详解(display,position, float)(文本流) 一.总结 1.文本流: 2.float和绝对定位都不占文本流的位置 3.普通流是默认定位方式,就是依次按照 ...
- HTML中DOM核心知识有哪些(带实例超详解)
HTML中DOM核心知识有哪些(带实例超详解) 一.总结: 1.先取html元素,然后再对他进行操作,取的话可以getElementById等 2.操作的话,可以是innerHtml,value等等 ...
- Mysql超详解
Mysql超详解 一.命令框基本操作及连接Mysql 找到Mysql安装路径,查看版本 同时按快捷键win+R会弹出一个框,在框中输入cmd 点击确定后会出现一个黑框,这是命令框,我们的操作要在这命令 ...
随机推荐
- 1034. [ZJOI2008]泡泡堂【贪心】
Description 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省的代表 队由n名选手组成,比赛的项目是老少咸宜的网络游戏泡泡堂.每一场比赛前,对 ...
- Day14 集合(一)
集合总体介绍 Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.*Java集合主要可以划分为4个部分:List列 ...
- windows禁用端口命令
netstat -aon|findstr 1099 找出占用1099端口的进程 然后关闭占用该端口的进程:taskkill -f -pid 3756(进程id)
- springboot不使用内置tomcat启动,用jetty或undertow
Spring Boot启动程序通常使用Tomcat作为默认的嵌入式服务器.如果需要更改 - 您可以排除Tomcat依赖项并改为包含Jetty或Undertow: jetty配置: <depend ...
- C++编写简单的Service和Client
在上一步的基础上 编写Service节点 这里,我们将创建一个简单的service节点("add_two_ints_server"),该节点将接收到两个整形数字,并返回它们的和. ...
- 有关ajax
1.什么是ajax? ajax是前端与后端交互所依赖的一项技术,它相当于一座桥梁,沟通了前端与后端. 2.ajax的优点 可以局部更新网页内容. 3.ajax的本质就是xmlHttpRequest对象 ...
- 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化
2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...
- 1-[Mysql]-数据库介绍及安装
1.数据库概述 1.数据库服务器: 运行数据库管理软件的计算机 2.数据库管理软件:mysql oracle db2 sqlserver 3.库:文件夹 4.表:文件 5.记录:事物的一系列典型特征: ...
- JAVAWEB servlet和jsp的权限访问控制
要想防止用户直接访问某个页面,那么就需要要求他带着session来访问,我们才让他访问,所以登录时设置的session就用上了 在用户没有session时,访问servlet或者jsp时直接重定向页面 ...
- 提高你的Python编码效率的“武林秘籍”
我用Python编程有几年了, 并且我仍然经常惊讶于Python代码可以如何的简洁,如何的 DRY . 我学到了很多小贴士和技巧,大多数来自于阅读开源项目的源代码,像Django, Flask, Re ...