UVa12304 2D Geometry 110 in 1!

news2025/1/12 16:10:46

题目链接

         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.coloradmin.cn/o/1373097.html

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

相关文章

C++从零基础到入门(1)

目录 一、输入输出 (iostream库) 1.标准输出流cout 2.标准输入流cin 3.标准库iostream &#xff08;1&#xff09;iostream中的窄字符&#xff08;char&#xff09; &#xff08;2&#xff09;iostream中的 宽字符&#xff08;wchar_t&#xff09; 二、变量与数据类型 …

Map与JSONObject区别

相同点&#xff1a; 都可以存key-value&#xff1b;key是唯一的,如果key重复了会覆盖前面的 不同点&#xff1a; &#xff08;1&#xff09;JSONObject 不可以存空&#xff0c;Map可以存空。 &#xff08;2&#xff09;Map由jdk提供&#xff0c;JsonObject需要第三方jar包提供。…

搜索与图论第一期 DFS(深度优先搜索)

前言 DFS这部分难度不大&#xff0c;大家应该完全掌握&#xff01;&#xff01;&#xff01; 一、DFS的基本内容 内容&#xff1a; 深度优先遍历图的方法是&#xff0c;从图中某顶点v出发&#xff1a; &#xff08;1&#xff09;访问顶点v&#xff1b; &#xff08;2&#…

使用Linux防火墙管理HTTP流量

在Linux系统中&#xff0c;防火墙是用于控制网络流量的重要工具。通过防火墙&#xff0c;你可以根据需要限制、过滤或允许特定的网络流量&#xff0c;从而提高系统的安全性。在处理HTTP流量时&#xff0c;防火墙可以帮助你实施访问控制、流量监控和其他安全策略。 iptables i…

【NVIDIA】Jetson Orin Nano系列:烧写Ubuntu22.04

1、简介 最新的sdk-manager已经可以安装到Ubuntu22.0&#xff0c;也支持在 Jetson Orin Nano 上烧写Ubuntu22.04。 官网介绍&#xff1a;https://developer.nvidia.com/sdk-manager 2、版本介绍 JetPack版本&#xff1a;https://developer.nvidia.com/embedded/jetpack-ar…

Camunda Event Based Gateway

一&#xff1a;bpmn 二&#xff1a;java 如果没有收到信号&#xff0c;超过等待时间&#xff0c;流程进入总经理审批&#xff0c;如果在等待时间内收到信号&#xff0c;流程进入副总经理审批。 示例1&#xff1a;发送信号事件&#xff0c;流程进入副总经理审批。 repository…

vue element-ui的table列表中展示缩略图片效果实例

这篇文章主要给大家介绍了关于vue element-ui的table列表中展示多张图片(可放大)效果的相关资料,文中通过代码示例介绍的非常详细,需要的朋友可以参考下 一、效果图 二、代码部分 1、原理 使用 <el-table-column> 和 <el-image> 组件来在表格中插入缩略图 2、te…

学习笔记之——3D Gaussian Splatting源码解读

之前博客对3DGS进行了学习与调研 学习笔记之——3D Gaussian Splatting及其在SLAM与自动驾驶上的应用调研-CSDN博客文章浏览阅读450次。论文主页3D Gaussian Splatting是最近NeRF方面的突破性工作&#xff0c;它的特点在于重建质量高的情况下还能接入传统光栅化&#xff0c;优…

CMU15-445-Spring-2023-Project #2 - B+Tree

前置知识&#xff1a;参考上一篇博文 CMU15-445-Spring-2023-Project #2 - 前置知识&#xff08;lec07-010&#xff09; CHECKPOINT #1 Task #1 - BTree Pages 实现三个page class来存储B树的数据。 BTree Page internal page和leaf page继承的基类&#xff0c;只包含两个…

人工智能:未来智慧城市建设的“智慧大脑”与核心价值

目录 一、引言 二、人工智能在智慧城市中的应用实例 三、人工智能对智慧城市建设的核心价值 四、面临的挑战与未来展望 五、结语 六、附&#xff1a;智慧城市全套解决方案大合集 - 下载 一、引言 随着科技的飞速发展&#xff0c;智慧城市的概念逐渐深入人心。智慧城市利…

爬虫你需要知道的:什么是http请求

1. 什么是http请求 我们将通过发送http请求来获取网页内容。http是HyperText Transfer Protocol的缩写&#xff0c;意思是超文本传输协议&#xff0c;它是一种客户端和服务器之间的请求响应协议。 浏览器就可以看作是一个客户端&#xff0c;当我们在浏览器地址栏输入想访问的…

uniapp在web端怎么使用svg图标呢

在图标库中添加好项目用到的图标&#xff0c;点击symbol点击生成在线链接 点击生成的在线链接&#xff0c;此时会跳转到一个新窗口&#xff0c;是一个js文件 复制这个js文件的内容 然后在uniapp中新建svg.js文件&#xff0c;把从上面复制的代码粘贴到这个svg.js中 在main.js中引…

创建并美化Github主页(内含组件)

目录 1、创建仓库 2、美化 1、包含多种 2、活动统计图 3、资料奖杯 4、文字的打字特效 5、中文网站卡片 6、贪吃蛇贡献图 7、可参考的页面 最近有想要写开源的打算了&#xff0c;计划了好久好久好久&#xff0c;不知道写啥(目前仍然不知道)…… 俗话说人活一张脸&#xff0…

“Tab“ 的新型可穿戴人工智能项链

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

uni微信小程序强制用户更新版本

强制更新的代码参考官方文档 uni.getUpdateManager() | uni-app官网 我这边的如下&#xff1a; //检查版本更新const updateManager uni.getUpdateManager();updateManager.onCheckForUpdate(function (res) {// 请求完新版本信息的回调console.log(res.hasUpdate, "是…

ABeam×StartUp丨ABeam旗下德硕管理咨询(深圳)新创部门拜访「光子晶体科技」

光子晶体科技 ABeamStartUp 光子透明芯片 显示技术 光学材料 近日&#xff0c;ABeam 旗下德硕管理咨询&#xff08;深圳&#xff09;有限公司&#xff08;以下简称“ABeam-SZ”&#xff09;新创部门一行拜访了深圳光子晶体科技有限公司&#xff08;以下简称“光子晶体科技”…

Ubuntu系统中指定端口防火墙状态查询与操作

浏览器访问&#xff1a; 如果遇到如山图所示的情况&#xff0c;既有可能是防火墙的问题。具体解决方案参照如下&#xff1a; 1.指定端口的防火墙状态查询 &#xff08;1&#xff09;查询命令 sudo ufw status | grep 8081/tcp #其中8081为要查询的端口号 如果端口是打开的…

你真的掌握了“C语言分支循环”吗

目录 前言 1. if语句 1.1 if 1.2 else 1.3 分支中包含多条语句 1.4 嵌套if 1.5 悬空else问题 2. 关系操作符 3. 条件操作符 4. 逻辑操作符&#xff1a;&& , || , &#xff01; 4.1 逻辑取反运算符 4.2 与运算符 4.3 或运算符 4.4 练习&#xff1a;闰年的判…

C++枚举类型可以作为返回值类型吗

当然&#xff1a; #include <iostream> // 定义一个枚举类型 enum class Color { RED, GREEN, BLUE }; // 函数返回枚举类型 Color getRandomColor() { static int nextColorIndex 0; Color color Color(nextColorIndex); nextColorIndex; if (nextColor…

DevEco Studio for Mac:zsh: command not found: ohpm

一、检查是否配置有ohpm环境 1、新打开一个终端输入export&#xff0c;查看是否有 ohpm路径&#xff1a; 二、如果没有找到ohpm路径&#xff0c;开始配置环境 。 1、查找本机ohpm路径&#xff0c;并记录ohpm解释器的路径&#xff1a; 2、打开终端工具&#xff0c;执行命令 ech…