点到圆弧的距离_到弧的距离_KM6714的博客-程序员秘密

技术标签: 几何  

Description

输入一个点P和一条圆弧(圆周的一部分),你的任务是计算P到圆弧的最短距离。换句话说,你需要在圆弧上找一个点,到P点的距离最小。
提示:请尽量使用精确算法。相比之下,近似算法更难通过本题的数据。

Input

输入包含最多10000组数据。每组数据包含8个整数x1, y1, x2, y2, x3, y3, xp, yp。圆弧的起点是A(x1,y1),经过点B(x2,y2),结束位置是C(x3,y3)。点P的位置是 (xp,yp)。输入保证A, B, C各不相同且不会共线。上述所有点的坐标绝对值不超过20。

Output

对于每组数据,输出测试点编号和P到圆弧的距离,保留三位小数。你的输出和标准输出之间最多能有0.001的误差。

Sample Input

<span class="sampledata" style="font-family: monospace; font-size: 18px; white-space: pre; background-color: rgb(141, 184, 255);">0 0 1 1 2 0 1 -1
3 4 0 5 -3 4 0 1</span>

Sample Output

<span class="sampledata" style="font-family: monospace; font-size: 18px; white-space: pre; background-color: rgb(141, 184, 255);">Case 1: 1.414
Case 2: 4.000</span>

HINT

Source


PS:

分两种情况:

第一种:点跟圆心的连线那段扇形的圆弧范围内,点到圆弧的最短距离为点到圆心的距离减去半径然后取绝对值;

第二种:点跟圆心的连线不在那段扇形的圆弧范围内,点到圆弧的最短的距离为到这段圆弧的两个端点的最小值。


代码如下:(参考夏笑声

[cpp]  view plain   copy
  print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <cstdio>  
  2. #include <cstring>  
  3. #include <cmath>  
  4. #include <iostream>  
  5. #include <algorithm>  
  6. using namespace std;  
  7. const double PI = acos(-1.0);  
  8.   
  9. struct Point  
  10. {  
  11.     double x,y;  
  12.     friend Point operator - (Point a,Point b) //重载友元运算符  
  13.     {  
  14.         Point temp;  
  15.         temp.x = a.x - b.x;  
  16.         temp.y = a.y - b.y;  
  17.         return temp;  
  18.     }  
  19. };  
  20.   
  21. Point p1, p2, p3, pc, pp;  
  22. double r;  
  23.   
  24. Point get_pc1(Point p1, Point p2, Point p3)  //求圆心  
  25. {  
  26.     double a, b, c, d, e, f;  
  27.     Point p;  
  28.     a = 2*(p2.x-p1.x);  
  29.     b = 2*(p2.y-p1.y);  
  30.     c = p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;  
  31.     d = 2*(p3.x-p2.x);  
  32.     e = 2*(p3.y-p2.y);  
  33.     f = p3.x*p3.x+p3.y*p3.y-p2.x*p2.x-p2.y*p2.y;  
  34.     p.x = (b*f-e*c)/(b*d-e*a);  
  35.     p.y = (d*c-a*f)/(b*d-e*a);  
  36.     r = sqrt((p.x-p1.x)*(p.x-p1.x)+(p.y-p1.y)*(p.y-p1.y));//半径  
  37.     return p;  
  38. }  
  39. double dis(Point a,Point b)  
  40. {  
  41.     return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));  
  42. }  
  43. double mult_cha(Point p1,Point p2)   //叉积  
  44. {  
  45.     return p1.x * p2.y - p2.x * p1.y;  
  46. }  
  47.   
  48. double get_ans(Point pc,Point pp,Point p1,Point p2,Point p3)  
  49. {  
  50.     double temp = mult_cha(p2-p1,p3-p1);//判断给点方向是顺时针还是逆时针  
  51.     double f1 = atan2((p1-pc).y,(p1-pc).x);//和x正半轴的夹角  
  52.     double f2 = atan2((p2-pc).y,(p2-pc).x);  
  53.     double f3 = atan2((p3-pc).y,(p3-pc).x);  
  54.     double f4 = atan2((pp-pc).y,(pp-pc).x);  
  55.   
  56.     double ans1 = fabs(dis(pp,pc) - r);//到圆心减去半径  
  57.     double ans2 = min(dis(pp,p1),dis(pp,p3));//取到端点的较小值  
  58.   
  59.     if(temp < 0)    //顺时针给点  
  60.     {  
  61.         if(f1 < f3) //判断区间方向,向下凹  
  62.         {  
  63.             if((f2 >= f1 && f2 <= f3) == (f4 >= f1 && f4 <= f3) )//p点和p2点在同一个区间  
  64.                 return ans1;  
  65.             else                        //p点和p2点不在同一个区间  
  66.                 return ans2;  
  67.         }  
  68.         else//向上凸  
  69.         {  
  70.             if((f2 >= f3 && f2 <= f1) == (f4 >=f3 && f4 <= f1) )  
  71.                 return ans1;  
  72.             else  
  73.                 return ans2;  
  74.         }  
  75.     }  
  76.     else  
  77.     {  
  78.         if(f1 > f3)  
  79.         {  
  80.             if((f2 <= f1 && f2 >= f3) == (f4 <= f1 && f4 >= f3) )  
  81.                 return ans1;  
  82.             else  
  83.                 return ans2;  
  84.         }  
  85.         else  
  86.         {  
  87.             if((f2 <= f3 && f2 >= f1) == (f4 <= f3 && f4 >= f1) )  
  88.                 return ans1;  
  89.             else  
  90.                 return ans2;  
  91.         }  
  92.     }  
  93. }  
  94.   
  95. int main()  
  96. {  
  97.     int cas = 0;  
  98.     while(~scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y,&p3.x,&p3.y,&pp.x,&pp.y))  
  99.     {  
  100.         pc = get_pc1(p1,p2,p3);//圆心  
  101.         double ans = get_ans(pc,pp,p1,p2,p3);  
  102.   
  103.         printf("Case %d: %.3lf\n",++cas,ans);  
  104.     }  
  105.     return 0;  
  106. }  
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/T_ravelers/article/details/51312639

智能推荐

第14课:郭盛华课程_VB编程之如何操作文件_郭盛华的博客-程序员秘密

主讲老师:郭盛华文件操作:在一个应用程序中,对文件的处理是一个比较常用的操作,如打开文件、保存文件,等等。Visual Basic 提供了三个控件对磁盘文件夹与文件进行显示与操作,它们分别是:DriveListBox(磁盘列表框)控件、DirListBox(文件夹列表框)控件,以及 FileListBox(文件列表框)控件。如图一:一、DriveListBo...

NYU AI作业习题-活动安排问题 BFS+DFS Iterative deepening depth-first search_LarryNLPIR的博客-程序员秘密

题目链接  http://cs.nyu.edu/courses/spring12/CSCI-GA.2560-001/prog1.html题目大意:给定n个任务的时间、价值及先后序关系,求一个可行的任务子集,使得时间之和不大于deadline,价值之和不小于targetVaule,且不可出现逆序。算法思路:题目已经给出算法,转化为状态空间搜索问题(tree-structured state

[读史思考]为何此大神可以同时进入文庙和武庙?_罗西的思考的博客-程序员秘密

带着孩子学历史,突然发现一个神人:杜预。为何神奇?因为杜预是明朝之前唯一一个同时进入文庙和武庙的历史人物。于是查找资料,想知道他为何可以同时入选,遂有此文章和大家共享,文末有专门针对程序员的借鉴之处。

Navicat for MySQL 1130 - Host 'DeskTop-**' is not allowed to connect to this MySQL-server_一博是我的的博客-程序员秘密

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' INDENTIFIED BY 'abc' WITH GRANT OPTION;意思是所有用户名为root,密码为abc的用户都可以连接navicat接下来刷新权限flush privileges;即可连接成功...

《征信业务管理办法》发布_M13601260375的博客-程序员秘密

为贯彻落实党中央、国务院关于征信业规范发展的决策部署,推进征信法治建设,践行“征信为民”理念,加强个人信息保护,中国人民银行发布《征信业务管理办法》,自2022年1月1日起施行。《征信业务管理办法》是《征信业管理条例》的配套制度,与《征信机构管理办法》共同构成征信法治体系的重要组成部分,对依法从严加强征信监管,保障信息主体合法权益和信息安全,促进征信业市场化、法治化和科技化发展具有积极意义。《征信业管理条例》实施以来,中国人民银行推动国家金融信用信息基础数据库不断完善服务功能,取得突破性进展,在防范金融

JMeter 动态参数请求_jmeter请求参数怎么动态_SilenceXSJ的博客-程序员秘密

JMeter 动态参数请求添加执行任务设置全局参数设置cookice添加http请求可设置 请求头信息 请求方式 数据传输方式 等使用 BeanShell PreProcessor 前置处理参数可添加 察看结果树 或者 图形结果 等观察JMeter 动态参数请求添加执行任务设置全局参数设置tonken data 等自定义变量设置cookice如果要测试要登陆的网站 , 可以先

随便推点

多媒体通信中内容分发网络技术分析_w网络结构分布对内容分发性能_leiruo_han的博客-程序员秘密

 内容分发网络(Content Distribution Network,CDN)是建立在内容分发技术上的网络架构和整体系统。内容分发技术是在流量管理、负载均衡和分布式技术基础上发展的一种分发缓存(Cache)技术,采用将缓存服务器放置于Internet的边缘节点处,通过负载均衡等算法实现资源的就近分配和就近访问原则,能达到对多媒体信息快速响应的目的。本文着重阐述内容分发网络的工作原理。  一

C#实现网卡IP地址自由切换_c# 修改有线网卡ip参数_Luckeryin的博客-程序员秘密

需求:笔记本经常要在不同的地点连接网络,而各地的网络IP配置各不相同,这就导致不时的更改网卡的IP地址设置。Windows上更改IP设置很不方便,于是希望能够开发一款能够适用于不同网络,不同网卡的快速IP地址切换程序。分析:关键在于如何实现对网络适配器的配置。其实,MS为我们提供了System.Management 命名空间下的ManagementClass类,通过它我们可以获取和设置电脑上所

Arduino蓝牙模块实验(HC-42)_Z·y001的博客-程序员秘密

一、目的:用手机连接蓝牙模块,并传输数据给Arduino板,进而控制led灯的开关。二、主要材料:蓝牙模块(HC-42)、Arduino板、led灯、电脑、手机蓝牙模块(HC42)简介:HC42 蓝牙串口通信模块是新一代的基于 Bluetooth Specification V5.0 BLE 蓝牙协议 的数传模块。无线工作频段为 2.4GHz ISM,调制方式是 GFSK。模块最大发射功率为 4dBm, 接收灵敏度-96dBm。参数:该蓝牙的默认波特率为9600.

C#相关概念(ArrayList,List,LinkedList,Dictionary、委托和事件、接口和抽象类)_c# 2.0 arraylist 委托查询_EngZegNgi的博客-程序员秘密

在平时的项目中,许多东西都是用到了才看,甚至是只用不看。对下面几个知识点进行总结,加深自己对C#的理解。1.Array,ArrayList,List,LinkedList,Queue,Stack,Dictionary(1)Array最常用的数据结构,顺序存储相同数据类型的内容,可以通过下标O(1)进行访问。数组定义使用需要显示指定数组长度,不能更改。一般定义为:int[

Python 连接Mysql数据库并创建数据表、插入数据_sql_createtb_南洲.的博客-程序员秘密

Python 连接本地数据库并创建数据表、插入数据,亦可访问远程数据库远程访问指定IP上的数据库建立连接代码为:db = pymysql.connect(“10.180.8.33”,“root”,“root123”, “picdetectdb”)#-*-coding: UTF-8 -*-import pymysqldb = pymysql.connect("localhost", "r...

windows下Qt使用fopen函数无法打开中文名文件_juelianhuayao的博客-程序员秘密

有个功能需要实现win下Qt将文件上传到服务器,文件有可能会带有中文,在linux下Qt编写测试demo时没有遇到任何问题,能顺利使用fopen打开中文文件,但是将代码移植到win下后发现使用fopen打开中文文件一直失败,参考了如下资料终于解决了问题:资料链接bool UTF8ToUnicode(const char* UTF8, wchar_t* strUnicode){ DWORD...

推荐文章

热门文章

相关标签