コード例 #1
0
    def __init__(self, points):
        self.output = [] # list of line segment
        self.arc = None  # binary tree for parabola arcs

        self.points = PriorityQueue() # site events
        self.event = PriorityQueue() # circle events

        # bounding box
        self.x0 = -50.0
        self.x1 = -50.0
        self.y0 = 550.0
        self.y1 = 550.0

        # insert points to site event
        for pts in points:
            point = Point(pts[0], pts[1])
            self.points.push(point)
            # keep track of bounding box size
            if point.x < self.x0: self.x0 = point.x
            if point.y < self.y0: self.y0 = point.y
            if point.x > self.x1: self.x1 = point.x
            if point.y > self.y1: self.y1 = point.y

        # add margins to the bounding box
        dx = (self.x1 - self.x0 + 1) / 5.0
        dy = (self.y1 - self.y0 + 1) / 5.0
        self.x0 = self.x0 - dx
        self.x1 = self.x1 + dx
        self.y0 = self.y0 - dy
        self.y1 = self.y1 + dy
コード例 #2
0
ファイル: Voronoi.py プロジェクト: tnakaicode/OCC_Voronoi
    def intersection(self, 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
コード例 #3
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
def find_circle_center(a, b, c):
    # check if bc is a "right turn" from ab - det
    if ((b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y)) < 0:
        return 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 None, None  # Points are co-linear

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

    max_x = ox + math.sqrt((a.x - ox)**2 + (a.y - oy)**2)
    o = Point(ox, oy)

    return max_x, o
コード例 #4
0
ファイル: Voronoi.py プロジェクト: tnakaicode/OCC_Voronoi
    def circle(self, a, b, c):
        # check if bc is a "right turn" from ab
        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
コード例 #5
0
    def arc_insert(self, p):
        if self.arc is None:
            self.arc = Arc(p)
        else:
            # find the current arcs at p.y
            i = self.arc
            while i is not None:
                flag, z = self.intersect(p, i)
                if flag:
                    # new parabola intersects arc i
                    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

                    # add p between i and i.pnext
                    i.pnext.pprev = Arc(p, i, i.pnext)
                    i.pnext = i.pnext.pprev

                    i = i.pnext # now i points to the new arc

                    # add new half-edges connected to i's endpoints
                    seg = Segment(z)
                    self.output.append(seg)
                    i.pprev.s1 = i.s0 = seg

                    seg = Segment(z)
                    self.output.append(seg)
                    i.pnext.s0 = i.s1 = seg

                    # check for new circle events around the new arc
                    self.check_circle_event(i, p.x)
                    self.check_circle_event(i.pprev, p.x)
                    self.check_circle_event(i.pnext, p.x)

                    return
                        
                i = i.pnext

            # if p never intersects an arc, append it to the list
            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)
            i.s1 = i.pnext.s0 = seg
            self.output.append(seg)
コード例 #6
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
 def finish_edges(self):
     limit = self.RIGHT + (self.RIGHT - self.LEFT) + (self.BOTTOM -
                                                      self.TOP)
     arc = self.beach_line
     while arc.next is not None:
         if arc.lower_edge is not None:
             point = find_intersection_of_parabolas(arc.point,
                                                    arc.next.point,
                                                    limit * 2.0)
             arc.lower_edge.finish(Point(-1 * point.x, -1 * point.y))
         arc = arc.next
コード例 #7
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
def calculate_parabolas_intersection(parabola1, parabola2, sweep_line):
    z0 = 2.0 * (parabola1.x - sweep_line)
    z1 = 2.0 * (parabola2.x - sweep_line)

    a = 1.0 / z0 - 1.0 / z1
    b = -2.0 * (parabola1.y / z0 - parabola2.y / z1)
    c = 1.0 * (parabola1.y**2 + parabola1.x**2 - sweep_line**2) / z0 - 1.0 * (
        parabola2.y**2 + parabola2.x**2 - sweep_line**2) / z1

    py = 1.0 * (-b - math.sqrt(b * b - 4 * a * c)) / (2 * a)
    px = 1.0 * (parabola1.x**2 + (parabola1.y - py)**2 -
                sweep_line**2) / (2 * parabola1.x - 2 * sweep_line)

    return Point(px, py)
コード例 #8
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
def find_intersection_of_parabolas(parabola1, parabola2, sweep_line):
    p = parabola1
    if parabola1.x == parabola2.x:
        py = (parabola1.y + parabola2.y) / 2.0
    elif parabola2.x == sweep_line:
        py = parabola2.y
    elif parabola1.x == sweep_line:
        py = parabola1.y
        p = parabola2
    else:
        return calculate_parabolas_intersection(parabola1, parabola2,
                                                sweep_line)

    px = (p.x**2 + (p.y - py)**2 - sweep_line**2) / (2 * p.x - 2 * sweep_line)
    res = Point(px, py)
    return res
コード例 #9
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
 def finish_edges_with_visualization(self):
     limit = self.RIGHT + (self.RIGHT - self.LEFT) + (self.BOTTOM -
                                                      self.TOP)
     arc = self.beach_line
     while arc.next is not None:
         if arc.lower_edge is not None:
             point = find_intersection_of_parabolas(arc.point,
                                                    arc.next.point,
                                                    limit * 2.0)
             arc.lower_edge.finish(Point(-1 * point.x, -1 * point.y))
             self.scenes.append(
                 Scene([
                     PointsCollection(self.points, color='red'),
                     PointsCollection(self.get_voronoi_points(),
                                      color='blue')
                 ], [LinesCollection(self.get_voronoi_lines())]))
         arc = arc.next
コード例 #10
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
コード例 #11
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
    def insert_arc(self, point):
        if self.beach_line is None:
            self.beach_line = Arc(point)
            return

        if self.insert_arc_among_existing(point):
            return

        arc = self.beach_line
        while arc.next is not None:
            arc = arc.next
        arc.next = Arc(point, arc)

        x = self.LEFT
        y = (arc.next.point.y + arc.point.y) / 2.0
        start = Point(x, y)

        edge = Edge(start)
        arc.lower_edge = arc.next.upper_edge = edge
        self.voronoi.append(edge)
コード例 #12
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
    def create_bounding_box(self, points):
        for pts in points:
            point = Point(pts[0], pts[1])
            self.events.push(point)

            if point.x < self.LEFT:
                self.LEFT = point.x
            if point.y < self.TOP:
                self.TOP = point.y
            if point.x > self.RIGHT:
                self.RIGHT = point.x
            if point.y > self.BOTTOM:
                self.BOTTOM = point.y

        dx = (self.RIGHT - self.LEFT + 1) / 5.0
        dy = (self.BOTTOM - self.TOP + 1) / 5.0
        self.LEFT = self.LEFT - dx
        self.RIGHT = self.RIGHT + dx
        self.TOP = self.TOP - dy
        self.BOTTOM = self.BOTTOM + dy
コード例 #13
0
ファイル: pomocy.py プロジェクト: Kmiotek/ProjektGeometryczne
def check_if_arc_intersects(point, arc):
    if arc is None:
        return None
    if arc.point.x == point.x:
        return None

    upper_intersection_y = 0
    lower_intersection_y = 0

    if arc.prev is not None:
        upper_intersection_y = (find_intersection_of_parabolas(
            arc.prev.point, arc.point, point.x)).y
    if arc.next is not None:
        lower_intersection_y = (find_intersection_of_parabolas(
            arc.point, arc.next.point, point.x)).y

    if (arc.prev is None or upper_intersection_y <= point.y) and (
            arc.next is None or point.y <= lower_intersection_y):
        py = point.y
        px = (arc.point.x**2 + (arc.point.y - py)**2 -
              point.x**2) / (2 * arc.point.x - 2 * point.x)
        return Point(px, py)
    return None