3
votes

I'm trying to find a way to calculate the intersection between two arcs. I need to use this to determine how much of an Arc is visually on the right half of a circle, and how much on the left. I though about creating an arc of the right half, and intersect that with the actual arc. But it takes me wayyy to much time to solve this, so I thought about asking here - someone must have done it before.

Edit: I'm sorry the previous illustration was provided when my head was too heavy after crunching angles. I'll try to explain again:

In this link you can see that I cut the arc in the middle to two halves, the right part of the Arc contains 135 degrees, and the left part has 90.

This Arc starts at -180 and ends at 45. (or starts at 180 and ends at 405 if normalized).

I have managed to create this code in order to calculate the amount of arc degrees contained in the right part, and in the left part:

f1 = (angle2>270.0f?270.0f:angle2) - (angle1<90.0f?90.0f:angle1);
if (f1 < 0.0f) f1 = 0.0f;
f2 = (angle2>640.0f?640.0f:angle2) - (angle1<450.0f?450.0f:angle1);
if (f2 < 0.0f) f2 = 0.0f;
f3 = (angle2>90.0f?90.0f:angle2) - angle1;
if (f3<0.0f) f3=0.0f;
f4 = (angle2>450.0f?450.0f:angle2) - (angle1<270.0f?270.0f:angle1); 
if (f4<0.0f) f4=0.0f;

It works great after normalizing the angles to be non-negative, but starting below 360 of course. Then f1 + f2 gives me the sum of the left half, and f3 + f4 gives me the sum of the right half. It also does not consider a case when the arc is defined as more than 360, which may be an "error" case.

BUT, this seems like more of a "workaround", and not a correct mathematical solution. I'm looking for a more elegant solution, which should be based on "intersection" between two arc (because math has no "sides", its not visual";

Thanks!!

2
An image illustrating what you mean would really help.freespace
In your image the left part contains 90deg surely ?High Performance Mark
Yeah I got confused. I'll fix it :-)daniel.gindi
What is your coordinate system? And how do you describe an arc? "Starting at -180 and ending in 135 degrees, clockwise" does not describe that image no matter how you turn it.Beta
I've edited to make this cleared. Thanks!daniel.gindi

2 Answers

2
votes

I think this works, but I haven't tested it thoroughly. You have 2 arcs and each arc has a start angle and a stop angle. I'll work this in degrees measured clockwise from north, as you have done, but it will be just as easy to work in radians measured anti-clockwise from east as the mathematicians do.

First 'normalise' your arcs, that is, reduce all the angles in them to lie in [0,360), so take out multiples of 360deg and make all the angles +ve. Make sure that the stop angle of each arc lies to clockwise of the start angle.

Next, choose the start angle of one of your arcs, it doesn't matter which. Sort all the angles you have (4 of them) into numerical order. If any of the angles are numerically smaller than the start angle you have chosen, add 360deg to them.

Re-sort the angles into increasing numerical order. Your chosen start angle will be the first element in the new list. From the start angle you already chose, what is the next angle in the list ?

1) If it is the stop angle of the same arc then either there is no overlap or this arc is entirely contained within the other arc. Make a note and find the next angle. If the next angle is the start angle of the other arc there is no overlap and you can stop; if it is the stop angle of the other arc then the overlap contains the whole of the first arc. Stop

2) If it is the start angle of the other arc, then the overlap begins at that angle. Make a note of this angle. The next angle your sweep encounters has to be a stop angle and the overlap ends there. Stop.

3) If it is the stop angle of the other arc then the overlap comprises the angle between the start angle of the first arc and this angle. Stop.

This isn't particularly elegant and relies on ifs rather more than I generally like but it should work and be relatively easy to translate into your favourite programming language.

And look, no trigonometry at all !

EDIT

Here's a more 'mathematical' approach since you seem to feel the need.

For an angle theta in (-pi,pi] the hyperbolic sine function (often called sinh) maps the angle to an interval on the real line in the interval (approximately) (-11.5,11.5]. Unlike arcsin and arccos the inverse of this function is also single-valued on the same interval. Follow these steps:

1) If an arc includes 0 break it into 2 arcs, (start,0) and (0,stop). You now have 2, 3 or 4 intervals on the real line.

2) Compute the intersection of those intervals and transform back from linear measurement into angular measurement. You now have the intersection of the two arcs.

2
votes

This test can be resumed with a one-line test. Even if a good answer is already posted, let me present mine.

Let assume that the first arc is A:(a0,a1) and the second arc is B:(b0,b1). I assume that the angle values are unique, i.e. in the range [0°,360°[, [0,2*pi[ or ]-pi,pi] (the range itself is not important, we will see why). I will take the range ]-pi,pi] as the range of all angles.


To explain in details the approach, I first design a test for interval intersection in R. Thus, we have here a1>=a0 and b1>=b0. Following the same notations for real intervals, I compute the following quantity:

S = (b0-a1)*(b1-a0)

If S>0, the two segments are not overlapping, else their intersection is not empty. It is indeed easy to see why this formula works. If S>0, we have two cases:

  • b0>a1 implies that b1>a0, so there is no intersection: a0=<a1<b0=<b1.

  • b1<a0 implies that b0<b1, so there is no intersection: b0=<b1<a0=<a1.

So we have a single mathematical expression which performs well in R.


Now I expand it over the circular domain ]-pi,pi]. The hypotheses a0<a1 and b0<b1 are not true anymore: for example, an arc can go from pi/2 to -pi/2, it is the left hemicircle. So I compute the following quantity:

S = (b0-a1)*(b1-a0)*H(a1-a0)*H(b1-b0)

where H is the step function defined by H(x)=-1 if x<0 else H(x)=1

Again, if S>0, there is no intersection between the arcs A and B. There are 16 cases to explore, and I will not do this here ... but it is easy to make them on a sheet :).

Remark: The value of S is not important, just the signs of the terms. The beauty of this formula is that it is independant from the range you have taken. Also, you can rewrite it as a logical test:

T := (b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0)

where ^ is logical XOR


EDIT

Alas, there is an obvious failure case in this formula ... So I correct it here. I realize that htere is a case where the intersection of the two arcs can be two arcs, for example when -pi<a0<b1<b0<a1<pi.

The solution to correct this is to introduce a second test: if the sum of the angles is above 2*pi, the arcs intersect for sure.

So the formula turns out to be:

T := (a1+b1-a0-b0+2*pi*((b1<b0)+(a1<a0))<2*pi) | ((b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0))

Ok, it is way less elegant than the previous one, but it is now correct.