Created
February 12, 2018 00:35
-
-
Save agea/059dcd41316b35e8b9406875428cc3a2 to your computer and use it in GitHub Desktop.
Circle Intersection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
http://paulbourke.net/geometry/circlesphere/ | |
Created on Sat Apr 8th 2017 | |
Circle Intersection | |
@PythonVer: Tested in 2.7.10 and 3.6 | |
@Author: Matt Woodhead | |
A note on angle convention: | |
+y | |
| / | |
| / | |
| / +ve Theta | |
| / ) | |
±180 degrees -x ----------------- +ve x 0 degrees | |
| \ ) | |
| \ -ve Theta | |
| \ | |
| \ | |
-y | |
The outputs are ordered from the angle of the lines drawn from the intersection | |
points to the centre of the first circle, from +180 degrees to -180 degrees. | |
""" | |
import math | |
PRECISION = 5 # Decimal point precision | |
class Circle(object): | |
""" An OOP implementation of a circle as an object """ | |
def __init__(self, xposition, yposition, radius): | |
self.xpos = xposition | |
self.ypos = yposition | |
self.radius = radius | |
def circle_intersect(self, circle2): | |
""" | |
Intersection points of two circles using the construction of triangles | |
as proposed by Paul Bourke, 1997. | |
http://paulbourke.net/geometry/circlesphere/ | |
""" | |
X1, Y1 = self.xpos, self.ypos | |
X2, Y2 = circle2.xpos, circle2.ypos | |
R1, R2 = self.radius, circle2.radius | |
Dx = X2-X1 | |
Dy = Y2-Y1 | |
D = round(math.sqrt(Dx**2 + Dy**2), PRECISION) | |
# Distance between circle centres | |
if D > R1 + R2: | |
return "The circles do not intersect" | |
elif D < math.fabs(R2 - R1): | |
return "No Intersect - One circle is contained within the other" | |
elif D == 0 and R1 == R2: | |
return "No Intersect - The circles are equal and coincident" | |
else: | |
if D == R1 + R2 or D == R1 - R2: | |
CASE = "The circles intersect at a single point" | |
else: | |
CASE = "The circles intersect at two points" | |
chorddistance = (R1**2 - R2**2 + D**2)/(2*D) | |
# distance from 1st circle's centre to the chord between intersects | |
halfchordlength = math.sqrt(R1**2 - chorddistance**2) | |
chordmidpointx = X1 + (chorddistance*Dx)/D | |
chordmidpointy = Y1 + (chorddistance*Dy)/D | |
I1 = (round(chordmidpointx + (halfchordlength*Dy)/D, PRECISION), | |
round(chordmidpointy - (halfchordlength*Dx)/D, PRECISION)) | |
theta1 = round(math.degrees(math.atan2(I1[1]-Y1, I1[0]-X1)), | |
PRECISION) | |
I2 = (round(chordmidpointx - (halfchordlength*Dy)/D, PRECISION), | |
round(chordmidpointy + (halfchordlength*Dx)/D, PRECISION)) | |
theta2 = round(math.degrees(math.atan2(I2[1]-Y1, I2[0]-X1)), | |
PRECISION) | |
if theta2 > theta1: | |
I1, I2 = I2, I1 | |
return (I1, I2, CASE) | |
# Main program: | |
C1 = Circle(0, 0, 350) | |
C2 = Circle(-130, 120, 250) | |
print(C1.circle_intersect(C2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment