def test_quad_tree_performance(self): runs = 5 success = True print("\n === SUPER SPARSE === \n") for i in range(runs): success = QuadTreeTests.run_quad_tree_performance_test( BoundingBox(0, 1000, 0, 1000), 1500, 8) and success print("\n === SPARSE === \n") for i in range(runs): success = QuadTreeTests.run_quad_tree_performance_test( BoundingBox(0, 1000, 0, 1000), 1500, 80) and success print("\n === DENSE === \n") for i in range(runs): success = QuadTreeTests.run_quad_tree_performance_test( BoundingBox(0, 1000, 0, 1000), 1500, 250) and success print("\n === SUPER DENSE === \n") for i in range(runs): success = QuadTreeTests.run_quad_tree_performance_test( BoundingBox(0, 1000, 0, 1000), 1500, 600) and success print( "\n === SUPER DENSE with multiple bounding boxes per segment === \n" ) for i in range(runs): success = QuadTreeTests.run_quad_tree_performance_test( BoundingBox(0, 1000, 0, 1000), 1500, 600, True) and success self.assertTrue(success)
def __init__(self, data, max_partitions=None, k=None, split_method='min_var'): """ :type data: pyspark.RDD :param data: pyspark RDD (key, k-dim vector like) :type max_partitions: int :param max_partitions: maximum number of partition to split into :type k: int :param k: dimensionality of the data :type split_method: str :param split_method: method for splitting on axis - 'min_var' minimizes the variance in each partition, 'rotation' cycles through the axis Split a given data set into approximately equal sized partition (if max_partitions is a power of 2 ** k) using binary tree methods """ self.split_method = split_method \ if split_method in ['min_var', 'rotation'] else 'min_var' self.k = int(k) if k is not None else len(data.first()[1]) self.max_partitions = int( max_partitions) if max_partitions is not None else 4**self.k data.cache() box = data.aggregate(BoundingBox(k=self.k), lambda total, (_, v): total.union(BoundingBox(v)), lambda total, v: total.union(v)) first_partition = data.map(lambda (key, value): ((key, 0), value)) self._create_partitions(first_partition, box) self.result = data.context.emptyRDD() for partition in self.partitions.itervalues(): self.result = self.result.union(partition)
def break_bounding_box_into_quadrants(bounding_box): """Return four bounding boxes representing four quadrants of a given bounding box.""" x_middle = (bounding_box.x_lower + bounding_box.x_upper) / 2 y_middle = (bounding_box.y_lower + bounding_box.y_upper) / 2 return (BoundingBox(bounding_box.x_lower, x_middle, bounding_box.y_lower, y_middle), BoundingBox(x_middle, bounding_box.x_upper, bounding_box.y_lower, y_middle), BoundingBox(bounding_box.x_lower, x_middle, y_middle, bounding_box.y_upper), BoundingBox(x_middle, bounding_box.x_upper, y_middle, bounding_box.y_upper))
def test_quad_tree_load_test(self): quad_tree = QuadTree(BoundingBox(0, 100, 0, 100)) points_bounding_box = BoundingBox(-10, 110, -10, 110) for i in range(200): point1 = QuadTreeTests.random_point(points_bounding_box) point2 = QuadTreeTests.random_point(points_bounding_box) while point1 == point2: point2 = QuadTreeTests.random_point(points_bounding_box) quad_tree.add(LineSegment(point1, point2)) self.assertTrue( type(quad_tree.get(BoundingBox(10, 90, 10, 90))) is list)
def _draw_box(self): line_thickness = self.settings.get('line_thickness') delta = line_thickness / 2 + self.settings.get('boxgap') bbox = BoundingBox() for line in self.coords: bbox.extend(line[0], line[2], line[1], line[3]) bbox.pad(delta) self.coords.append([bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymin, 0, 0]) self.coords.append([bbox.xmax, bbox.ymin, bbox.xmax, bbox.ymax, 0, 0]) self.coords.append([bbox.xmax, bbox.ymax, bbox.xmin, bbox.ymax, 0, 0]) self.coords.append([bbox.xmin, bbox.ymax, bbox.xmin, bbox.ymin, 0, 0])
def from_dict(cls, d): '''Constructs a DetectedObject from a JSON dictionary.''' return cls( d["label"], d["confidence"], BoundingBox.from_dict(d["bounding_box"]), )
def test_non_including_bounding_boxes_intersection(self): self.assertTrue( do_bounding_boxes_intersect_not_including_upper_limits( BoundingBox(1, 2, 1, 2), BoundingBox(0, 10, 0, 10))) self.assertFalse( do_bounding_boxes_intersect_not_including_upper_limits( BoundingBox(10, 11, 1, 2), BoundingBox(0, 10, 0, 10))) self.assertFalse( do_bounding_boxes_intersect_not_including_upper_limits( BoundingBox(1, 2, 10, 12), BoundingBox(0, 10, 0, 10))) self.assertFalse( do_bounding_boxes_intersect_not_including_upper_limits( BoundingBox(10, 12, 10, 12), BoundingBox(0, 10, 0, 10)))
def get_line_segment_multiple_bounding_boxes(segment, count): x_step = (segment.end.x - segment.start.x) / count y_step = (segment.end.y - segment.start.y) / count result = [] for i in range(count): result.append( BoundingBox(segment.start.x + x_step * i, segment.start.x + x_step * (i + 1), segment.start.y + y_step * i, segment.start.y + y_step * (i + 1))) return result
def get_bounding_box(self): w = 0 # TODO: take border into account max_ascender = max_descender = -10000 for i, child in enumerate(self._children): bbox = child.get_bounding_box() if bbox.ascender > max_ascender: max_ascender = bbox.ascender if bbox.descender > max_descender: max_descender = bbox.descender if i > 0: w += self.spacing w += bbox.w return BoundingBox(w, max_ascender, max_descender)
def _draw_box(self): line_thickness = self.settings.get('line_thickness') delta = line_thickness / 2 + self.settings.get('boxgap') bbox = BoundingBox() for line in self.coords: bbox.extend(line[0], line[2], line[1], line[3]) bbox.pad(delta) self.coords.append([bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymin, 0, 0]) self.coords.append([bbox.xmax, bbox.ymin, bbox.xmax, bbox.ymax, 0, 0]) self.coords.append([bbox.xmax, bbox.ymax, bbox.xmin, bbox.ymax, 0, 0]) self.coords.append([bbox.xmin, bbox.ymax, bbox.xmin, bbox.ymin, 0, 0])
def get_bounding_box(self): cbox = self.font.compute_control_box(self._caption) # FIXME: for now, we just add a fixed-width border, but this should be injected by the box model return BoundingBox(cbox.width + 6, cbox.y_max + 3, -cbox.y_min + 3)
def job_text(self): self.text = MyText() if self.settings.get('cut_type') == CUT_TYPE_VCARVE: thickness = 0.0 else: thickness = self.settings.get('line_thickness') self.text.set_font(self.font) self.text.set_char_space(self.settings.get('char_space')) self.text.set_line_space(self.settings.get('line_space')) self.text.set_word_space(self.settings.get('word_space')) self.text.set_thickness(thickness) # the text to be carved or engraved if len(self.settings.get('default_text')) > 0: self.text.set_text(self.settings.get('default_text')) else: self.text.set_text(self.settings.get_text_code()) self.text.set_coords_from_strokes() self.engrave.set_image(self.text) font_line_height = self.font.line_height() if font_line_height <= -1e10: if self.settings.get('height_calculation') == "max_all": raise JobError('No Font Characters Found') elif self.settings.get('height_calculation') == "max_use": raise JobError( 'Input Characters Were Not Found in the Current Font') return # Text transformations alignment = self.settings.get('justify') mirror = self.settings.get('mirror') flip = self.settings.get('flip') upper = self.settings.get('upper') angle = self.settings.get('text_angle') radius_in = self.settings.get('text_radius') text_radius = self.calc_text_radius() x_scale, y_scale = self.get_xy_scale() self.text.transform_scale(x_scale, y_scale) self.text.align(alignment) self.text.transform_on_radius(alignment, text_radius, upper) self.text.transform_angle(angle) if mirror: self.text.transform_mirror() if flip: self.text.transform_flip() self.plot_bbox = self.text.bbox minx, maxx, miny, maxy = self.plot_bbox.tuple() # engrave box or circle if self.settings.get('plotbox'): if radius_in == 0: delta = self.get_delta() self.text.add_box(delta, mirror, flip) self.plot_bbox = self.text.bbox minx, maxx, miny, maxy = self.plot_bbox.tuple() else: # Don't create the circle coords here, # a G-code circle command is generated later (when not v-carving) # For the circle to fit later on, the plot bounding box is adjusted with its radius maxr = max(radius_in, self.text.get_max_radius()) # thickness = self.settings.get('line_thickness') radius_plot = maxr + thickness / 2 minx = miny = -radius_plot maxx = maxy = -minx self.plot_bbox = BoundingBox(minx, maxx, miny, maxy) x_zero, y_zero = self.move_origin(self.plot_bbox) x_offset = -x_zero y_offset = -y_zero self.text.transform_translate(x_offset, y_offset) self.plot_bbox = BoundingBox(minx + x_offset, maxx + x_offset, miny + y_offset, maxy + y_offset) self.text.bbox = self.plot_bbox
def get_bounding_box(tile_pos): """Get the BoundingBox for the tile, given its position.""" block = Vec(BLOCK_WIDTH, BLOCK_WIDTH) return BoundingBox(tile_pos, tile_pos + block)
def __read_regions_file(self, fn, padding_factor, max_size, min_nfacet_per_axis): """ Reads a ds9 region file and sets up a grid of sub clusters (aka. facets) for each hull read out of the file. Each of the sub clusters are padded to a padding factor as determined by DDFacet's EstimateNpix. The number of sub clusters is determined from the maximum size of such sub cluster. If the fn is None it is assumed that the user intends to split the full sky up into a single direction with each sub cluster contributing to this single direction (i.e. regular tesselation of the sky into square facets). Subclusters are guaranteed to be odd sized and square return dictionary of directions, each entry containing a list of sub regions """ clusters = [] if fn is not None: # dde case with open(fn) as f: parser = DS9Parser(f.read()) for regi, reg in enumerate(parser.shapes): coords = map(int, [c.value for c in reg.coord]) assert len(coords) % 2 == 0, "Number of region coords must be multiple of 2-tuple" coords = np.array(coords).reshape([len(coords) // 2, 2]) clusters.append(BoundingConvexHull(coords, name="DDE_REG{0:d}".format(regi + 1))) else: # die case clusters = [BoundingBox(0, self.__nx - 1, 0, self.__ny - 1, name="die", check_mask_outofbounds=True)] log(2).print("\tInitialized bounding boxes for regions. There are {0:d} region(s)".format(len(clusters))) # now create axis aligned bounding boxes for each of the regions # and further split them to the maximum permitted facet size clusters = [BoundingBoxFactory.AxisAlignedBoundingBox(c, check_mask_outofbounds=False) for c in clusters] def __split_regular_region(reg, max_size): if max_size < 0: raise ValueError("Expected positive value for min_size") reg_size_deg = np.max(np.array(reg.box_npx) * self.pixel_scale / 3600.0) nsplit = max(1, max(min_nfacet_per_axis, int(np.ceil(reg_size_deg / max_size)))) return BoundingBoxFactory.SplitBox(reg, nsubboxes=nsplit, check_mask_outofbounds=True) log(2).print("\tSplitting regions into facetted regions, with maximum unpadded size of {0:.2f} degrees per facet".format(max_size)) clusters = [aasubreg for aareg in map(lambda reg: __split_regular_region(reg, max_size), clusters) for aasubreg in aareg] clusters = map(lambda reg: BoundingBoxFactory.AxisAlignedBoundingBox(reg, square=True, check_mask_outofbounds=False), clusters) def __pad_cluster(c, padding_factor): npx,_ = c.box_npx # square facet at this point # this returns an odd npix: npixunpadded, npixpadded = EstimateNpix(npx, Padding=padding_factor) return BoundingBoxFactory.PadBox(c, npixpadded, npixpadded, check_mask_outofbounds=False) log(2).print("\tPadding all facets by a minimum factor of {0:.2f}x".format(padding_factor)) clusters = map(lambda c: __pad_cluster(c, padding_factor), clusters) log.debug("\tNormalizing regional weights") BoundingConvexHull.normalize_masks(clusters) log(2).print("\tCaching regional weight maps for future predicts") map(lambda x: x.mask, clusters) # cache mask dirs = {} for c in clusters: dirs[c.name] = dirs.get(c.name, []) + [c] return dirs
def test_is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( self): self.assertTrue( is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( BoundingBox(1, 2, 1, 2), BoundingBox(0, 10, 0, 10))) self.assertTrue( is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( BoundingBox(0, 2, 0, 2), BoundingBox(0, 10, 0, 10))) self.assertFalse( is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( BoundingBox(-0.01, 2, 0, 2), BoundingBox(0, 10, 0, 10))) self.assertFalse( is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( BoundingBox(20, 21, 20, 21), BoundingBox(0, 10, 0, 10))) self.assertFalse( is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( BoundingBox(9, 10, 0, 1), BoundingBox(0, 10, 0, 10))) self.assertFalse( is_bounding_box_fully_inside_bounding_box_not_including_upper_limits( BoundingBox(5, 6, 9, 10), BoundingBox(0, 10, 0, 10)))
def get_bounding_box_of_width(self, width): """Get a bounding box at the current position with a custom width.""" block = Vec(width, width) return BoundingBox(self.pos, self.pos + block)
def test_quad_tree_smoke_test(self): quad_tree = QuadTree(BoundingBox(0, 0, 100, 100)) quad_tree.add(LineSegment(Point(10, 10), Point(20, 20))) self.assertEqual(quad_tree.get(BoundingBox(10, 90, 10, 90)), [LineSegment(Point(10, 10), Point(20, 20))])