topic
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
answer
To judge whether a circle intersects with a triangle, first judge the distribution of points as follows:
1. All three points are inside the circle and do not intersect
2. All three points are outside the circle, requiring special judgment
3. Others: intersection
For case 2:
1. If the circle intersects any edge, then intersect, for each edge, turn into 2
2. For each edge, find the distance from the point to the line, if the distance is greater than the radius, there is no intersection, otherwise, turn into 3
3. If the angles centered on the two triangle points are acute angles, they intersect, otherwise they do not intersect. The specific analysis is as follows:
If the distance from the center of the circle to the line segment is greater than r
, it can be directly determined that the line segment has no intersection with the circle
The distance from the center of the circle to the line segment is less than r
The first case:
In this case, we can get,
Second case:
In this case, we can get
Line
Equation The standard form of the line equation is:
code
#include <iostream>
#include <limits>
#include <algorithm>
using namespace std;
using ll = long long;
ll Distance(ll x1, ll y1, ll x2, ll y2)
{
return (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
}
bool isSegmentCircle(ll x, ll y, ll r,ll px1, ll py1, ll px2, ll py2)
{
ll a, b, c; // 直线方程的三个参数
if (px1 == px2)
{
a = 1;
b = 0;
c = -px1;
}
else if (py1 == py2)
{
a = 0;
b = 1;
c = -py1;
}
else
{
a = py2 - py1;
b = px1 - px2;
c = px2*py1 - px1*py2;
}
ll dMax = r*r*(a*a + b*b);
ll dUp = a*x + b*y + c;
dUp = dUp*dUp; // 点到直线距离
if (dUp > dMax)
return false;
// 向量点乘
ll sita1 = (x - px1)*(px2 - px1) + (y - py1)*(py2 - py1);
ll sita2 = (x - px2)*(px1 - px2) + (y - py2)*(py1 - py2);
if (sita1 > 0 && sita2 > 0)
return true;
return false;
}
bool isInterset(ll x, ll y, ll r, ll posX[], ll posY[])
{
ll d1 = Distance(x, y, posX[0], posY[0]);
ll d2 = Distance(x, y, posX[1], posY[1]);
ll d3 = Distance(x, y, posX[2], posY[2]);
ll d = r*r;
if (d1 < d && d2 < d && d3 < d)
return false;
if (d1 > d && d2 > d && d3>d)
{
bool f = false;
f = f || isSegmentCircle(x, y,r, posX[0], posY[0], posX[1], posY[1]);
f = f || isSegmentCircle(x, y,r, posX[1], posY[1], posX[2], posY[2]);
f = f || isSegmentCircle(x, y,r, posX[2], posY[2], posX[0], posY[0]);
return f;
}
return true;
}
int main()
{
// freopen("input.txt", "r", stdin);
int T;
cin >> T;
ll x, y, r;
ll posX[3];
ll posY[3];
while (T--)
{
scanf("%lld%lld%lld", &x, &y, &r);
for (int i = 0; i < 3; ++i)
scanf("%lld%lld", &posX[i], &posY[i]);
if (isInterset(x, y, r, posX, posY))
cout << "Yes\n";
else
cout << "No\n";
}
return 0;
}
Ideas refer to http://blog.csdn.net/f_zyj/article/details/52066901