I am trying to solve simple task, but I am not finding any elegant solution.
I basically solving intersection of two circular sectors. Each sector is given by 2 angles (from atan2 func) within (-pi, pi] range. Each selector occupy maximum angle of 179.999. So it can be tell for every two angles where the circular sector is.
The return value should describe mutual intersection based on following:
value <1 if one angle is contained by second one (value represents how much space occupy percentually)
value >1 if first angle (the dotted one) is outside the other one, value represents how much of dotted angle is out of the other one
basic cases and some examples are on image bellow
the problem is that there are so many cases which should be handled and I am looking for some elegant way to solve it.
I can compare two angles only when they are on the right side of unit circle (cos>0) because on the left side, angle numerically bigger is graphically lower. I tried use some projection on the right half:
if(x not in <-pi/2, pi/2>)
{
c = getSign(x)*pi/2;
x = c - (x - c);
}
but there is a problem with sectors which occupy part of both halves of unit circle...
There are so many cases... Does somebody know how to solve this elegantly? (I use c++, but any hint or pseudocode is fine)
To do this, you need to work out the radius and the centre of each circle. If the sum of the radii and the distance between the centres are equal, then the circles touch externally. If the difference between the radii and the distance between the centres are equal, then the circles touch internally.
A Venn diagram uses circles that overlap or don't overlap to show the commonalities and differences among things or groups of things. Things that have commonalities are shown as overlapping circles while things that are distinct stand alone.
Given the coordinates of the centres of two circles (X1, Y1) and (X2, Y2) as well as the radii of the respective circles R1 and R2. Find the floor of the area of their intersection. Example 1: Input: X1=0,Y1=0,R1=4 X2=6,Y2=0,R2=4 Output: 7 Explanation: The intersecting area equals 7.25298806.
Therefore, the real intersection of two spheres is a circle. The plane determined by this circle is perpendicular to the line connecting the centers of the spheres and this line passes through the center of this circle.
You can do the following:
s_start
, s_end
) where s_start
is in (-pi,pi] and s_end
in [s_start
,s_start+pi
).s0_start
< s1_start
now we have only 3 cases (a, b1, b2):
a) s1_start <= s0_end
: intersection, s1_start inside s0
b) s1_start > s0_end
:
b1) s0_start + 2*pi <= s1_end
: intersection, (s0_start + 2*pi) inside s1
b2) s0_start + 2*pi > s1_end
: no intersection
Thus we get the following code:
const double PI = 2.*acos(0.);
struct TSector { double a0, a1; };
// normalized range for angle
bool isNormalized(double a)
{ return -PI < a && a <= PI; }
// special normal form for sector
bool isNormalized(TSector const& s)
{ return isNormalized(s.a0) && s.a0 <= s.a1 && s.a1 < s.a0+PI; }
// normalize a sector to the special form:
// * -PI < a0 <= PI
// * a0 < a1 < a0+PI
void normalize(TSector& s)
{
assert(isNormalized(s.a0) && isNormalized(s.a1));
// choose a representation of s.a1 s.t. s.a0 < s.a1 < s.a0+2*PI
double a1_bigger = (s.a0 <= s.a1) ? s.a1 : s.a1+2*PI;
if (a1_bigger >= s.a0+PI)
std::swap(s.a0, s.a1);
if (s.a1 < s.a0)
s.a1 += 2*PI;
assert(isNormalized(s));
}
bool intersectionNormalized(TSector const& s0, TSector const& s1,
TSector& intersection)
{
assert(isNormalized(s0) && isNormalized(s1) && s0.a0 <= s1.a0);
bool isIntersecting = false;
if (s1.a0 <= s0.a1) // s1.a0 inside s0 ?
{
isIntersecting = true;
intersection.a0 = s1.a0;
intersection.a1 = std::min(s0.a1, s1.a1);
}
else if (s0.a0+2*PI <= s1.a1) // (s0.a0+2*PI) inside s1 ?
{
isIntersecting = true;
intersection.a0 = s0.a0;
intersection.a1 = std::min(s0.a1, s1.a1-2*PI);
}
assert(!isIntersecting || isNormalized(intersection));
return isIntersecting;
}
main()
{
TSector s0, s1;
s0.a0 = ...
normalize(s0);
normalize(s1);
if (s1.a0 < s0.a0)
std::swap(s0, s1);
TSection intersection;
bool isIntersection = intersectionNormalized(s0, s1, intersection);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With