예제 #1
0
    def getPaths(self):
        paths = Paths.Paths()
        paths.closed_paths = self._closed_paths
        for hash_lists in self._endpoints_map.values():
            for info in hash_lists:
                if info.point_index == 0:
                    paths.open_paths.append(info.path)

        for distance in [100, 250]:
            n = 0
            while n < len(paths.open_paths):
                m = self._findOpenPathCloseTo(paths.open_paths[n][-1], paths.open_paths, distance)
                if m is not None and m != n:
                    paths.open_paths[n] += paths.open_paths[m]
                    paths.open_paths.pop(m)
                    if m < n:
                        n -= 1
                    continue
                n += 1

        n = 0
        while n < len(paths.open_paths):
            if PointUtil.length(PointUtil.sub(paths.open_paths[n][0], paths.open_paths[n][-1])) < 200:
                paths.closed_paths.append(paths.open_paths[n])
                paths.open_paths.pop(n)
                continue
            n += 1

        return paths
예제 #2
0
 def _findClosestIndexTo(self, point, path):
     best = None
     best_distance = None
     for m in range(0, len(path)):
         distance = PointUtil.lengthSquared(PointUtil.sub(point, path[m]))
         if best_distance is None or best_distance > distance:
             best_distance = distance
             best = m
     return best
예제 #3
0
 def _orderStartPoints(self):
     if len(self._result.open_paths) > 1:
         start = self._result.open_paths[0][0]
         for n in range(1, len(self._result.open_paths)):
             if PointUtil.lengthSquared(PointUtil.sub(start, self._result.open_paths[n][0])) > PointUtil.lengthSquared(PointUtil.sub(start, self._result.open_paths[n][-1])):
                 self._result.open_paths[n].reverse()
             start = self._result.open_paths[n][-1]
     if len(self._result.closed_paths) > 1:
         start = self._result.closed_paths[0][0]
         for n in range(1, len(self._result.closed_paths)):
             best = self._findClosestIndexTo(start, self._result.closed_paths[n])
             self._result.closed_paths[n] = self._result.closed_paths[n][best:] + self._result.closed_paths[n][:best]
             start = self._result.closed_paths[n][0]
         best = self._findClosestIndexTo(self._result.closed_paths[1][0], self._result.closed_paths[0])
         self._result.closed_paths[0] = self._result.closed_paths[0][best:] + self._result.closed_paths[0][:best]
예제 #4
0
 def _findEndpoint(self, point):
     best = None
     best_hash = None
     best_distance = 10 * 10
     for hash in _hashes(point):
         if hash in self._endpoints_map:
             for info in self._endpoints_map[hash]:
                 p = info.path[info.point_index]
                 distance = PointUtil.lengthSquared(PointUtil.sub(p, point))
                 if distance < best_distance:
                     best_distance = distance
                     best_hash = hash
                     best = info
     if best is not None:
         self._endpoints_map[best_hash].remove(best)
     return best
예제 #5
0
 def _centerPoints(self, paths):
     center_points = []
     for poly in paths.closed_paths:
         center = (0, 0)
         for point in poly:
             center = PointUtil.add(center, point)
         center = (center[0] / len(poly), center[1] / len(poly))
         center_points.append(center)
     return center_points
예제 #6
0
 def _calculateClosedOrder(self, center_points):
     done = [False] * len(center_points)
     start = None
     for n in range(0, len(center_points)):
         if start is None or center_points[start][0] > center_points[n][0]:
             start = n
     if start is None:
         return []
     done[start] = True
     result = [start]
     while len(result) < len(center_points):
         best_distance = None
         best = None
         for n in range(0, len(center_points)):
             if done[n]:
                 continue
             distance = PointUtil.lengthSquared(PointUtil.sub(center_points[start], center_points[n]))
             if best_distance is None or best_distance > distance:
                 best_distance = distance
                 best = n
         done[best] = True
         result.append(best)
         start = best
     return result
예제 #7
0
 def _findOpenPathCloseTo(self, point, open_paths, distance):
     for n in range(0, len(open_paths)):
         if PointUtil.length(PointUtil.sub(open_paths[n][0], point)) < distance:
             return n
     return None
예제 #8
0
    def _calculateOpenOrder(self, paths):
        quick_finds = 0
        slow_finds = 0
        slow_time = 0.0
        Logger.log("i", "Line order optimizer, start")

        hash_map = {}
        for n in range(0, len(paths)):
            h = _hash(paths[n][0])
            if h not in hash_map:
                hash_map[h] = []
            hash_map[h].append(n)
            h = _hash(paths[n][-1])
            if h not in hash_map:
                hash_map[h] = []
            hash_map[h].append(n)

        todo = set(range(0, len(paths)))
        start = None
        for n in range(0, len(paths)):
            if start is None or paths[start][0][0] > paths[n][0][0]:
                start = n
        if start is None:
            return []
        todo.remove(start)
        result = [start]
        while len(result) < len(paths):
            best_distance = None
            best = None
            for h in _hashes(paths[start][0]):
                if h in hash_map:
                    for n in hash_map[h]:
                        if n not in todo:
                            continue
                        distance = min(
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][0], paths[n][0])),
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][0], paths[n][-1])),
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][-1], paths[n][0])),
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][-1], paths[n][-1]))
                        )
                        if best_distance is None or best_distance > distance:
                            best_distance = distance
                            best = n
            for h in _hashes(paths[start][-1]):
                if h in hash_map:
                    for n in hash_map[h]:
                        if n not in todo:
                            continue
                        distance = min(
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][0], paths[n][0])),
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][0], paths[n][-1])),
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][-1], paths[n][0])),
                            PointUtil.lengthSquared(PointUtil.sub(paths[start][-1], paths[n][-1]))
                        )
                        if best_distance is None or best_distance > distance:
                            best_distance = distance
                            best = n
            if best is None:
                slow_finds += 1
                t = time.time()
                for n in todo:
                    distance = min(
                        PointUtil.lengthSquared(PointUtil.sub(paths[start][0], paths[n][0])),
                        PointUtil.lengthSquared(PointUtil.sub(paths[start][0], paths[n][-1])),
                        PointUtil.lengthSquared(PointUtil.sub(paths[start][-1], paths[n][0])),
                        PointUtil.lengthSquared(PointUtil.sub(paths[start][-1], paths[n][-1]))
                    )
                    if best_distance is None or best_distance > distance:
                        best_distance = distance
                        best = n
                slow_time += time.time() - t
            else:
                quick_finds += 1
            todo.remove(best)
            result.append(best)
            start = best
        Logger.log("i", "Line order optimizer, quick: %d, slow: %d (%f)", quick_finds, slow_finds, slow_time)
        return result