Пример #1
0
    def _circle_tangents(self, other, invert_second_radius):
        "compute tangents as explained in \
        https://en.wikipedia.org/wiki/Tangent_lines_to_circles#Analytic_geometry"

        dx = other.pos.pos_x - self.pos.pos_x
        dy = other.pos.pos_y - self.pos.pos_y
        if not invert_second_radius:
            dr = other.radius - self.radius
        else:
            dr = -other.radius - self.radius
        d = sqrt(dx * dx + dy * dy)

        x = dx / d
        y = dy / d
        r = dr / d

        a1 = r * x - y * sqrt(1 - r * r)
        b1 = r * y + x * sqrt(1 - r * r)
        c1 = self.radius - (a1 * self.pos.pos_x + b1 * self.pos.pos_y)

        a2 = r * x + y * sqrt(1 - r * r)
        b2 = r * y - x * sqrt(1 - r * r)
        c2 = self.radius - (a2 * self.pos.pos_x + b2 * self.pos.pos_y)

        x11 = (b1 * (b1 * self.pos.pos_x - a1 * self.pos.pos_y) - a1 * c1)
        y11 = (a1 * (-b1 * self.pos.pos_x + a1 * self.pos.pos_y) - b1 * c1)

        x12 = (b1 * (b1 * other.pos.pos_x - a1 * other.pos.pos_y) - a1 * c1)
        y12 = (a1 * (-b1 * other.pos.pos_x + a1 * other.pos.pos_y) - b1 * c1)

        x21 = (b2 * (b2 * self.pos.pos_x - a2 * self.pos.pos_y) - a2 * c2)
        y21 = (a2 * (-b2 * self.pos.pos_x + a2 * self.pos.pos_y) - b2 * c2)

        x22 = (b2 * (b2 * other.pos.pos_x - a2 * other.pos.pos_y) - a2 * c2)
        y22 = (a2 * (-b2 * other.pos.pos_x + a2 * other.pos.pos_y) - b2 * c2)

        start1 = Vec2D(x11, y11)
        end1 = Vec2D(x12, y12)
        orient11 = Vec2D.orientation(end1, start1, self.pos)
        orient12 = Vec2D.orientation(start1, end1, other.pos)

        start2 = Vec2D(x21, y21)
        end2 = Vec2D(x22, y22)
        orient21 = Vec2D.orientation(end2, start2, self.pos)
        orient22 = Vec2D.orientation(start2, end2, other.pos)

        tan1 = Tangent(start1, self, orient11, end1, other, orient12)
        tan2 = Tangent(start2, self, orient21, end2, other, orient22)

        return [tan1, tan2]
Пример #2
0
    def _circle_tangents(self, other, invert_second_radius):
        "compute tangents as explained in \
        https://en.wikipedia.org/wiki/Tangent_lines_to_circles#Analytic_geometry"

        dx = other.pos.pos_x - self.pos.pos_x
        dy = other.pos.pos_y - self.pos.pos_y
        if not invert_second_radius:
            dr = other.radius - self.radius
        else:
            dr = - other.radius - self.radius
        d = sqrt(dx*dx + dy*dy)

        x = dx/d
        y = dy/d
        r = dr/d

        a1 = r*x - y*sqrt(1 - r*r)
        b1 = r*y + x*sqrt(1 - r*r)
        c1 = self.radius - (a1*self.pos.pos_x + b1*self.pos.pos_y)

        a2 = r*x + y*sqrt(1 - r*r)
        b2 = r*y - x*sqrt(1 - r*r)
        c2 = self.radius - (a2*self.pos.pos_x + b2*self.pos.pos_y)

        x11 = (b1*(b1*self.pos.pos_x - a1*self.pos.pos_y) - a1*c1)
        y11 = (a1*(-b1*self.pos.pos_x + a1*self.pos.pos_y) - b1*c1)

        x12 = (b1*(b1*other.pos.pos_x - a1*other.pos.pos_y) - a1*c1)
        y12 = (a1*(-b1*other.pos.pos_x + a1*other.pos.pos_y) - b1*c1)

        x21 = (b2*(b2*self.pos.pos_x - a2*self.pos.pos_y) - a2*c2)
        y21 = (a2*(-b2*self.pos.pos_x + a2*self.pos.pos_y) - b2*c2)

        x22 = (b2*(b2*other.pos.pos_x - a2*other.pos.pos_y) - a2*c2)
        y22 = (a2*(-b2*other.pos.pos_x + a2*other.pos.pos_y) - b2*c2)

        start1 = Vec2D(x11, y11)
        end1 = Vec2D(x12, y12)
        orient11 = Vec2D.orientation(end1, start1, self.pos)
        orient12 = Vec2D.orientation(start1, end1, other.pos)

        start2 = Vec2D(x21, y21)
        end2 = Vec2D(x22, y22)
        orient21 = Vec2D.orientation(end2, start2, self.pos)
        orient22 = Vec2D.orientation(start2, end2, other.pos)

        tan1 = Tangent(start1, self, orient11, end1, other, orient12)
        tan2 = Tangent(start2, self, orient21, end2, other, orient22)

        return [tan1, tan2]
    def test_orientation_colinear(self):
        "test that orientation returns (almost) zero for colinear points"

        vec1 = Vec2D(0, 0)
        vec2 = Vec2D(1, 0)
        vec3 = Vec2D(2, 0)

        self.assertAlmostEqual(0, Vec2D.orientation(vec1, vec2, vec3))
    def test_negative_orientation(self):
        "test that orientation returns postive value for positively oriented \
                points"
        vec1 = Vec2D(0, 0)
        vec2 = Vec2D(0, 1)
        vec3 = Vec2D(1, 0)

        self.assertTrue(Vec2D.orientation(vec1, vec2, vec3) < 0)
Пример #5
0
    def test_orientation_colinear(self):
        "test that orientation returns (almost) zero for colinear points"

        vec1 = Vec2D(0, 0)
        vec2 = Vec2D(1, 0)
        vec3 = Vec2D(2, 0)

        self.assertAlmostEqual(0, Vec2D.orientation(vec1, vec2, vec3))
Пример #6
0
    def test_negative_orientation(self):
        "test that orientation returns postive value for positively oriented \
                points"

        vec1 = Vec2D(0, 0)
        vec2 = Vec2D(0, 1)
        vec3 = Vec2D(1, 0)

        self.assertTrue(Vec2D.orientation(vec1, vec2, vec3) < 0)
def sort_points_on_circle(points, circle):
    "sort points by their angle on the circle"

    if not points:
        return []

    reference = points[0]
    rest = points[1:len(points)]

    sorted_points = sorted(
        rest, key=lambda p: Vec2D.orientation(reference, circle.pos, p))

    return [reference] + sorted_points
def sort_points_on_circle(points, circle):
    "sort points by their angle on the circle"

    if not points:
        return []

    reference = points[0]
    rest = points[1: len(points)]

    sorted_points = sorted(rest,
                           key=lambda p:
                           Vec2D.orientation(reference, circle.pos, p))

    return [reference] + sorted_points