UVa12304(计算几何中圆的基本操作)
断断续续写了250多行的模拟,其间被其他事情打扰,总共花了一天才AC吧~
这道题目再次让我明白,有些事情看起来很难,实际上并没有我们想象中的那么难。当然了我主要指的不是这个题的难度……
也是初学计算几何,然后居然胆大妄为地不用刘汝佳的思路去实现这些个功能,其中有三个功能是我用自己的思路实现的吧(瞎暴力),最后果然也是自己写的出锅了。
当一个贼长的模拟题交上去一发WA时,我是欲哭无泪的……这让我怎么debug……只好不断安慰自己要用计算几何题去练习耐心。
只是没想到在不断的固执与冷静的试探之下,不到一个晚上就成功了,当然了,对拍拍出来的呗……
我的主要错误在于在我自己的实现思路里,旋转向量时应该顺时针还是逆时针是取决于输入的,而我粗暴地“一视同仁”了。还好后来发现不难改,加个正负1去control就好了~
自己的辣鸡代码贴一贴留着自己看,难得写这么长:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct Point 5 { 6 double x, y; 7 Point(double a = 0, double b = 0):x(a), y(b){ } 8 }; 9 typedef Point Vector; 10 11 const double PI = acos(-1.0); 12 int dcmp(double x) 13 { 14 if (fabs(x) < 1e-6) return 0; 15 else return x < 0 ? -1 : 1; 16 } 17 Vector operator + (const Point &A, const Point &B) { return Vector(A.x + B.x, A.y + B.y); } 18 Vector operator - (const Point &A, const Point &B) { return Vector(A.x - B.x, A.y - B.y); } 19 Vector operator * (const Point &A, double p) { return Vector(A.x * p, A.y * p); } 20 Vector operator / (const Point &A, double p) { return Vector(A.x / p, A.y / p); } 21 bool operator < (const Point &A, const Point &B) { return dcmp(A.x - B.x) < 0 || (dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) < 0); } 22 bool operator == (const Point &A, const Point &B) { return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0; } 23 24 double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; } 25 double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; } 26 double Length(Vector A) { return sqrt(Dot(A, A)); } 27 double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } 28 Vector Normal(Vector A) { double L = Length(A); return Vector(-A.y / L, A.x / L); } 29 Vector Rotate(Vector A, double rad) { return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad)); } 30 31 Point Get_Line_Intersect(Point P, Vector v, Point Q, Vector w) 32 { 33 Point u = P - Q; 34 double t = Cross(w, u) / Cross(v, w); 35 return P + v*t; 36 } 37 38 double Distance_to_Line(Point P, Point A, Point B) 39 { 40 Vector v1 = P - A, v2 = B - A; 41 return fabs(Cross(v1, v2) / Length(v2)); 42 } 43 44 struct Circle 45 { 46 Point c; 47 double r; 48 // Circle(Point a = (0, 0), double x = 0):c(a), r(x){} 49 Point point(double seta) { return Point(c.x + cos(seta)*r, c.y + sin(seta)*r); } 50 }; 51 52 struct Line 53 { 54 Point p; 55 Vector v; 56 Line(Point p, Vector v):p(p), v(v) { } 57 58 Point point(double t) { return p + v*t; } 59 Line move(double d) { return Line(p + Normal(v)*d, v); } 60 }; 61 62 double formattedAngle(Vector A) 63 { 64 double a = atan2(A.y, A.x) / PI * 180; 65 if (dcmp(a) < 0) a += 180; 66 if (dcmp(a - 180) >= 0) a -= 180; 67 return a; 68 } 69 70 int getTangents(Point P, Circle C, vector<double> &v) 71 { 72 Vector u = C.c - P; 73 double d = Length(u); 74 75 if (dcmp(d - C.r) < 0) return 0; 76 else if (dcmp(d - C.r) == 0) 77 { 78 v.push_back(formattedAngle(Rotate(u, PI/2))); 79 return 1; 80 } 81 else 82 { 83 double a = asin(C.r / d); 84 v.push_back(formattedAngle(Rotate(u, a))); 85 v.push_back(formattedAngle(Rotate(u, -a))); 86 return 2; 87 } 88 } 89 90 void get_Line_Circle_Intersection(Line L, Circle C, vector<Point> &ans) 91 { 92 double t1, t2; 93 double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y; 94 double e = a*a + c*c, f = 2*(a*b + c*d), g = b*b + d*d - C.r*C.r; 95 double delta = f*f - 4*e*g; 96 97 if (dcmp(delta) < 0) return; 98 else if (dcmp(delta) == 0) 99 { 100 t1 = t2 = -f/2/e; 101 ans.push_back(L.point(t1)); 102 } 103 else 104 { 105 t1 = (-f + sqrt(delta)) / 2 / e; 106 t2 = (-f - sqrt(delta)) / 2 / e; 107 ans.push_back(L.point(t1)), ans.push_back(L.point(t2)); 108 } 109 } 110 111 inline double angle(Vector A) { return atan2(A.y, A.x); } 112 113 int get_Circle_Circle_Intersection(Circle C1, Circle C2, vector<Point> &v) 114 { 115 double d = Length(C1.c - C2.c); 116 if (dcmp(d) == 0) 117 { 118 if (dcmp(C1.r - C2.r) == 0) return -1; 119 return 0; 120 } 121 if (dcmp(C1.r + C2.r - d) < 0) return 0; 122 if (dcmp(fabs(C1.r - C2.r) - d) > 0) return 0; 123 124 double a = angle(C2.c - C1.c); 125 double da = acos((C1.r*C1.r + d*d - C2.r*C2.r) / (2*C1.r*d)); 126 Point p1 = C1.point(a - da), p2 = C1.point(a + da); 127 128 v.push_back(p1); 129 if (p1 == p2) return 1; 130 v.push_back(p2); 131 return 2; 132 } 133 134 void CircumscribedCircle() 135 { 136 Point P[3]; 137 for (int i = 0; i < 3; i++) scanf("%lf%lf", &P[i].x, &P[i].y); 138 139 Point c = Get_Line_Intersect((P[0] + P[1])/2, Rotate(P[1] - P[0], PI/2), (P[2] + P[0])/2, Rotate(P[2] - P[0], -PI/2)); 140 141 printf("(%.6lf,%.6lf,%.6lf)\n", c.x, c.y, Length(c - P[0])); 142 } 143 144 void InscribedCircle() 145 { 146 Point P[3]; 147 for (int i = 0; i < 3; i++) scanf("%lf%lf", &P[i].x, &P[i].y); 148 149 Vector v1 = Rotate(P[1] - P[0], (Cross(P[2] - P[0], P[1] - P[0]) > 0 ? -1 : 1) * Angle(P[1]-P[0], P[2]-P[0]) / 2); 150 Vector v2 = Rotate(P[0] - P[1], (Cross(P[2] - P[1], P[0] - P[1]) > 0 ? -1 : 1) * Angle(P[0]-P[1], P[2]-P[1]) / 2); 151 Point c = Get_Line_Intersect(P[0], v1, P[1], v2); 152 153 printf("(%.6lf,%.6lf,%.6lf)\n", c.x, c.y, Distance_to_Line(c, P[0], P[1])); 154 } 155 156 void TangentLineThroughPoint() 157 { 158 Circle C; 159 Point P; 160 vector<double> v; 161 scanf("%lf%lf%lf", &C.c.x, &C.c.y, &C.r); 162 scanf("%lf%lf", &P.x, &P.y); 163 164 printf("["); 165 if (getTangents(P, C, v)) sort(v.begin(), v.end()), printf("%.6lf", v[0]); 166 if (v.size() == 2) printf(",%.6lf", v[1]); 167 printf("]\n"); 168 } 169 170 void CircleThroughAPointAndTangentToALineWithRadius() 171 { 172 Circle P; 173 Point A, B; 174 scanf("%lf%lf%lf%lf%lf%lf%lf", &P.c.x, &P.c.y, &A.x, &A.y, &B.x, &B.y, &P.r); 175 176 Line original(A, B - A); 177 vector<Point> v; 178 get_Line_Circle_Intersection(original.move(P.r), P, v); 179 get_Line_Circle_Intersection(original.move(-P.r), P, v); 180 sort(v.begin(), v.end()); 181 182 printf("["); 183 if (v.size()) printf("(%.6lf,%.6lf)", v[0].x, v[0].y); 184 for (int i = 1; i < v.size(); i++) printf(",(%.6lf,%.6lf)", v[i].x, v[i].y); 185 printf("]\n"); 186 } 187 188 inline Point e_to_go(Vector A, double len) { return A / Length(A) * len; } 189 190 void CircleTangentToTwoLinesWithRadius() 191 { 192 Point A, B, C ,D; 193 double r; 194 scanf("%lf%lf %lf%lf %lf%lf %lf%lf %lf", &A.x, &A.y, &B.x, &B.y, &C.x, &C.y, &D.x, &D.y, &r); 195 196 vector<Point> v; 197 int control = Cross(B - A, D - C) < 0 ? -1 : 1; 198 199 Point P = Get_Line_Intersect(A, B-A, C, D-C); 200 double seta = Angle(B - A, D - C)/2; 201 Vector v1 = Rotate(B - A, control*seta); 202 Vector v2 = Rotate(B - A, -control*(PI/2 - seta)); 203 204 v.push_back(P + e_to_go(v1, r/sin(seta))); 205 v.push_back(P - e_to_go(v1, r/sin(seta))); 206 v.push_back(P + e_to_go(v2, r/cos(seta))); 207 v.push_back(P - e_to_go(v2, r/cos(seta))); 208 sort(v.begin(), v.end()); 209 210 for (int i = 0; i < v.size(); i++) 211 printf("%c(%.6lf,%.6lf)", ",["[i == 0], v[i].x, v[i].y); 212 printf("]\n"); 213 } 214 215 void CircleTangentToTwoDisjointCirclesWithRadius() 216 { 217 Circle C1, C2; 218 double r; 219 scanf("%lf%lf%lf %lf%lf%lf %lf", &C1.c.x, &C1.c.y, &C1.r, &C2.c.x, &C2.c.y, &C2.r, &r); 220 C1.r += r, C2.r += r; 221 vector<Point> v; 222 get_Circle_Circle_Intersection(C1, C2, v); 223 sort(v.begin(), v.end()); 224 225 if (!v.size()) printf("["); 226 for (int i = 0; i < v.size(); i++) 227 printf("%c(%.6lf,%.6lf)", ",["[i == 0], v[i].x, v[i].y); 228 printf("]\n"); 229 } 230 231 int main() 232 { 233 string s; 234 while (cin >> s) 235 { 236 if (s.length() < 19) InscribedCircle(); 237 else 238 { 239 switch(s[18]) 240 { 241 case 'e': 242 CircumscribedCircle(); break; 243 case 'P': 244 TangentLineThroughPoint(); break; 245 case 't': 246 CircleThroughAPointAndTangentToALineWithRadius(); break; 247 case 'L': 248 CircleTangentToTwoLinesWithRadius(); break; 249 case 'D': 250 CircleTangentToTwoDisjointCirclesWithRadius(); break; 251 default : break; 252 } 253 } 254 } 255 return 0; 256 }
View Code
转载于:https://www.cnblogs.com/AlphaWA/p/10200931.html
UVa12304(计算几何中圆的基本操作)相关推荐
- C语言中文件的基本操作函数fprintf和fscanf实例介绍
C语言文章更新目录 C/C++学习资源(百度云盘链接) 计算机二级资料(过级专用) C语言学习路线(从入门到实战) 编写C语言程序的7个步骤和编程机制 C语言基础-第一个C程序 C语言基础-简单程序分 ...
- matlab中的图像,MATLAB中图像的基本操作
MATLAB中图像的基本操作 1.读取.显示图片 MATLAB中提供了immread()与imshow()函数读取和显示图片.其中读取函数imread()原型: imread: A= imread(f ...
- python连接mongodb进行查询_Python中的MongoDB基本操作:连接、查询实例
MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可护展的高性能数据存储解决方案.它的特点是高性能.易部署.易使用,存储数据非常方便. MongoDB 简单使用 联 ...
- MySQL学习笔记03【数据库表的CRUD操作、数据库表中记录的基本操作、客户端图形化界面工具SQLyog】
MySQL 文档-黑马程序员(腾讯微云):https://share.weiyun.com/RaCdIwas 1-MySQL基础.pdf.2-MySQL约束与设计.pdf.3-MySQL多表查询与事务 ...
- Java黑皮书课后题第8章:*8.34(几何:最右下角的点)在计算几何中经常需要从一个点集中找到最右下角的点。编写一个测试程序,提示用户输入6个点的坐标,然后显示最右下角的点
*8.34(几何:最右下角的点)在计算几何中经常需要从一个点集中找到最右下角的点.编写一个测试程序,提示用户输入6个点的坐标,然后显示最右下角的点 题目 题目描述与运行示例 破题 代码 题目 题目描述 ...
- arcgis mxt模板 创建工具条无法保存_【从零开始学GIS】ArcGIS中的绘图基本操作(二)...
大家好,我是肝教程肝到熊猫眼的三三. 本系列教程的发布,受到了很多同学的鼓励,大家在后台或微信上表达出对教程的喜爱,这便是更新教程的最大动力. 上回教程讲解了"GIS基本操作".& ...
- oracle的一些基本操作,Oracle中的一些基本操作
关于Oracle中的一些基本操作,包括表空间操作,用户操作,表操作 1 --创建表空间 2 create tablespace itheima 3 datafile 'I:\oracle\table\ ...
- 三维空间中圆的参数方程及matlab程序画图
原文链接: 三维空间中圆的参数方程 三维空间中,以点为圆心.以向量为法向量.半径为 r 的圆(见下图), 它的参数方程为: 其中,与分别对应单位向量与,它们既垂直于,又互相垂直:随着从0变化到 ,通过 ...
- c/c++中字符串的基本操作API
c/c++中字符串的基本操作API 首先我们来认识几个#include <string.h>头文件中的API函数 strlen(const char *_Str) /*获取除了'\0'以外 ...
- 使用html制作圆弧正方形,JavaScript+html5 canvas制作的圆中圆效果实例
本文实例讲述了JavaScript+html5 canvas制作的圆中圆效果.分享给大家供大家参考,具体如下: 运行效果截图如下: 具体代码如下: demo #canvas { background: ...
最新文章
- android 常用小功能(第二版)
- mysql 查看版本
- Maven的pom文件那些事
- Android --- 微信支付时出现错误:错误的签名,验签失败,return_code=FAIL
- pytorch torch.nn.Sequential(* args)(嘎哈用的?构建神经网络用的?)
- mysql重置auto_increment字段
- Javascript 浏览器探测
- 科幻作家阿西莫夫上世纪预言2019: 计算机彻底变革教育,太空移民进行中
- 赛题解析|初赛赛道三:服务网格控制面分治体系构建
- 一些关于网页标题的动态js特效
- 车辆行人识别训练与部署,EasyDL-Jetson Nano 端边云协作专场公开课
- Linux软件包安装和卸载
- Algorithm:贪心策略之区间覆盖问题
- py脚本实现用例执行html报告,pytest文档7-pytest-html生成html报告
- [转载]Oracle监听器安装与设置(2)
- VS C++ 重新编译
- Atitit.ide代码块折叠插件 eclipse
- C语言编程题:(C语言)分糖果 通俗易懂
- Rhadoop集群搭建
- EasyClick 易点云测
热门文章
- That's why you go away
- Caused by: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found
- 计算机电子表格课程导入,又到了每年此刻,教你把课程表导入日历
- 关于Eclipse4.7安装TomcatPlugin后无法显示三只猫问题
- 第9章 Linux的磁盘管理
- SQL Server2005,win8、win10系统安装教程,你急需的都在这里!
- 解决eWebEditor上传图片提示:请选择一个有效的文件,支持的格式有(GIF|JPG|JPEG|BMP|PNG)!
- html文件做屏保win10,给Win10系统设置一个漂亮屏保的三种方法(图文)
- postman测试图片上传接口一直失败的解决办法
- Jmeter进行上传图片接口测试