题目地址:https://vjudge.net/problem/UVA-12304

题目:


看这里:https://uva.onlinejudge.org/external/123/12304.pdf

解题思路:


紫书P267-P269将的很清楚了,新的知识点是直线平移的求法:

直线,v是方向向量

1.求出单位法向量normal

Point Verunit(Point a) //单位法向量
{return Point(-a.y, a.x) / Length(a);
}
Point normal = Verunit(v);

2.借助单位法向量和平移距离d求出直线

new_line = Line(p+normal*d, v)

其中p+noraml*d是p在平移后的直线对应的坐标p’

ac代码:


代码有点长,验板子题

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10;
const double eps = 1e-6;//eps用于控制精度,或者更高精度
const double  pi = acos(-1.0);//pi// 点
struct Point//点或向量
{double x, y;Point(double x = 0, double y = 0) :x(x), y(y) {}friend bool operator < (Point a, Point b){return a.x == b.x ? a.y < b.y : a.x < b.x;}
};
typedef Point Vector;
Vector operator + (Vector a, Vector b)//向量加法
{return Vector(a.x + b.x, a.y + b.y);
}
Vector operator - (Vector a, Vector b)//向量减法
{return Vector(a.x - b.x, a.y - b.y);
}
Vector operator * (Vector a, double p)//向量数乘
{return Vector(a.x * p, a.y * p);
}
Vector operator / (Vector a, double p)//向量数除
{return Vector(a.x / p, a.y / p);
}
int dcmp(double x)//精度三态函数(>0,<0,=0)
{if (fabs(x) < eps)return 0; //等于else return x < 0 ? -1 : 1;//小于,大于
}
bool operator == (const Point &a, const Point &b)//向量相等
{return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
//点的辅助函数
double Dot(Vector a, Vector b)//点积
{return a.x * b.x + a.y * b.y;
}
double Cross(Vector a, Vector b)//外积
{return a.x * b.y - a.y * b.x;
}
double Length(Vector a)//模
{return sqrt(Dot(a, a));
}
Vector Rotate(Vector a, double rad)//逆时针旋转rad弧度
{return Vector(a.x*cos(rad) - a.y*sin(rad), a.x*sin(rad) + a.y*cos(rad));
}
double Angle(Point a)//极角
{return atan2(a.y, a.x);
}
double RadToDegree(double rad)//弧度转角度
{return 180.0*rad/pi;
}
Point Verunit(Point a) //单位法向量
{return Point(-a.y, a.x) / Length(a);
}
double DistanceToLine(Point P, Point A, Point B)//点P到AB所在直线的距离
{Vector v1 = B - A, v2 = P - A;return fabs(Cross(v1, v2)) / Length(v1);
}struct Circle
{Point c;double r;Circle(Point c, double r):c(c),r(r){}Point point(double a)//基于圆心角求圆上一点坐标{return Point(c.x + cos(a)*r, c.y + sin(a)*r);}
};
struct Line{ // p+v*t t是变量Point p;Point v;//方向向量double ang;//斜率Line(Point _p, Point _v):p(_p),v(_v){ang = atan2(v.y, v.x);}Point point(double a) // 直线上某一点{return p+v*a;}friend bool operator < (Line a, Line b){return a.ang < b.ang;}
};//两圆交点
int getCirleCirleIntersection(Circle C1, Circle C2, vector<Point>& sol)//求两圆交点
{double d = Length(C1.c - C2.c);if (dcmp(d) == 0)//圆心重合{if (dcmp(C1.r - C2.r) == 0) return -1;//重合else return 0;}if (dcmp(C1.r + C2.r - d) < 0) return 0;//相离if (dcmp(fabs(C1.r - C2.r) - d) > 0) return 0; //内含,圆心不重合double a = Angle(C2.c - C1.c);double da = acos((C1.r*C1.r + d * d - C2.r*C2.r) / (2 * C1.r*d));Point p1 = C1.point(a - da), p2 = C1.point(a + da);sol.push_back(p1);if (p1 == p2)return 1;sol.push_back(p2);return 2;
}
// 直线交点,P,方向向量v
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w)
{Vector u = P - Q;//QPdouble t = Cross(w, u) / Cross(v, w);return P + v * t;
}
//直线和圆的交点
int getLineCircleIntersection(Line L, Circle C, double& t1, double& t2, vector<Point>& sol)
{double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;double e = a*a + c*c, f = 2*(a*b + c*d), g = b*b + d*d -C.r*C.r;double delta = f*f - 4*e*g;//判别式if(dcmp(delta) < 0) return 0;//相离if(dcmp(delta) == 0){t1 = t2 = -f / (2*e);sol.push_back(L.point(t1));return 1;//相切}t1 = (-f - sqrt(delta)) / (2*e); sol.push_back(L.point(t1));t2 = (-f + sqrt(delta)) / (2*e); sol.push_back(L.point(t2));return 2;
}
//外接圆
Circle CircumscribedCircle(Point p1, Point p2, Point p3)
{double Bx = p2.x-p1.x, By = p2.y-p1.y;double Cx = p3.x-p1.x, Cy = p3.y-p1.y;double D = 2*(Bx*Cy-By*Cx);double cx = (Cy*(Bx*Bx+By*By) - By*(Cx*Cx+Cy*Cy))/D + p1.x;double cy = (Bx*(Cx*Cx+Cy*Cy) - Cx*(Bx*Bx+By*By))/D + p1.y;Point p = Point(cx, cy);return Circle(p, Length(p1-p));
}
//内切圆
Circle InscribedCircle(Point p1, Point p2, Point p3)
{double a = Length(p2-p3);double b = Length(p3-p1);double c = Length(p1-p2);Point p = (p1*a+p2*b+p3*c) / (a+b+c);return Circle(p, DistanceToLine(p, p1, p2));
}
//过定点做圆的切线, 返回切点个数,v中存切点
int TangentLineThroughPoint(Point p, Circle C, Vector* v)
{Vector u = C.c - p;double dist = Length(u);if(dist < C.r) return 0;//insideelse if(dcmp(dist - C.r) == 0)//on the circle{v[0] = Rotate(u, pi/2);return 1;}else //outside{double ang = asin(C.r / dist);v[0] = Rotate(u, -ang);v[1] = Rotate(u, ang);return 2;}
}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);char op[200];double a[20];Point v[10];//存直线和圆的切点double degree[10];//存极角vector<Point> sol;//存坐标while(~scanf("%s", op)){if(strcmp(op, "CircumscribedCircle") == 0){for(int i = 1; i <= 6; i++) scanf("%lf", &a[i]);Circle C = CircumscribedCircle(Point(a[1], a[2]), Point(a[3], a[4]), Point(a[5], a[6]));printf("(%.6lf,%.6lf,%.6lf)\n", C.c.x, C.c.y, C.r);}else if(strcmp(op, "InscribedCircle") == 0){for(int i = 1; i <= 6; i++) scanf("%lf", &a[i]);Circle C = InscribedCircle(Point(a[1], a[2]), Point(a[3], a[4]), Point(a[5], a[6]));printf("(%.6lf,%.6lf,%.6lf)\n", C.c.x, C.c.y, C.r);}else if(strcmp(op, "TangentLineThroughPoint") == 0){for(int i = 1; i <= 5; i++) scanf("%lf", &a[i]);int num = TangentLineThroughPoint(Point(a[4], a[5]), Circle(Point(a[1], a[2]), a[3]), v);if(!num){printf("[]\n");continue;}for(int i = 0; i < num; i++){double de = RadToDegree(Angle(v[i]));//极角可能是负的,不符合条件的情况:de<0,de>=180if(dcmp(de) < 0) de = 180.0 + de; // de < 0else while(dcmp(de-180.0) >= 0) de -= 180.0; // de >= 180degree[i] = de;}sort(degree, degree+num);printf("[");for(int i = 0; i < num; i++){if(i) printf(",");printf("%.6lf", degree[i]);}printf("]\n");}else if(strcmp(op, "CircleThroughAPointAndTangentToALineWithRadius") == 0){for(int i = 1; i <= 7; i++) scanf("%lf", &a[i]);Point A = Point(a[3], a[4]), B = Point(a[5], a[6]);Circle C = Circle(Point(a[1], a[2]), a[7]);Point normal = Verunit(B-A) * a[7];//获得和BA这条直线平行且距离为r的直线Line l1 = Line(A+normal, B-A), l2 = Line(A-normal, B-A);//转化为两直线和圆的交点sol.clear();double t1 = -1,t2 = -1;//两交点的极角getLineCircleIntersection(l1,C,t1,t2,sol);getLineCircleIntersection(l2,C,t1,t2,sol);sort(sol.begin(), sol.end());printf("[");for(int i = 0; i < sol.size(); i++){if(i) printf(",");printf("(%.6lf,%.6lf)", sol[i].x, sol[i].y);}printf("]\n");}else if(strcmp(op, "CircleTangentToTwoLinesWithRadius") == 0){for(int i = 1; i <= 9; i++) scanf("%lf", &a[i]);Point A = Point(a[1],a[2]), B = Point(a[3],a[4]);Point C = Point(a[5],a[6]), D = Point(a[7], a[8]);Point normal1 = Verunit(B-A) * a[9];Point normal2 = Verunit(D-C) * a[9];//转化为求两两直线交点,已经保证必有交点sol.clear();sol.push_back(GetLineIntersection(A+normal1, B-A, C+normal2, D-C));sol.push_back(GetLineIntersection(A+normal1, B-A, C-normal2, D-C));sol.push_back(GetLineIntersection(A-normal1, B-A, C+normal2, D-C));sol.push_back(GetLineIntersection(A-normal1, B-A, C-normal2, D-C));sort(sol.begin(), sol.end());printf("[");for(int i = 0; i < sol.size(); i++){if(i) printf(",");printf("(%.6lf,%.6lf)",sol[i].x, sol[i].y);}printf("]\n");}else if(strcmp(op, "CircleTangentToTwoDisjointCirclesWithRadius") == 0){for(int i = 1; i <= 7; i++) scanf("%lf", &a[i]);Circle c1 = Circle(Point(a[1],a[2]),a[3]+a[7]);Circle c2 = Circle(Point(a[4],a[5]),a[6]+a[7]);//转化为两圆交点sol.clear();getCirleCirleIntersection(c1, c2, sol);sort(sol.begin(), sol.end());printf("[");for(int i = 0; i < sol.size(); i++){if(i) printf(",");printf("(%.6lf,%.6lf)",sol[i].x, sol[i].y);}printf("]\n");}}return 0;
}
/**
output:
(9.734940,5.801205,11.332389)
(9.113006,6.107686,5.644984)
[53.977231,160.730818]
[0.000000]
[]
[(112.047575,299.271627),(199.997744,199.328253)]
[(-0.071352,123.937211),(150.071352,256.062789)]
[(100.000000,200.000000)]
[]
[(72.231286,121.451368),(87.815122,63.011983),(128.242785,144.270867),(143.826621,85.831483)]
[(157.131525,134.836744),(194.943947,202.899105)]
[(204.000000,178.000000)]*/

【UVA12304】2D Geometry 110 in 1!(外接圆/内切圆/切点等圆相关问题的模版题)相关推荐

  1. LA 3263 That Nice Euler Circuit (2D Geometry)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  2. 三角形面积外接圆内切圆

    三角形面积 4 * area = sqrt((a + b + c) * (a + b - c) * (a + c - b) * (b + c - a)) OR (海伦公式) s = (a +b + c ...

  3. 第7期:计算几何(持续更新中......)

    // 2022/01/22更新 更新内容主要为算法竞赛入门经典--训练指南(升级版)(刘汝佳.陈锋编著)第4章几何问题 1 二维几何基础 在平面坐标系下,向量和点一样,也用两个数x,y表示.第6章介绍 ...

  4. 编程挑战之三角形的内切圆与外接圆

    一个三角形必然存在它的内接圆与外切圆,求他们的面积比.考虑到精度问题,我们输出面积比*1000的整数部分(直接下取整). 输入数据是一个三角形的三个顶点,但这三个顶点在三维空间中,所以输入是9个整数, ...

  5. 三点外接圆_故地重游伪切圆——伪外接圆的基本性质

    在思考一个有关于伪外接圆的等角线问题时,我回想起伪外接圆的一道小题目,这是2012年罗马尼亚大师杯的第六题,这道题目直接以结论的形式呈现出了伪外接圆的基本性质,是一道入门伪外接圆必做的精巧小题. 当然 ...

  6. java geometry mysql_Java Geometry空间几何数据的处理应用

    先了解几个基本概念,有助于了解本文应用场景 地理信息系统GIS-百度百科 地理信息系统(Geographic Information System或 Geo-Information system,GI ...

  7. 【STM32H7教程】第51章 STM32H7的LTDC应用之LCD汉字显示和2D图形显示

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第51章       STM32H7的LTDC应用之LCD汉字 ...

  8. 1、DirectX 系列之 Direct 2D

    Direct 2D是一个 采用立即模式 绘图的2D 图形API,也就是跟显卡驱动打交道的一个小程序,图形业务能力包括 2-D geometry, bitmaps, and text. WM_Paint ...

  9. 【STM32F429开发板用户手册】第41章 STM32F429的LTDC应用之LCD汉字显示和2D图形显示

    最新教程下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93255 第41章       STM32F429的LTDC应用之LCD汉字 ...

  10. 2d的公式_西师大版六年级数学上册全册必背公式+高清版电子课文,收藏预习

    六年级数学上册必背公式 长度单位换算 1千米=1000米 1米=10分米 1分米=10厘米 1米=100厘米 1厘米=10毫米 面积单位换算 1平方千米=100公顷 1公顷=10000平方米 1平方米 ...

最新文章

  1. python eval 入门_Python学习笔记整理3之输入输出、python eval函数
  2. 将地址转换为链接的正则表达式(regex url href)
  3. OAF TABLE中添加序号列
  4. 常用命令之------tcpdump
  5. 太赞了!《Python知识手册》更新到v2.2版
  6. AtCoder Beginner Contest 131 F - Must Be Rectangular!
  7. anaconda对应python版本_Python基础——如何查看python版本、如何查看多个python版本
  8. php缩放库,php的缩放图像类使用
  9. python读取大文件csv_对python中大文件的导入与导出方法详解
  10. Android桌面组件开发之实时文件夹(Live_Folders)
  11. 带有第三方工具的Spring Boot Initilizr
  12. ARM DS-5 Flex网络许可证编译错误“Error: C9933W: Waiting for license...”
  13. python车流量检测车流统计车辆计数yolov5 deepsort车流检测
  14. 谷歌地球替代软件、谷歌街景、谷歌三维城市模型查看全方案
  15. 【唐老狮】Unity和UE4两大游戏引擎,你该如何选择?
  16. php业名人,名人榜
  17. win10计算机方差,标准差计算工具
  18. 史上最全的中高级JAVA工程师-面试题汇总
  19. Win7下使用VirtualBox虚拟机安装OS X 10.9 Mavericks
  20. cesium着色器学习系列2-Appearance对象

热门文章

  1. CIE Radar 2006(ICR2006)开始征文了
  2. mysql的模拟数据,员工的模拟数据,sql语句的应用,粘贴即用
  3. you need python_Life is short, you need Python!
  4. C# Parse and TryParse 方法详解
  5. Unity编辑器:自定义编辑器样式——GUIStyle
  6. 平安夜,Python 送你一顶圣诞帽 @微信官方
  7. 关于SQL\SQL Server的三值逻辑简析
  8. Logback 深入分析
  9. hibernate-annotation
  10. ASP.NET 2.0使用Web Part创建应用程序之一(共二)