📜  三个切圆内的内切圆的半径

📅  最后修改于: 2021-04-27 06:02:50             🧑  作者: Mango

如下图所示,有4个具有正整数半径r1r2r3r4的圆。

任务是在给定半径r1r2r3的情况下,找到由三个圆组成的圆的半径r4
(请注意,上图中的圆圈彼此相切。)

例子:

方法1 :(使用二进制搜索):

  1. 政策是加入所有圆的中心并形成4个三角形
  2. 三角形形成后,使用二分查找法将三个较小三角形的面积之和与主三角形尽可能相等。

分析上述方法:

  1. 此方法之所以有效,是因为上面的图像中最初有4个三角形。
  2. 带边的主三角形(r1+r2, r1+r3, r2+r3) 和带有边的三个较小的三角形(r1+r4, r2+r4, r1+r2), (r1+r4, r3+r4, r1+r3), (r2+r4, r3+r4, r2+r3)
  3. 主三角形由较小的三角形组成,因此主三角形的面积是较小三角形的面积之和。

形成搜索空间:
在这里二进制搜索。可以选择r的值,并且可以计算所有三个较小三角形的面积之和,并将其与主三角形的面积进行比较。

  1. 选择下限l = 0
  2. 选择上限h = s/(r1 + r2 + r3)

通过直觉,将r4的上限值作为内接圆的半径(r1+r2, r1+r3, r2+r3) 三角形小于:
r upper_bound = 2s/(r1+r2+r2+r3+r3+r1) = s/(r1+r2+r3)
现在,可以在以下搜索空间中应用二进制搜索。

以下是使用上述方法实现的问题。

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Radius of the 3 given circles
// declared as double.
double r1, r2, r3;
 
// Calculation of area of a triangle by Heron's formula
double area(double a, double b, double c)
{
    double p = (a + b + c) / 2;
    return sqrt(p) * sqrt(p - a) * sqrt(p - b) * sqrt(p - c);
}
 
// Applying binary search to find the
// radius r4 of the required circle
double binary_search()
{
    // Area of main triangle
    double s = area(r1 + r2, r2 + r3, r3 + r1);
    double l = 0, h = s / (r1 + r2 + r3);
    // Loop runs until l and h becomes approximately equal
    while (h - l >= 1.e-7) {
        double mid = (l + h) / 2;
 
        // Area of smaller triangles
        double s1 = area(mid + r1, mid + r2, r1 + r2);
        double s2 = area(mid + r1, mid + r3, r1 + r3);
        double s3 = area(mid + r2, mid + r3, r2 + r3);
 
        // If sum of smaller triangles
        // is less than main triangle
        if (s1 + s2 + s3 < s) {
            l = mid;
        }
        // If sum of smaller triangles is
        // greater than or equal to main triangle
        else {
            h = mid;
        }
    }
    return (l + h) / 2;
}
// Driver code
int main()
{
    // Taking r1, r2, r3 as input
    r1 = 1.0;
    r2 = 2.0;
    r3 = 3.0;
    // Call to function binary search
    cout << fixed << setprecision(6) << binary_search() << endl;
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    // Radius of the 3 given circles
    // declared as double.
    static double r1, r2, r3;
 
    // Calculation of area of a triangle by Heron's formula
    static double area(double a, double b, double c)
    {
        double p = (a + b + c) / 2;
        return Math.sqrt(p) * Math.sqrt(p - a) *
               Math.sqrt(p - b) * Math.sqrt(p - c);
    }
 
    // Applying binary search to find the
    // radius r4 of the required circle
    static double binary_search()
    {
        // Area of main triangle
        double s = area(r1 + r2, r2 + r3, r3 + r1);
        double l = 0, h = s / (r1 + r2 + r3);
         
        // Loop runs until l and h becomes approximately equal
        while (h - l >= 1.e-7)
        {
            double mid = (l + h) / 2;
 
            // Area of smaller triangles
            double s1 = area(mid + r1, mid + r2, r1 + r2);
            double s2 = area(mid + r1, mid + r3, r1 + r3);
            double s3 = area(mid + r2, mid + r3, r2 + r3);
 
            // If sum of smaller triangles
            // is less than main triangle
            if (s1 + s2 + s3 < s)
            {
                l = mid;
            }
             
            // If sum of smaller triangles is
            // greater than or equal to main triangle
            else
            {
                h = mid;
            }
        }
        return (l + h) / 2;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        // Taking r1, r2, r3 as input
        r1 = 1.0;
        r2 = 2.0;
        r3 = 3.0;
         
        // Call to function binary search
        System.out.printf("%.6f", binary_search());
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
import math
 
# Radius of the 3 given circles
r1 = 0
r2 = 0
r3 = 0
 
# Calculation of area of a
# triangle by Heron's formula
def area(a, b, c):
     
    p = (a + b + c) / 2
 
    return ((math.sqrt(p)) *
            (math.sqrt(p - a)) *
            (math.sqrt(p - b)) *
            (math.sqrt(p - c)))
 
# Applying binary search to find the
# radius r4 of the required circle
def binary_search():
     
    global r1, r2, r3
 
    # Area of main triangle
    s = area(r1 + r2, r2 + r3, r3 + r1)
    l = 0
    h = s / (r1 + r2 + r3)
 
    # Loop runs until l and h
    # becomes approximately equal
    while (h - l > 0.00000001):
        mid = (l + h) / 2
 
        # Area of smaller triangles
        s1 = area(mid + r1, mid + r2, r1 + r2)
        s2 = area(mid + r1, mid + r3, r1 + r3)
        s3 = area(mid + r2, mid + r3, r2 + r3)
 
        # If sum of smaller triangles
        # is less than main triangle
        if (s1 + s2 + s3 < s):
            l = mid
             
        # If sum of smaller triangles is
        # greater than or equal to main triangle
        else:
            h = mid
             
    return ((l + h) / 2)
 
# Driver code
 
# Taking r1, r2, r3 as input
r1 = 1
r2 = 2
r3 = 3
 
# Call to function binary search
print("{0:.6f}".format(binary_search()))
 
# This code is contributed by avanitrachhadiya2155


C#
// C# implementation of the approach
using System;
 
class GFG
{
 
    // Radius of the 3 given circles
    // declared as double.
    static double r1, r2, r3;
 
    // Calculation of area of a triangle by Heron's formula
    static double area(double a, double b, double c)
    {
        double p = (a + b + c) / 2;
        return Math.Sqrt(p) * Math.Sqrt(p - a) *
            Math.Sqrt(p - b) * Math.Sqrt(p - c);
    }
 
    // Applying binary search to find the
    // radius r4 of the required circle
    static double binary_search()
    {
        // Area of main triangle
        double s = area(r1 + r2, r2 + r3, r3 + r1);
        double l = 0, h = s / (r1 + r2 + r3);
         
        // Loop runs until l and h
        // becomes approximately equal
        while (h - l > 0.00000001)
        {
            double mid = (l + h) / 2;
 
            // Area of smaller triangles
            double s1 = area(mid + r1, mid + r2, r1 + r2);
            double s2 = area(mid + r1, mid + r3, r1 + r3);
            double s3 = area(mid + r2, mid + r3, r2 + r3);
 
            // If sum of smaller triangles
            // is less than main triangle
            if (s1 + s2 + s3 < s)
            {
                l = mid;
            }
             
            // If sum of smaller triangles is
            // greater than or equal to main triangle
            else
            {
                h = mid;
            }
        }
        return (l + h) / 2;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        // Taking r1, r2, r3 as input
        r1 = 1.0;
        r2 = 2.0;
        r3 = 3.0;
         
        // Call to function binary search
        Console.Write("{0:F6}", binary_search());
    }
}
 
// This code is contributed by Rajput-Ji


C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Driver code
int main()
{
    // Radius of the 3 given circles declared as double.
    double r1, r2, r3;
 
    // Taking r1, r2, r3 as input
    r1 = 1;
    r2 = 2;
    r3 = 3;
 
    // Calculation of r4 using formula given above
    double r4 = (r1 * r2 * r3)
                / (r1 * r2 + r2 * r3 + r1 * r3
                   + 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
    cout << fixed << setprecision(6) << r4 << '\n';
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
 
    // Driver code
    public static void main(String[] args)
    {
        // Radius of the 3 given circles declared as double.
        double r1, r2, r3;
 
        // Taking r1, r2, r3 as input
        r1 = 1;
        r2 = 2;
        r3 = 3;
 
        // Calculation of r4 using formula given above
        double r4 = (r1 * r2 * r3) /
                    (r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
                    Math.sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
        System.out.printf("%.6f", r4);
    }
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the approach
from math import sqrt
 
# Driver code
 
# Radius of the 3 given circles declared as double.
 
# Taking r1, r2, r3 as input
r1 = 1
r2 = 2
r3 = 3
 
# Calculation of r4 using formula given above
r4 = (r1 * r2 * r3)/ (r1 * r2 + r2 * r3 + r1 * r3
            + 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)))
print(round(r4, 6))
 
# This code is contributed by mohit kumar 29


C#
// C# implementation of the approach
using System;
 
class GFG
{
  
    // Driver code
    public static void Main(String[] args)
    {
        // Radius of the 3 given circles declared as double.
        double r1, r2, r3;
  
        // Taking r1, r2, r3 as input
        r1 = 1;
        r2 = 2;
        r3 = 3;
  
        // Calculation of r4 using formula given above
        double r4 = (r1 * r2 * r3) /
                    (r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
                    Math.Sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
        Console.Write("{0:F6}", r4);
    }
}
 
// This code contributed by PrinciRaj1992


输出:
0.260870

方法2 :(使用笛卡尔定理)

  1. 根据笛卡尔定理,这些圆的半径或“曲率”的倒数k_1 = 1/r_1, k_2 = 1/r_2, k_3 = 1/r_3\:and\:k_4 = 1/r_4 满足以下关系。
    2(k_1^2+k_2^2+k_3^2+k_4^2) = (k_1+k_2+k_3+k_4)^2
  2. 如果k_1, k_2, k_3 众所周知,一个人可以解决, k_4 = k_1 + k_2 + k_3 \pm 2\sqrt{k_1 k_2 + k_2 k_3 + k_1 k_3}
  3. 在求解上述方程式时;
    r_4 = (r_1*r_2*r_3)\, /\, (r_1*r_2 + r_2*r_3 + r_3*r_1 + 2.0\, *\, \sqrt{(r_1*r_2*r_3*(r_1+r_2+r_3))})

以下是使用上述公式实现的问题。

C++

// C++ implementation of the approach
#include 
using namespace std;
 
// Driver code
int main()
{
    // Radius of the 3 given circles declared as double.
    double r1, r2, r3;
 
    // Taking r1, r2, r3 as input
    r1 = 1;
    r2 = 2;
    r3 = 3;
 
    // Calculation of r4 using formula given above
    double r4 = (r1 * r2 * r3)
                / (r1 * r2 + r2 * r3 + r1 * r3
                   + 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
    cout << fixed << setprecision(6) << r4 << '\n';
    return 0;
}

Java

// Java implementation of the approach
class GFG
{
 
    // Driver code
    public static void main(String[] args)
    {
        // Radius of the 3 given circles declared as double.
        double r1, r2, r3;
 
        // Taking r1, r2, r3 as input
        r1 = 1;
        r2 = 2;
        r3 = 3;
 
        // Calculation of r4 using formula given above
        double r4 = (r1 * r2 * r3) /
                    (r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
                    Math.sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
        System.out.printf("%.6f", r4);
    }
}
 
// This code is contributed by 29AjayKumar

Python3

# Python3 implementation of the approach
from math import sqrt
 
# Driver code
 
# Radius of the 3 given circles declared as double.
 
# Taking r1, r2, r3 as input
r1 = 1
r2 = 2
r3 = 3
 
# Calculation of r4 using formula given above
r4 = (r1 * r2 * r3)/ (r1 * r2 + r2 * r3 + r1 * r3
            + 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)))
print(round(r4, 6))
 
# This code is contributed by mohit kumar 29

C#

// C# implementation of the approach
using System;
 
class GFG
{
  
    // Driver code
    public static void Main(String[] args)
    {
        // Radius of the 3 given circles declared as double.
        double r1, r2, r3;
  
        // Taking r1, r2, r3 as input
        r1 = 1;
        r2 = 2;
        r3 = 3;
  
        // Calculation of r4 using formula given above
        double r4 = (r1 * r2 * r3) /
                    (r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
                    Math.Sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
        Console.Write("{0:F6}", r4);
    }
}
 
// This code contributed by PrinciRaj1992
输出:
0.260870

参考

  • https://brilliant.org/wiki/descartes-theorem/
  • https://zh.wikipedia.org/wiki/Descartes%27_theorem/
  • http://www.ambrsoft.com/TrigoCalc/Circles3/Tangency/Tangent.htm