Reputation: 689
I want to give the points [0,1],[1,0] and [0,-1] to python and plot the circle that passes over them. Does exists a python module that make this? I have tried using matplotlib:
import matplotlib.pyplot as plt
plt.plot([0,1,0],[1,0,-1])
plt.show()
But only gave me two lines.
Upvotes: 9
Views: 21234
Reputation: 4347
This code also lets you easily check whether the 3 points form a line or not.
def define_circle(p1, p2, p3):
"""
Returns the center and radius of the circle passing the given 3 points.
In case the 3 points form a line, returns (None, infinity).
"""
temp = p2[0] * p2[0] + p2[1] * p2[1]
bc = (p1[0] * p1[0] + p1[1] * p1[1] - temp) / 2
cd = (temp - p3[0] * p3[0] - p3[1] * p3[1]) / 2
det = (p1[0] - p2[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p2[1])
if abs(det) < 1.0e-6:
return (None, np.inf)
# Center of circle
cx = (bc*(p2[1] - p3[1]) - cd*(p1[1] - p2[1])) / det
cy = ((p1[0] - p2[0]) * cd - (p2[0] - p3[0]) * bc) / det
radius = np.sqrt((cx - p1[0])**2 + (cy - p1[1])**2)
return ((cx, cy), radius)
And to solve the original question:
center, radius = define_circle((0,1), (1,0), (0,-1))
if center is not None:
plt.figure(figsize=(4, 4))
circle = plt.Circle(center, radius)
plt.gcf().gca().add_artist(circle)
(Adjusted from here)
Upvotes: 19
Reputation: 6156
I was very curious why the accepted answer by Alex Martelli works. And I had to create a report for my lecture anyway, so I'm pasting it here for posterity.
Upvotes: 5
Reputation: 21
Given three points whose coordinates are:
(p,t) (q,u) (s,z)
...the equation of the circle defined by those three points is:
x^2 + y^2 + Ax + By + C = 0
where:
A=((u-t)*z^2+(-u^2+t^2-q^2+p^2)*z+t*u^2+(-t^2+s^2-p^2)*u+(q^2-s^2)*t)/((q-p)*z+(p-s)*u+(s-q)*t)
B=-((q-p)*z^2+(p-s)*u^2+(s-q)*t^2+(q-p)*s^2+(p^2-q^2)*s+p*q^2-p^2*q)/((q-p)*z+(p-s)*u+(s-q)*t)
C=-((p*u-q*t)*z^2+(-p*u^2+q*t^2-p*q^2+p^2*q)*z+s*t*u^2+(-s*t^2+p*s^2-p^2*s)*u+(q^2*s-q*s^2)*t)/((q-p)*z+(p-s)*u+(s-q)*t)
The above is the general solution. You can put the formulas for A, B, and C into your program and find the equation for any circle, given 3 points.
For your particular problem with points (0,1) (1,0) (0,-1) you will get:
A=0
B=0
C=-1
... so the equation will be
x^2 + y^2 -1 = 0 (the unit circle)
Upvotes: 2
Reputation: 881537
There was a "code golf" question exactly matching this (except that the circle's equation was requested, rather than plotting it) -- see https://codegolf.stackexchange.com/questions/2289/circle-through-three-points . Unraveling the first and shortest (Python) solution into more readable, less-hacky form to match your exact specs - but keeping the core idea of using complex numbers for simpler calculations:
x, y, z = 0+1j, 1+0j, 0-1j
w = z-x
w /= y-x
c = (x-y)*(w-abs(w)**2)/2j/w.imag-x
print '(x%+.3f)^2+(y%+.3f)^2 = %.3f^2' % (c.real, c.imag, abs(c+x))
OK, this still "prints the equation" rather than "plotting the circle", but, we're getting close:-). To actually plot the circle in matplotlib
, see e.g plot a circle with pyplot -- in the solution above, c
is the (negated) center of the circle (as a complex number, so use .real and .imag for the x/y coordinates), and abs(c+x)
the radius (a real number, abs
makes it so).
Upvotes: 18
Reputation: 3094
To draw a circle in matplotlib, first you need to declare an artist
circle = plt.Circle((0,0), 2)
you then have to add that artist to an instance of axes:
fig, ax = plt.subplots()
ax.add_artist(circle)
then you can draw it safely.
plt.show()
Notice that artist Circle
takes (x,y)
coordinates of the circle's center, and radius r
. That means you're going to have to calculate those values yourself.
Upvotes: 1