def cover(self, other): # okrąg pokrywający oba if self.pt.distance(other.pt) <= (max(self.radius, other.radius) - min(self.radius, other.radius)): if other.radius >= self.radius: return other else: return self x = (self.pt.x + other.pt.x) / 2 y = (self.pt.y + other.pt.y) / 2 vector = Point(x / Point(x, y).length(), y / Point(x, y).length()) center = Point() center.x = vector.x * (self.radius + other.radius + \ Point(self.pt.x, self.pt.y).distance( Point(other.pt.x, other.pt.y))) / 2 - self.radius * vector.x center.y = vector.y * (self.radius + other.radius + \ Point(self.pt.x, self.pt.y).distance( Point(other.pt.x, other.pt.y))) / 2 - self.radius * vector.y rad = center.distance(self.pt) + self.radius return Circle(center.x, center.y, rad) #distance to funkcja licząca odległość między dwoma punktami," #znajduje się w clasie Point" # def distance(self, other): # return sqrt((self.x-other.x)**2+(self.y-other.y)**2)"
def test_distance(self): a = Point(0,0) b = Point(3,4) c = Point(2,0) error_msg1 = "incorrect distance between (%d, %d) and (%d, %d)" % (a.x, a.y, c.x, c.y) error_msg2 = "incorrect distance between (%d, %d) and (%d, %d)" % (a.x, a.y, b.x, b.y) self.assertEqual(a.distance(c), 2, error_msg1) self.assertEqual(a.distance(b), 5, error_msg2)
def test_distance(self): a = Point(0, 0) b = Point(3, 4) c = Point(2, 0) error_msg1 = "incorrect distance between (%d, %d) and (%d, %d)" % (a.x, a.y, c.x, c.y) error_msg2 = "incorrect distance between (%d, %d) and (%d, %d)" % (a.x, a.y, b.x, b.y) self.assertEqual(a.distance(c), 2, error_msg1) self.assertEqual(a.distance(b), 5, error_msg2)
def fit_cirlce(pp, warnIfIllDefined=True): """ fit_cirlce(pp, warnIfIllDefined=True) Calculate the circle (x - c.x)**2 + (y - x.y)**2 = c.r**2 From the set of points pp. Returns a point instance with an added attribute "r" specifying the radius. In case the three points are on a line, the algorithm will fail, and return 0 for x,y and r. This waring can be suppressed. The solution is a Least Squares fit. The method as describes in [1] is called Modified Least Squares (MLS) and poses a closed form solution which is very robust. [1] Dale Umbach and Kerry N. Jones 2000 A Few Methods for Fitting Circles to Data IEEE Transactions on Instrumentation and Measurement """ # Init error point ce = Point(0,0) ce.r = 0.0 def cov(a, b): n = len(a) Ex = a.sum() / n Ey = b.sum() / n return ( (a-Ex)*(b-Ey) ).sum() / (n-1) # Get x and y elements X = pp[:,0] Y = pp[:,1] # In the paper there is a factor n*(n-1) in all equations below. However, # this factor is removed by devision in the equations in the following cell A = cov(X,X) B = cov(X,Y) C = cov(Y,Y) D = 0.5 * ( cov(X,Y**2) + cov(X,X**2) ) E = 0.5 * ( cov(Y,X**2) + cov(Y,Y**2) ) # Calculate denumerator denum = A*C - B*B if denum==0: if warnIfIllDefined: print("Warning: can not fit a circle to the given points.") return ce # Calculate point c = Point( (D*C-B*E)/denum, (A*E-B*D)/denum ) # Calculate radius c.r = c.distance(pp).sum() / len(pp) # Done return c
class Circle: """Klasa reprezentująca okręgi na płaszczyźnie.""" #center = Point(int x, int y) #int radius def __init__(self, x, y, radius): if radius < 0: print("promień ujemny") raise ValueError self.pt = Point(x, y) self.radius = radius def __repr__(self): # "Circle(x, y, radius)" return "Circle({}, {}, {})".format(self.pt.x, self.pt.y, self.radius) def __eq__(self, other): return self.pt == other.pt and self.radius == other.radius def __ne__(self, other): return not self == other def area(self): # pole powierzchni return pi * self.radius * self.radius def move(self, x, y): # przesuniecie o (x, y) a = self.pt.x + x b = self.pt.y + y return Circle(a, b, self.radius) def cover(self, other): # okrąg pokrywający oba if self.pt.distance(other.pt) <= (max(self.radius, other.radius) - min(self.radius, other.radius)): if other.radius >= self.radius: return other else: return self x = (self.pt.x + other.pt.x) / 2 y = (self.pt.y + other.pt.y) / 2 vector = Point(x / Point(x, y).length(), y / Point(x, y).length()) center = Point() center.x = vector.x * (self.radius + other.radius + \ Point(self.pt.x, self.pt.y).distance( Point(other.pt.x, other.pt.y))) / 2 - self.radius * vector.x center.y = vector.y * (self.radius + other.radius + \ Point(self.pt.x, self.pt.y).distance( Point(other.pt.x, other.pt.y))) / 2 - self.radius * vector.y rad = center.distance(self.pt) + self.radius return Circle(center.x, center.y, rad) #distance to funkcja licząca odległość między dwoma punktami," #znajduje się w clasie Point" # def distance(self, other): # return sqrt((self.x-other.x)**2+(self.y-other.y)**2)"