51 nod 1298 circles and triangles (computational geometry)

Topic source:  HackerRank
Base Time Limit: 1 second Space Limit: 131072 KB Score: 0  Difficulty: Basic
 collect
 focus on
Given the center and radius of the circle, and the three vertices of the triangle, ask whether the circle intersects the triangle. The intersection outputs "Yes", otherwise it outputs "No". (The area of ​​the triangle is greater than 0).

Input
Line 1: A number T, representing the number of tests entered (1 <= T <= 10000), and then every 4 lines are used to describe a set of test data.
4-1: Three numbers, the first two numbers are the coordinates xc, yc of the center of the circle, and the third number is the radius R of the circle. (-3000 <= xc, yc <= 3000, 1 <= R <= 3000)
4-2: 2 numbers, the coordinates of the first point of the triangle.
4-3: 2 numbers, the coordinates of the second point of the triangle.
4-4: 2 numbers, the coordinates of the third point of the triangle. (-3000 <= xi, yi <= 3000)
Output
A total of T lines, for each set of input data, the intersection output "Yes", otherwise output "No".
Input example
2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5
Output example
Yes
No

思路:分析三角形和圆的位置关系可知非常复杂。
简化问题用从对立事件角度考虑。我们知道当圆与三角形不相交的情况有:
1)三角形的三点都在圆内,即圆心到三条边的距离都小于半径R
2)当三角形的三点都在圆外时,只有圆心到三条边的距离都大于半径R时才满足不相交。

其余的情况都是相交。

这里还要解决的一个问题就是如何求圆心到三条边的距离?
利用海伦公式,p=(a+b+c)/2;S=sqrt(p*(p-a)*(p-b)*(p-c));-->S=h*d/2;
把三角形上的两个点与圆心看成一个三角形,通过这个三角形的面积来求出圆心到这条边的距离。

#include<bits/stdc++.h>
#define M 1e-6
using namespace std;
double dis1(double a,double b,double x,double y)
{
    return sqrt((a-x)*(a-x)+(b-y)*(b-y));
}
double dis2(double a1,double b1,double a2,double b2,double x,double y)
{
    double a=dis1(a1,b1,x,y);
    double b=dis1(a2,b2,x,y);
    double c=dis1(a1,b1,a2,b2);
    if(a*a>=b*b+c*c)
        return b;
    else if(b*b>=a*a+c*c)
        return a;
    double p=(a+b+c)/2;
    double s=sqrt(p*(p-a)*(p-b)*(p-c));
    return s*2/c;///Heron's formula uses the triangle formed by the center of the circle and the two points of the triangle to find the distance from the center of the circle to the side
}
intmain()
{
    int t;
    cin>>t;
    while(t--)
    {
        double x,y,r;
        double a1,b1,a2,b2,a3,b3;
        double d1,d2,d3,d4,d5,d6;
        cin>>x>>y>>r;
        cin>>a1>>b1;
        cin>>a2>>b2;
        cin>>a3>>b3;
        d1=dis1(a1,b1,x,y);
        d2=dis1(a2,b2,x,y);
        d3=dis1(a3,b3,x,y);///The distance from the three points to the center of the circle
        d4=dis2(a1,b1,a2,b2,x,y);
        d5=dis2(a1,b1,a3,b3,x,y);
        d6=dis2(a2,b2,a3,b3,x,y);/// Find the distance from the center of the circle to the three sides
        if(d4-r>M&&d5-r>M&&d6-r>M)
            printf("No\n");
        else if(d1<r&&d2<r&&d3<r)
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324520686&siteId=291194637