Hit! Gym - 101522H (2)“三角形相似”

Hit! Gym - 101522H (2)“三角形相似”


题目链接

题意:
分别给出两个圆的圆心坐标和半径长度,并保证两个圆有公共部分(相交/相切/内含),输出一个位于公共部分的点的坐标,答案不唯一。
注意一下距离的精度10^-5。

做法:
下面以一个简单的例子说明,其他可以类比。
我们假设两个圆的半径分别为r1, r2, 两圆相交部分的长度为x。标注A, B, C, D四个点,分别过B, C, D点作垂线。图如下:
这里写图片描述
把图简化一下,只留下最重要的部分:
这里写图片描述
我们的代码是这样的,通过两个圆的半径长度的比值,然后直接得到一个,在连接两圆圆心的线段上的点,并且这个点就是两个圆相交部分中的一个点。

    k = r1 / (r1 + r2);
    x = x1 + k * (x2 - x1);
    y = y1 + k * (y2 - y1);

可是为什么呢?这个点为什么会在两个圆的相交部分呢?
我们已经假设两圆相交部分的长度为x,AC = r1, BD = r2, 则AB = r1-x, AD = r1+r2-x。
由此,我们可以得到一个式子,它解释了为什么。

(r1-x)/(r1+r2-x) <= r1/(r1+r2) <= r1/(r1+r2-x)

中间部分的r1/(r1+r2),就是我们代码中的k。首先,我么可以通过通分,检验一下式子的正确性。
把前面设的变量代入,上式也可以表示为:

AB/AD <= AC/(r1+r2) <= AC/AD

B, C是x的两个端点,这个比例式说明,在BC即x的长度内确实存在一个点,满足条件。结合两个公式和图,认真多看几遍,拿笔比划比划,就会明白了。

#include <stdio.h>

int
main() {
    double x1, x2, y1, y2, r1, r2;
    double k, x, y;

    scanf("%lf %lf %lf", &x1, &y1, &r1);
    scanf("%lf %lf %lf", &x2, &y2, &r2);
    k = r1 / (r1 + r2);
    x = x1 + k * (x2 - x1);
    y = y1 + k * (y2 - y1);
    printf("%f %f\n", x, y);

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值