예제 #1
0
    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)"
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
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
예제 #5
0
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)"