📌  相关文章
📜  检查是否可以将圆上给定的两个点连接起来,使它们之间的距离为 k

📅  最后修改于: 2021-10-23 08:13:29             🧑  作者: Mango

给定两个圆和一个长度 K。找出我们是否可以连接两个点(每个圆的周长上有一个),使点之间的距离为 K。(两个点的坐标不必是整数值)。
例子:

Input: Circle-1 Center (0, 0) Radius = 5
       Circle-2 Center (8, 3) Radius = 2
       K = 3
Output: Yes
Maximum Distance: 15
Minimum Distance: 2

方法:

  1. 我们必须找到这些圆上任意两点之间可能的最大和最小距离,如果 K 在这个范围内,那么答案是肯定的,否则我们找不到这样的线段。
  2. 要查找最小和最大距离:
  • 情况 1:当两个圆不相交或仅接触一点时。
    在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离将是中心之间的距离 – 半径(圆 1) – 半径(圆 2)。

圆点

  • 情况 2:当两个圆恰好在两点相交时。
    在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离为 0。(我们在两个圆中有两个共同点)。

相交

  • 情况 3:当圆 1 完全在圆 2 内时。
    在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离为半径(圆 2) – 中心之间的距离 – 半径(圆 1)

圆圈

  • 情况 4:当圆 2 完全在圆 1 内时。
    在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离为半径(圆 1) – 中心之间的距离 – 半径(圆 2)

圆圈

  • 情况 5:当两个圆的中心相同时
    • 子案例1:半径也相同。最小距离和最大距离均为 0。
    • 子案例2:半径不同(R1最大距离为 R1+R2
      最小距离为 R2-R1

同一个中心

下面是上述方法的实现:

C++
// C++ program to implement above approach
#include 
#define ll long long int
using namespace std;
 
struct t {
    ll x, y, r;
};
typedef struct t node;
 
// Return distance between the centers
long double dis(ll x1, ll y1, ll x2, ll y2)
{
    return sqrt((x1 - x2) * (x1 - x2)
                + (y1 - y2) * (y1 - y2));
}
 
bool check(node c1, node c2, int k)
{
    long double min = 0;
    long double max = 0;
    // Distance between centers
    long double de = dis(c1.x, c1.y, c2.x, c2.y);
    // Case 5
    if (de == 0) {
        // SubCase 1
        if (c1.r == c2.r) {
            min = 0;
            max = 0;
        }
        // Subcase 2
        else {
            if (c1.r - c2.r > 0) {
                min = c1.r - c2.r;
                max = min + 2 * c2.r;
            }
            else {
                min = c2.r - c1.r;
                max = min + 2 * c1.r;
            }
        }
    }
    // Case 1
    else if (de >= c1.r + c2.r) {
        min = de - c1.r - c2.r;
        max = de + c1.r + c2.r;
    }
    // Case 3
    else if (de + c2.r < c1.r) {
        max = c2.r + c1.r + de;
        min = c1.r - de - c2.r;
    }
    // Case 4
    else if (de + c1.r < c2.r) {
 
        max = c2.r + c1.r + de;
        min = c2.r - de - c1.r;
    }
    // Case 2
    else if ((de + c2.r >= c1.r) || (de + c1.r >= c2.r)) {
        max = c2.r + c1.r + de;
        min = 0;
    }
    // Since value of k will always be an integer
    ll temin = (ll)(ceil(min));
    ll re = (ll)max;
    if (k >= temin && k <= re)
        return true;
    return false;
}
 
// Driver Code
int main()
{
    node circle1, circle2;
    int k = 3;
    circle1.x = 0;
    circle1.y = 0;
    circle1.r = 5;
    circle2.x = 8;
    circle2.y = 3;
    circle2.r = 2;
    if (check(circle1, circle2, k))
        cout << "YES" << endl;
    else
        cout << "NO" << endl;
}


Java
// Java program to implement above approach
class GFG
{
 
    static class node
    {
        long x, y, r;
    };
 
    // Return distance between the centers
    static long dis(long x1, long y1, long x2, long y2)
    {
        return (long) Math.sqrt((x1 - x2) * (x1 - x2)
                + (y1 - y2) * (y1 - y2));
    }
 
    static boolean check(node c1, node c2, int k)
    {
        long min = 0;
        long max = 0;
         
        // Distance between centers
        long de = dis(c1.x, c1.y, c2.x, c2.y);
         
        // Case 5
        if (de == 0)
        {
            // SubCase 1
            if (c1.r == c2.r)
            {
                min = 0;
                max = 0;
            }
            // Subcase 2
            else if (c1.r - c2.r > 0)
            {
                min = c1.r - c2.r;
                max = min + 2 * c2.r;
            }
            else
            {
                min = c2.r - c1.r;
                max = min + 2 * c1.r;
            }
        }
         
        // Case 1
        else if (de >= c1.r + c2.r)
        {
            min = de - c1.r - c2.r;
            max = de + c1.r + c2.r;
        }
        // Case 3
        else if (de + c2.r < c1.r)
        {
            max = c2.r + c1.r + de;
            min = c1.r - de - c2.r;
        }
        // Case 4
        else if (de + c1.r < c2.r)
        {
 
            max = c2.r + c1.r + de;
            min = c2.r - de - c1.r;
        }
        // Case 2
        else if ((de + c2.r >= c1.r) || (de + c1.r >= c2.r))
        {
            max = c2.r + c1.r + de;
            min = 0;
        }
         
        // Since value of k will always be an integer
        long temin = (long) (Math.ceil(min));
        long re = (long) max;
        if (k >= temin && k <= re)
        {
            return true;
        }
        return false;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        node circle1 = new node();
        node circle2 = new node();
        int k = 3;
        circle1.x = 0;
        circle1.y = 0;
        circle1.r = 5;
        circle2.x = 8;
        circle2.y = 3;
        circle2.r = 2;
        if (check(circle1, circle2, k))
        {
            System.out.println("Yes");
        }
        else
        {
            System.out.println("No");
        }
    }
}
 
// This code is contributed by Princi Singh


Python
# Python3 program to implement above approach
from math import sqrt,ceil,floor
 
# Return distance between the centers
def dis(x1, y1, x2, y2):
    return sqrt((x1 - x2) * (x1 - x2) +
                (y1 - y2) * (y1 - y2))
 
def check(c1, c2, k):
    min = 0
    max = 0
     
    # Distance between centers
    de = dis(c1[0], c1[1], c2[0], c2[1])
     
    # Case 5
    if (de == 0):
         
        # SubCase 1
        if (c1[2] == c2[2]):
            min = 0
            max = 0
     
        # Subcase 2
        else:
            if (c1[2] - c2[2] > 0):
                min = c1[2] - c2[2]
                max = min + 2 * c2[2]
 
            else:
                min = c2[2] - c1[2]
                max = min + 2 * c1[2]
 
    # Case 1
    elif (de >= c1[2] + c2[2]):
        min = de - c1[2] - c2[2]
        max = de + c1[2] + c2[2]
     
    # Case 3
    elif (de + c2[2] < c1[2]):
        max = c2[2] + c1[2] + de
        min = c1[2] - de - c2[2]
     
    # Case 4
    elif (de + c1[2] < c2[2]):
 
        max = c2[2] + c1[2] + de
        min = c2[2] - de - c1[2]
     
    # Case 2
    elif ((de + c2[2] >= c1[2]) or (de + c1[2] >= c2[2])):
        max = c2[2] + c1[2] + de
        min = 0
 
    # Since value of k wialways be an integer
    temin = ceil(min)
    re = max
    if (k >= temin and k <= re):
        return True
    return False
 
# Driver Code
circle1 = [0, 0, 5]
circle2 = [8, 3, 2]
k = 3
 
if (check(circle1, circle2, k)):
    print("YES")
else:
    print("NO" )
     
# This code is contributed by mohit kumar 29


C#
// C# program to implement above approach
using System;
     
class GFG
{
 
    public class node
    {
        public long x, y, r;
    };
 
    // Return distance between the centers
    static long dis(long x1, long y1, long x2, long y2)
    {
        return (long) Math.Sqrt((x1 - x2) * (x1 - x2)
                + (y1 - y2) * (y1 - y2));
    }
 
    static Boolean check(node c1, node c2, int k)
    {
        long min = 0;
        long max = 0;
         
        // Distance between centers
        long de = dis(c1.x, c1.y, c2.x, c2.y);
         
        // Case 5
        if (de == 0)
        {
            // SubCase 1
            if (c1.r == c2.r)
            {
                min = 0;
                max = 0;
            }
            // Subcase 2
            else if (c1.r - c2.r > 0)
            {
                min = c1.r - c2.r;
                max = min + 2 * c2.r;
            }
            else
            {
                min = c2.r - c1.r;
                max = min + 2 * c1.r;
            }
        }
         
        // Case 1
        else if (de >= c1.r + c2.r)
        {
            min = de - c1.r - c2.r;
            max = de + c1.r + c2.r;
        }
        // Case 3
        else if (de + c2.r < c1.r)
        {
            max = c2.r + c1.r + de;
            min = c1.r - de - c2.r;
        }
        // Case 4
        else if (de + c1.r < c2.r)
        {
 
            max = c2.r + c1.r + de;
            min = c2.r - de - c1.r;
        }
        // Case 2
        else if ((de + c2.r >= c1.r) || (de + c1.r >= c2.r))
        {
            max = c2.r + c1.r + de;
            min = 0;
        }
         
        // Since value of k will always be an integer
        long temin = (long) (Math.Ceiling((double)min));
        long re = (long) max;
        if (k >= temin && k <= re)
        {
            return true;
        }
        return false;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        node circle1 = new node();
        node circle2 = new node();
        int k = 3;
        circle1.x = 0;
        circle1.y = 0;
        circle1.r = 5;
        circle2.x = 8;
        circle2.y = 3;
        circle2.r = 2;
        if (check(circle1, circle2, k))
        {
            Console.WriteLine("Yes");
        }
        else
        {
            Console.WriteLine("No");
        }
    }
}
 
// This code contributed by Rajput-Ji


Javascript


输出:
YES