Пример #1
0
    def intersection(p0, p1, l):
        # get the intersection of two parabolas
        p = p0
        if p0.x == p1.x:
            py = (p0.y + p1.y) / 2.0
        elif p1.x == l:
            py = p1.y
        elif p0.x == l:
            py = p0.y
            p = p1
        else:
            # use quadratic formula
            z0 = 2.0 * (p0.x - l)
            z1 = 2.0 * (p1.x - l)

            a = 1.0 / z0 - 1.0 / z1
            b = -2.0 * (p0.y / z0 - p1.y / z1)
            c = 1.0 * (p0.y**2 + p0.x**2 -
                       l**2) / z0 - 1.0 * (p1.y**2 + p1.x**2 - l**2) / z1

            py = 1.0 * (-b - math.sqrt(b * b - 4 * a * c)) / (2 * a)

        px = 1.0 * (p.x**2 + (p.y - py)**2 - l**2) / (2 * p.x - 2 * l)
        res = Point(px, py)
        return res
Пример #2
0
    def circle(self, a, b, c):
        if ((b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y)) > 0:
            return False, None, None

        # Joseph O'Rourke, Computational Geometry in C (2nd ed.) p.189
        A = b.x - a.x
        B = b.y - a.y
        C = c.x - a.x
        D = c.y - a.y
        E = A * (a.x + b.x) + B * (a.y + b.y)
        F = C * (a.x + c.x) + D * (a.y + c.y)
        G = 2 * (A * (c.y - b.y) - B * (c.x - b.x))

        if G == 0:
            return False, None, None  # Points are co-linear

        # point o is the center of the circle
        ox = 1.0 * (D * E - B * F) / G
        oy = 1.0 * (A * F - C * E) / G

        # o.x plus radius equals max x coord
        x = ox + math.sqrt((a.x - ox)**2 + (a.y - oy)**2)
        o = Point(ox, oy)

        return True, x, o
Пример #3
0
def bresenham_line(p1, p2):
    x0 = p1.x
    x1 = p2.x
    y0 = p1.y
    y1 = p2.y

    dx = x1 - x0
    dy = y1 - y0

    xsign = 1 if dx > 0 else -1
    ysign = 1 if dy > 0 else -1

    dx = abs(dx)
    dy = abs(dy)

    if dx > dy:
        xx, xy, yx, yy = xsign, 0, 0, ysign
    else:
        dx, dy = dy, dx
        xx, xy, yx, yy = 0, ysign, xsign, 0

    D = 2 * dy - dx
    y = 0

    for x in range(dx + 1):
        yield Point(x0 + x * xx + y * yx, y0 + x * xy + y * yy)
        if D > 0:
            y += 1
            D -= dx
        D += dy
Пример #4
0
def read_points(filename):
    book = open_workbook(filename)
    position_sheet = book.sheet_by_index(0)
    value_sheet = book.sheet_by_index(1)

    d = dict()
    for row in range(1, position_sheet.nrows):
        key = position_sheet.cell(row, 0).value
        x = position_sheet.cell(row, 1).value
        y = position_sheet.cell(row, 2).value
        d[key] = Point(key, x, y)

    for row in range(1, value_sheet.nrows):
        key = value_sheet.cell(row, 0).value
        val = value_sheet.cell(row, 1).value
        d[key].val = val

    return d.values()
Пример #5
0
 def __init__(self, points, check=True):
     self.points = [Point(*x) for x in points]
     if len(self.points) < 3:
         raise ValueError('Not a polygon')
     self.edges = self.gen_edges()
     if check and not (self.check_convex()
                       and self.check_self_intersection()
                       and self.check_num_of_edges()):
         raise ValueError('Not convex')
     self.bbb = []
     self.circles = None
Пример #6
0
    def voronoi(self):
        test = set()
        for e in self.edges:
            i = 0
            for u in bresenham_line(*e.points):
                if i % 20 == 0:
                    test.add(u)
                i += 1
        v = Voronoi(test)
        v.process()
        self.bbb = []
        voronoi_res = []
        ddd = {}
        for e in v.output:
            p01 = round(e.points[0].x), round(e.points[0].y)
            p02 = round(e.points[1].x), round(e.points[1].y)

            if p01 == p02:
                continue
            if p01 in ddd:
                ddd[p01] += 1
            else:
                ddd[p01] = 1
            p1 = Point(*p01)
            p2 = Point(*p02)
            voronoi_res.append(Segment(p1, p2))

        for e in voronoi_res:
            p1 = e.points[0]
            p2 = e.points[1]
            if self.check_point_inside_polygon(p1) and \
                    self.check_point_inside_polygon(p2) and \
                    not self.check_point_on_edge(p1) and \
                    not self.check_point_on_edge(p2):
                self.bbb.append(e)

        self.filter_bbb(voronoi_res, ddd)
Пример #7
0
    def arc_insert(self, p):
        if self.arc is None:
            self.arc = Arc(p)
        else:
            i = self.arc
            while i is not None:
                flag, z = self.intersect(p, i)
                if flag:
                    flag, zz = self.intersect(p, i.pnext)
                    if (i.pnext is not None) and (not flag):
                        i.pnext.pprev = Arc(i.p, i, i.pnext)
                        i.pnext = i.pnext.pprev
                    else:
                        i.pnext = Arc(i.p, i)
                    i.pnext.s1 = i.s1
                    i.pnext.pprev = Arc(p, i, i.pnext)
                    i.pnext = i.pnext.pprev
                    i = i.pnext  # now i points to the new arc
                    seg = Segment(z, None)
                    self.output.append(seg)
                    i.pprev.s1 = i.s0 = seg
                    seg = Segment(z, None)
                    self.output.append(seg)
                    i.pnext.s0 = i.s1 = seg
                    self.check_circle_event(i)
                    self.check_circle_event(i.pprev)
                    self.check_circle_event(i.pnext)
                    return
                i = i.pnext

            i = self.arc
            while i.pnext is not None:
                i = i.pnext
            i.pnext = Arc(p, i)

            # insert new segment between p and i
            x = self.x0
            y = (i.pnext.p.y + i.p.y) / 2.0
            start = Point(x, y)

            seg = Segment(start, None)
            i.s1 = i.pnext.s0 = seg
            self.output.append(seg)
Пример #8
0
    def intersect(self, p, i):
        # check whether a new parabola at point p intersect with arc i
        if i is None:
            return False, None
        if i.p.x == p.x:
            return False, None

        a = 0.0
        b = 0.0

        if i.pprev is not None:
            a = (self.intersection(i.pprev.p, i.p, 1.0 * p.x)).y
        if i.pnext is not None:
            b = (self.intersection(i.p, i.pnext.p, 1.0 * p.x)).y

        if (((i.pprev is None) or (a <= p.y))
                and ((i.pnext is None) or (p.y <= b))):
            py = p.y
            px = 1.0 * (i.p.x**2 +
                        (i.p.y - py)**2 - p.x**2) / (2 * i.p.x - 2 * p.x)
            res = Point(px, py)
            return True, res
        return False, None