UVa12304 2D Geometry 110 in 1!

题目链接

         UVa12304 2D Geometry 110 in 1!

题意

        这是一个拥有6(二进制是110)个子问题的2D几何问题集。
        1 CircumscribedCircle x1 y1 x2 y2 x3 y3:求三角形(x1,y1)-(x2,y2)-(x3,y3)的外接圆。这3点保证不共线。答案应格式化成(x,y,r),表示圆心为(x,y),半径为r。
        2、InscribedCircle x1 y1 x2 y2 x3 y3:求三角形(x1,y1)-(x2,y2)-(x3,y3)的内切圆。这3点保证不共线。答案应格式化成(x,y,r),表示圆心为(x,y),半径为r。
        3、TangentLineThroughPoint xc yc r xp yp:给定一个圆心在(xc,yc),半径为r 的圆,求过点(xp,yp)并且和这个圆相切的所有切线。每条切线格式化为angle,表示直线的极角(角度,0≤angle<180)。整个答案应格式化为列表(见后)。如果无解,应打印空列表。
        4、CircleThroughAPointAndTangentToALineWithRadius xp yp x1 y1 x2 y2 r:求出所有经过点(xp,yp)并且和直线(x1,y1)-(x2,y2)相切的半径为r 的圆。每个圆格式化为(x,y),因为半径已经给定。整个答案应格式化为列表(同上)。 
        5、CircleTangentToTwoLinesWithRadius x1 y1 x2 y2 x3 y3 x4 y4 r:给出两条不平行直线(x1,y1)-(x2,y2)和(x3,y3)-(x4,y4),求所有半径为r 并且同时和这两条直线相切的圆。每个圆格式化为(x,y),因为半径已经给定。整个答案应格式化为列表(同上)。
        6、CircleTangentToTwoDisjointCirclesWithRadius x1 y1 r1 x2 y2 r2 r:给定两个相离的圆(x1,y1,r1)和(x2,y2,r2),求出所有和这两个圆外切的,半径为r 的圆。注意,因为是外切,求出的圆不能把这两个给定圆包含在内部。每个圆格式化为(x,y),因为半径已经给定。整个答案应格式化为列表(同上)。
        对于上述所有直线,输入的两个点保证不重合。当格式化实数列表时,所有数应从小到大排列;当格式化二元组(x,y)时,先按x 从小到大排序,当x 相同时按y 从小到大排序。

分析

        第一个问题设外接圆的圆心坐标为x、y,半径为r,列方程组求解。

        第二个问题利用内心坐标公式求解:设\bigtriangleup ABC的顶点坐标分别为(x_{A},y_{A})(x_{B},y_{B})(x_{C},y_{C}),三个角对应的边长分别为a、b、c,则内心坐标为x=(a\cdot x_{A}+b\cdot x_{B}+c\cdot x_{C})/(a+b+c),y=(a\cdot y_{A}+b\cdot y_{B}+c\cdot y_{C})/(a+b+c)。求得内心坐标后再求一下它与三角形某条边的距离即可得到内切圆半径。

        第三个子问题切线格式化为极角要注意反三角函数的值域,最后一定要确保在[0,180)

       《训练指南》上讲第四、五、六个问题的解法:

        第四个问题:因为已知半径为r,所以要想和直线L相切,圆心到直线的距离一定为r。满足这个条件的点的轨迹是两条直线。而要想过定点,圆心点该点的距离一定为r,满足这个条件的点的轨迹是一个圆。求出圆和这两条直线的交点即可。

        第五个问题解法类似,根据每条直线得到两条新直线,再两两求交点即可。
        第六个问题解法也类似,根据两个圆得到两个新的圆,求交点即可。

        这里说一下第五、六两个问题的直接几何解法:

        第五个问题:求出两直线的交点P,以及pc与两条直线的夹角α,则\left | pc \right |=r/\sin \alpha,并且将某直线的方向向量旋转α角就得到pc的方向向量,由此算出一个C,pc的方向向量再依次旋转90度三下可以算出另外三个C点,要注意旋转90度和270度时pc长度变了(\left | pc \right |=r/\cos \alpha)。

        第六个问题:本质是求下图的C点坐标,借助余弦定理把∠ A求出,然后将AB的方向向量旋转∠ A就得到AC的方向向量,进而算出C点坐标。

AC代码

#include <iostream>
#include <cmath>
#include <iomanip>
#include <algorithm>
using namespace std;#define eps 1e-10
struct Point {double x, y;Point(double x = 0, double y = 0) : x(x), y(y) {}void Normalize() {double l = sqrt(x*x + y*y); x /= l; y /= l;}
};
typedef Point Vector;Vector operator+ (Vector A, Vector B) {return Vector(A.x + B.x, A.y + B.y);
}Vector operator- (Point A, Point 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);
}bool operator< (const Point& a, const Point& b) {return a.x < b.x || (a.x == b.x && a.y < b.y);
}int dcmp(double x) {return abs(x) < eps ? 0 : (x < 0 ? -1 : 1);
}double Dot(Vector A, Vector B) {return A.x * B.x + A.y * B.y;
}double Length(Vector A) {return sqrt(Dot(A, A));
}double Angle(Vector A, Vector B) {return acos(Dot(A, B) / Length(A) / Length(B));
}double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x;
}Vector Rotate(Vector A, double rad) {return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));
}Vector Normal(Vector A) {double L = Length(A);return Vector(-A.y / L, A.x / L);
}Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {Vector u = P - Q;double t = Cross(w, u) / Cross(v, w);return P + v * t;
}double DistanceToLine(Point P, Point A, Point B) {Vector v1 = B - A, v2 = P - A;return abs(Cross(v1, v2)) / Length(v1);
}void solveU() {double x1, y1, x2, y2, x3, y3; cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;double x = ((x1*x1+y1*y1)*(y2-y3) + (x2*x2+y2*y2)*(y3-y1) + (x3*x3+y3*y3)*(y1-y2)) /((y1-y3)*(x1-x2) - (y1-y2)*(x1-x3)) / 2;double y = ((x1*x1+y1*y1)*(x2-x3) + (x2*x2+y2*y2)*(x3-x1) + (x3*x3+y3*y3)*(x1-x2)) /((x1-x3)*(y1-y2) - (x1-x2)*(y1-y3)) / 2;cout << '(' << x << ',' << y << ',' << sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1)) << ')' << endl;
}void solveI() {Point p1, p2, p3; cin >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y;double a = Length(p2-p3), b = Length(p3-p1), c = Length(p1-p2); Point p = (p1*a+p2*b+p3*c)/(a+b+c);cout << '(' << p.x << ',' << p.y << ',' << DistanceToLine(p, p1, p2) << ')' << endl;
}void solveT() {int x, y, r, xp, yp; cin >> x >> y >> r >> xp >> yp;int d = (x-xp)*(x-xp) + (y-yp)*(y-yp) - r*r;if (d < 0.) {cout << "[]" << endl; return;} else if (d == 0) {double a = 180*atan2(yp-y, xp-x)/M_PI; a = a<0 ? a + 450 : a + 90;cout << '[' << (dcmp(a-360)>=0 ? a-360 : (dcmp(a-180)>=0 ? a-180 : a)) << ']' << endl; return;} else {double a = 180*atan2(yp-y, xp-x)/M_PI, b = 180*asin(r/sqrt((x-xp)*(x-xp) + (y-yp)*(y-yp)))/M_PI;if (a < 0) a += 360;double x = a + b, y = a<b ? 180+a-b : a-b;x = dcmp(x-360)>=0 ? x-360 : (dcmp(x-180)>=0 ? x-180 : x);y = dcmp(y-360)>=0 ? y-360 : (dcmp(y-180)>=0 ? y-180 : y);cout << '[' << min(x, y) << ',' << max(x, y) << ']' << endl;}
}void solveA() {int xp, yp, x1, y1, x2, y2, r; cin >> xp >> yp >> x1 >> y1 >> x2 >> y2 >> r;if ((xp-x1)*(yp-y2) == (xp-x2)*(yp-y1)) {double a = atan2(x2-x1, y1-y2);Point p1(xp + r*cos(a), yp + r*sin(a)), p2(xp - r*cos(a), yp - r*sin(a)), t;if (p2 < p1) t = p1, p1 = p2, p2 = t;cout << "[(" << p1.x << ',' << p1.y << "),(" << p2.x << "," << p2.y << ")]" << endl;} else {Point a(x1, y1), b(x2, y2); Vector v = Normal(Vector(x2-x1, y2-y1));double d = DistanceToLine(Point(xp, yp), a, b);Point p(xp + v.x * r, yp + v.y * r);if (d > 2*r) {cout << "[]" << endl;} else if (d == 2*r) {if (DistanceToLine(p, a, b) > 2*r) p.x = xp - v.x * r, p.y = yp - v.y * r;cout << "[(" << p.x << ',' << p.y << ")]" << endl;} else {double d1 = DistanceToLine(p, a, b);if ((d<r && dcmp(d1+d-r) == 0) || (d>r && dcmp(d1+r-d) == 0)) v.x = -v.x, v.y = -v.y;double a = atan2(v.y, v.x), b = acos((r-d)/r);Point p1(xp + r*cos(a+b), yp + r*sin(a+b)), p2(xp + r*cos(a-b), yp + r*sin(a-b)), t;if (p2 < p1) t = p1, p1 = p2, p2 = t;cout << "[(" << p1.x << ',' << p1.y << "),(" << p2.x << "," << p2.y << ")]" << endl;}}
}void solveL() {Point p1, p2, p3, p4; int r; cin >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y >> p4.x >> p4.y >> r;Vector v = p2-p1, w = p4-p3; Point p = GetLineIntersection(p1, v, p3, w); double a = Angle(v, w) / 2;v.Normalize(); v = Rotate(v, Cross(v, w) < 0. ? -a : a);double r1 = r / sin(a), r2 = r / cos(a);Point c[] = {Point(p.x + v.x*r1, p.y + v.y*r1), Point(p.x - v.x*r1, p.y - v.y*r1),Point(p.x - v.y*r2, p.y + v.x*r2), Point(p.x + v.y*r2, p.y - v.x*r2)};sort(c, c+4);cout << "[(" << c[0].x << ',' << c[0].y << "),(" << c[1].x << "," << c[1].y << "),("<< c[2].x << ',' << c[2].y << "),(" << c[3].x << "," << c[3].y << ")]" << endl;
}void solveD() {int x1, y1, r1, x2, y2, r2, r; cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2 >> r;double d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); Vector v(x2-x1, y2-y1); int cmp = dcmp(d - r1 - r2 - 2*r);if (cmp > 0 || (dcmp(d+min(r1,r2)-max(r1,r2)) < 0)) {cout << "[]" << endl;} else if (cmp == 0) {double t = (r1+r) / d;cout << "[(" << x1 + v.x * t << ',' << y1 + v.y * t << ")]" << endl;} else {double a = acos(((r+r1)*(r+r1) + d*d - (r+r2)*(r+r2)) / (r+r1) / d / 2);v.Normalize(); Vector w = Rotate(v, -a); v = Rotate(v, a);Point p1(x1 + v.x*(r+r1), y1 + v.y*(r+r1)), p2(x1 + w.x*(r+r1), y1 + w.y*(r+r1)), t;if (p2 < p1) t = p1, p1 = p2, p2 = t;cout << "[(" << p1.x << ',' << p1.y << "),(" << p2.x << "," << p2.y << ")]" << endl;}
}char s[48];void solve() {if (s[0] == 'I') solveI();else if (s[0] == 'T') solveT();else if (s[4] == 'u') solveU();else if (s[13] == 'A') solveA();else if (s[18] == 'L') solveL();else solveD();
}int main() {cout << fixed << setprecision(6);while (cin >> s) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/612191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器 配置git

参考了下面这篇文章&#xff0c;不对的地方做了改正 在服务器上git clone github项目的过程-CSDN博客 1. 下载解压 wget https://www.kernel.org/pub/software/scm/git/git-2.34.1.tar.gz tar -zxvf git-2.34.1.tar.gz 2. 安装 cd git-2.34.1/ ./configure make confi…

Geotools-PG空间库(Crud,属性查询,空间查询)

建立连接 经过测试&#xff0c;这套连接逻辑除了支持纯PG以外&#xff0c;也支持人大金仓&#xff0c;凡是套壳PG的都可以尝试一下。我这里的测试环境是Geosence创建的pg SDE&#xff0c;数据库选用的是人大金仓。 /*** 获取数据库连接资源** param connectConfig* return* {…

springboot私人健身与教练预约管理系统源码和论文

随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&#xf…

【rk3568】01-环境搭建

文章目录 1.开发板介绍1.1相关资源&#xff1a;1.2接口布局1.3屏幕1.4核心板引脚可复用资源 2.环境搭建2.1安装依赖包2.2git配置2.3安装sdk2.4sdk介绍2.5sdk编译 3.镜像介绍 1.开发板介绍 开发板&#xff1a;atk-rk3568开发板 eMMC&#xff1a;64G LPDDR4&#xff1a;4G 显示屏…

螺旋数字矩阵 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法: 给出数字个数n和行数m (0 < n <= 999,0 < m <= 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3……

创建ROS模型与小机器人地图规划

1、打开自己的VM系统 2、安装小机器人的安装包&#xff0c;输入如下命令&#xff0c;回车输入密码(自己设的)&#xff1a; sudo apt install ros-noetic-turtlebot3-simulations ros-noetic-turtlebot3-slam ros-noetic-turtlebot3-navigation 提示我之前安装过了 3、用rosla…

Java 常见缓存详解以及解决方案

一. 演示Mybatis 一级缓存 首先我们准备一个接口 两个实现的方法&#xff0c; 当我们调用这个queryAll&#xff08;&#xff09;方法时我们需要调用selectAll&#xff08;&#xff09;方法来查询数据 调用此接口实现效果 这个时候我们就可以发现了问题&#xff0c;我们调用方法…

18张AI电脑动漫超清壁纸免费分享

18张AI电脑动漫壁纸&#xff0c;紫色系和暗黑系&#xff0c;都很不错&#xff0c;喜欢的朋友可以拿去 CSDN免积分下载

【LV12 DAY12-13 GPIO C 语言与寄存器封装】

GPIO 通用型输入输出&#xff0c;GPIO可以控制连接在其引脚实现信号的输入和输出 芯片的引脚和外部设备相连从而实现与外部硬件的通讯&#xff0c;控制&#xff0c;信号采集的功能。 控制CHG_COK引脚输出为高电平&#xff0c;LED亮&#xff0c;输出为低电平&#xff0c;LED熄灭…

Android 10.0 TvSettings系统设置wifi连接密码框点击Enter键失去焦点

1.前言 在10.0的box产品开发中,在TvSettings中,在wifi连接的时候,在用遥控器输入wifi密码框的时候,会发现在按遥控器Enter键的时候, 发现EditText焦点失去了,导致输入法消失了,为了解决这个问题就需要拦截Enter键保证正常输入wifi密码,接下来就来实现这个功能 如图: 2.…

CSS 弹幕按钮动画

<template><view class="content"><button class="btn-23"><text class="text">弹幕按钮</text><text class="marquee">弹幕按钮</text></button></view></template><…

win7添加access的odbc数据源

从控制面板打开odbc数据源&#xff1b;如果像下面没有access的驱动程序&#xff0c; 根据资料&#xff0c;打开C盘-Windows-SysWow64-odbcad32.exe&#xff0c;看一下就有了&#xff1b; 然后添加用户DSN&#xff0c;选中access的驱动程序&#xff0c; 自己输入一个数据源名&am…

【浅尝C++】引用

&#x1f388;归属专栏&#xff1a;浅尝C &#x1f697;个人主页&#xff1a;Jammingpro &#x1f41f;记录一句&#xff1a;大半夜写博客的感觉就是不一样&#xff01;&#xff01; 文章前言&#xff1a;本篇文章简要介绍C中的引用&#xff0c;每个介绍的技术点&#xff0c;在…

Gitlab-ci:从零开始的前端自动化部署

一.概念介绍 1.1 gitlab-ci && 自动化部署工具的运行机制 以gitlab-ci为例&#xff1a; (1) 通过在项目根目录下配置.gitlab-ci.yml文件&#xff0c;可以控制ci流程的不同阶段&#xff0c;例如install/检查/编译/部署服务器。gitlab平台会扫描.gitlab-ci.yml文件&…

QML实现的图片浏览器

很久之前实现了一个QWidget版本的图片浏览器:基于Qt5的图片浏览器QHImageViewer 今天用QML也实现一个,功能差不多: ●悬浮工具栏 ●支持图片缩放、旋转、还原、旋转、拖动。 ●拖动图片时,释放鼠标图片会惯性滑动。 ●支持左右翻页查看文件夹中的图片。 ●支持保存图片至本…

【ONE·MySQL || 常见的基本函数】

总言 主要内容&#xff1a;介绍了MySQL中常用的基本函数。一些聚合函数、时间日期函数、字符串函数、数字函数等。       文章目录 总言1、聚合函数1.1、汇总1.2、COUNT()函数1.2.1、基本说明1.2.2、使用演示 1.3、SUM( )函数1.3.1、基本说明1.3.2、使用演示 1.4、AVG( )函…

java基础之Java8新特性-Optional

目录 1.简介 2.Optional类常用方法 3.示例代码 4.示例代码仓库地址 1.简介 Java 8引入了一个重要的新特性&#xff0c;即Optional类。Optional类是为了解决空指针异常而设计的。 在Java中&#xff0c;当我们尝试访问一个空对象的属性或调用其方法时&#xff0c;很容易抛出…

【服务器数据恢复】Hyper-V虚拟化数据恢复案例

服务器数据恢复环境&#xff1a; Windows Server操作系统服务器&#xff0c;部署Hyper-V虚拟化环境&#xff0c;虚拟机的硬盘文件和配置文件存放在某品牌MD3200存储中&#xff0c;MD3200存储中有一组由4块硬盘组成的raid5阵列&#xff0c;存放虚拟机的数据文件&#xff1b;另外…

国内首款支持苹果Find My芯片-伦茨科技ST17H6x

深圳市伦茨科技有限公司&#xff08;以下简称“伦茨科技”&#xff09;发布ST17H6x Soc平台。成为继Nordic之后全球第二家取得Apple Find My「查找」认证的芯片厂家&#xff0c;该平台提供可通过Apple Find My认证的Apple查找&#xff08;Find My&#xff09;功能集成解决方案。…

建立四叉树[中等]

一、题目 给你一个n * n矩阵grid&#xff0c;矩阵由若干0和1组成。请你用四叉树表示该矩阵grid。你需要返回能表示矩阵grid的四叉树的根结点。四叉树数据结构中&#xff0c;每个内部节点只有四个子节点。此外&#xff0c;每个节点都有两个属性&#xff1a; 【1】val&#xff1…