Beispiel #1
0
class OrderShortestPath(OrderHandler):
    """  This uses Dijkstra's algorithm to find the shortest path.

    """
    name = QApplication.translate("job", "Shortest Path")
    time_limit = 0.2  # This is in the UI thread

    def order(self, job, path):
        """ Sort subpaths by minimizing the distances between all start
        and end points.

        """
        subpaths = split_painter_path(path)
        log.debug("Subpath count: {}".format(len(subpaths)))

        # Cache all start and end points
        time_limit = time() + self.time_limit
        zero = QVector2D(0, 0)
        for sp in subpaths:
            # Average start and end into one "vertex"
            start = sp.elementAt(0)
            end = sp.elementAt(sp.elementCount() - 1)
            sp.start_point = QVector2D(start.x, start.y)
            sp.end_point = QVector2D(end.x, end.y)

        distance = QVector2D.distanceToPoint
        original = subpaths[:]
        result = []
        p = zero
        while subpaths:
            best = sys.maxsize
            shortest = None
            for sp in subpaths:
                d = distance(p, sp.start_point)
                if d < best:
                    best = d
                    shortest = sp

            p = shortest.end_point
            result.append(shortest)
            subpaths.remove(shortest)

            # time.time() is slow so limit the calls
            if time() > time_limit:
                result.extend(subpaths)  # At least part of it is optimized
                log.debug("Shortest path search aborted (time limit reached)")
                break
        d = self.subpath_move_distance(zero, original)
        d = d - self.subpath_move_distance(zero, result)
        log.debug("Shortest path search: Saved {} in of movement ".format(
            to_unit(d, 'in')))
        return join_painter_paths(result)

    def subpath_move_distance(self, p, subpaths, limit=sys.maxsize):
        # Collect start and end points
        d = 0

        # Local ref saves a lookup per iter
        distance = QVector2D.distanceToPoint
        for sp in subpaths:
            d += distance(p, sp.start_point)
            if d > limit:
                break  # Over the limit already abort
            p = sp.end_point
        return d
Beispiel #2
0
class OrderReversed(OrderHandler):
    name = QApplication.translate("job", "Reversed")

    def order(self, job, path):
        return path.toReversed()
Beispiel #3
0
class OrderMaxY(OrderHandler):
    name = QApplication.translate("job", 'Max Y')

    def order(self, job, path):
        return self.order_by_func(job, path, lambda p: p.boundingRect().top())
Beispiel #4
0
class OrderNormal(OrderHandler):
    name = QApplication.translate("job", "Normal")

    def order(self, job, path):
        return path
Beispiel #5
0
def tr(*args, **kwargs):
    """ Alias to translate """
    from enaml.qt.QtWidgets import QApplication
    return QApplication.translate(*args, **kwargs)