Example #1
0
    def __cleanup_mask(self):
        mask = self.get_mask()

        # Drop points from all shapes which are not part of the convex hulls.
        for shape in mask:
            if len(shape) <= 3:
                continue
            points = [self.get_pos_for_color(c) for c in shape]
            edge_points = geom.convex_hull(points)
            for col, point in zip(shape, points):
                if point in edge_points:
                    continue
                shape.remove(col)

        # Drop shapes smaller than the minimum size.
        newmask = []
        min_size = self.get_radius() * self.min_shape_size
        for shape in mask:
            points = [self.get_pos_for_color(c) for c in shape]
            void = geom.convex_hull(points)
            size = self._get_void_size(void)
            if size >= min_size:
                newmask.append(shape)
        mask = newmask

        # Drop shapes whose points entirely lie within other shapes
        newmask = []
        maskvoids = [
            (shape,
             geom.convex_hull([self.get_pos_for_color(c) for c in shape]))
            for shape in mask
        ]
        for shape1, void1 in maskvoids:
            shape1_subsumed = True
            for p1 in void1:
                p1_subsumed = False
                for shape2, void2 in maskvoids:
                    if shape1 is shape2:
                        continue
                    if geom.point_in_convex_poly(p1, void2):
                        p1_subsumed = True
                        break
                if not p1_subsumed:
                    shape1_subsumed = False
                    break
            if not shape1_subsumed:
                newmask.append(shape1)
        mask = newmask

        self.set_mask(mask)
        self.queue_draw()
Example #2
0
    def __cleanup_mask(self):
        mask = self.get_mask()

        # Drop points from all shapes which are not part of the convex hulls.
        for shape in mask:
            if len(shape) <= 3:
                continue
            points = [self.get_pos_for_color(c) for c in shape]
            edge_points = geom.convex_hull(points)
            for col, point in zip(shape, points):
                if point in edge_points:
                    continue
                shape.remove(col)

        # Drop shapes smaller than the minimum size.
        newmask = []
        min_size = self.get_radius() * self.min_shape_size
        for shape in mask:
            points = [self.get_pos_for_color(c) for c in shape]
            void = geom.convex_hull(points)
            size = self._get_void_size(void)
            if size >= min_size:
                newmask.append(shape)
        mask = newmask

        # Drop shapes whose points entirely lie within other shapes
        newmask = []
        maskvoids = [(shape, geom.convex_hull([self.get_pos_for_color(c)
                                               for c in shape]))
                     for shape in mask]
        for shape1, void1 in maskvoids:
            shape1_subsumed = True
            for p1 in void1:
                p1_subsumed = False
                for shape2, void2 in maskvoids:
                    if shape1 is shape2:
                        continue
                    if geom.point_in_convex_poly(p1, void2):
                        p1_subsumed = True
                        break
                if not p1_subsumed:
                    shape1_subsumed = False
                    break
            if not shape1_subsumed:
                newmask.append(shape1)
        mask = newmask

        self.set_mask(mask)
        self.queue_draw()
Example #3
0
 def geometry(self):
   hull = geom.convex_hull(self.stops())
   return {
     'type': 'Polygon',
     'coordinates': [
       hull + [hull[0]]
     ]
   }    
Example #4
0
    def colors_to_mask_void(self, colors):
        """Converts a set of colours to a mask void (convex hull).

        Mask voids are the convex hulls of the (x, y) positions for the
        colours making up the mask, so mask shapes with fewer than 3 colours
        are returned as the empty list.

        """
        points = []
        if len(colors) < 3:
            return points
        for col in colors:
            points.append(self.get_pos_for_color(col))
        return geom.convex_hull(points)
Example #5
0
    def colors_to_mask_void(self, colors):
        """Converts a set of colours to a mask void (convex hull).

        Mask voids are the convex hulls of the (x, y) positions for the
        colours making up the mask, so mask shapes with fewer than 3 colours
        are returned as the empty list.

        """
        points = []
        if len(colors) < 3:
            return points
        for col in colors:
            points.append(self.get_pos_for_color(col))
        return geom.convex_hull(points)
Example #6
0
    def __update_active_objects(self, x, y):
        # Decides what a click or a drag at (x, y) would do, and updates the
        # mouse cursor and draw state to match.

        assert self.__drag_func is None
        self.__active_shape = None
        self.__active_ctrlpoint = None
        self.__tmp_new_ctrlpoint = None
        self.queue_draw()  # yes, always

        # Possible mask void manipulations
        mask = self.get_mask()
        for mask_idx in xrange(len(mask)):
            colors = mask[mask_idx]
            if len(colors) < 3:
                continue

            # If the pointer is near an existing control point, clicking and
            # dragging will move it.
            void = []
            for col_idx in xrange(len(colors)):
                col = colors[col_idx]
                px, py = self.get_pos_for_color(col)
                dp = math.sqrt((x-px)**2 + (y-py)**2)
                if dp <= self.__ctrlpoint_grab_radius:
                    mask.remove(colors)
                    mask.insert(0, colors)
                    self.__active_shape = colors
                    self.__active_ctrlpoint = col_idx
                    self.__set_cursor(None)
                    return
                void.append((px, py))

            # If within a certain distance of an edge, dragging will create and
            # then move a new control point.
            void = geom.convex_hull(void)
            for p1, p2 in geom.pairwise(void):
                isect = geom.nearest_point_in_segment(p1, p2, (x, y))
                if isect is not None:
                    ix, iy = isect
                    di = math.sqrt((ix-x)**2 + (iy-y)**2)
                    if di <= self.__ctrlpoint_grab_radius:
                        newcol = self.get_color_at_position(ix, iy)
                        self.__tmp_new_ctrlpoint = newcol
                        mask.remove(colors)
                        mask.insert(0, colors)
                        self.__active_shape = colors
                        self.__set_cursor(None)
                        return

            # If the mouse is within a mask void, then dragging would move that
            # shape around within the mask.
            if geom.point_in_convex_poly((x, y), void):
                mask.remove(colors)
                mask.insert(0, colors)
                self.__active_shape = colors
                self.__set_cursor(None)
                return

        # Away from shapes, clicks and drags manipulate the entire mask: adding
        # cutout voids to it, or rotating the whole mask around its central
        # axis.
        alloc = self.get_allocation()
        cx, cy = self.get_center(alloc=alloc)
        radius = self.get_radius(alloc=alloc)
        dx, dy = x-cx, y-cy
        r = math.sqrt(dx**2 + dy**2)
        if r < radius*(1.0-self.min_shape_size):
            if len(mask) < self.__max_num_shapes:
                d = self.__dist_to_nearest_shape(x, y)
                minsize = radius * self.min_shape_size
                if d is None or d > minsize:
                    # Clicking will result in a new void
                    self.__set_cursor(self.__add_cursor)
        else:
            # Click-drag to rotate the entire mask
            self.__set_cursor(self.__rotate_cursor)
Example #7
0
 def geometry(self):
     hull = geom.convex_hull(self.stops())
     return {'type': 'Polygon', 'coordinates': [hull + [hull[0]]]}
Example #8
0
 def test_convex_hull(self):
   expect = [[0, 1], [1, 0], [1, 1]]
   data = geom.convex_hull(mockpoints())
   for i,j in zip(data, expect):
     self.assertAlmostEqual(i[0], j[0])
     self.assertAlmostEqual(i[1], j[1])
Example #9
0
if not arcpy.Exists(new_fc):
    tweet.info("Creating feature class {}".format(new_fc))
    result = arcpy.management.CreateFeatureclass(output_geodatabase, output_class, "POLYGON", spatial_reference=spatialRef)
    if not group_field is None:
        arcpy.AddField_management(new_fc, group_field, "TEXT")
else:
    tweet.info("Emptying feature class {}".format(new_fc))
    arcpy.DeleteFeatures_management(new_fc)

insert = ['SHAPE@']
if not group_field is None:
    insert.append(group_field)

with arcpy.da.InsertCursor(new_fc, insert) as icursor:
    for group in point_lists:
        points = point_lists[group]
        convex_hull = geom.convex_hull(points)
        concave_hull = geom.concave_hull(convex_hull, points, min_length_fraction=minimum_length, min_angle=minimum_angle, max_iterations=iteration_cap)
        if not group_field is None:
            icursor.insertRow([concave_hull, group])
        else:
            icursor.insertRow([concave_hull])


   


    
    
        
Example #10
0
    def __update_active_objects(self, x, y):
        # Decides what a click or a drag at (x, y) would do, and updates the
        # mouse cursor and draw state to match.

        assert self.__drag_func is None
        self.__active_shape = None
        self.__active_ctrlpoint = None
        self.__tmp_new_ctrlpoint = None
        self.queue_draw()  # yes, always

        # Possible mask void manipulations
        mask = self.get_mask()
        for mask_idx in xrange(len(mask)):
            colors = mask[mask_idx]
            if len(colors) < 3:
                continue

            # If the pointer is near an existing control point, clicking and
            # dragging will move it.
            void = []
            for col_idx in xrange(len(colors)):
                col = colors[col_idx]
                px, py = self.get_pos_for_color(col)
                dp = math.sqrt((x - px)**2 + (y - py)**2)
                if dp <= self.__ctrlpoint_grab_radius:
                    mask.remove(colors)
                    mask.insert(0, colors)
                    self.__active_shape = colors
                    self.__active_ctrlpoint = col_idx
                    self.__set_cursor(None)
                    return
                void.append((px, py))

            # If within a certain distance of an edge, dragging will create and
            # then move a new control point.
            void = geom.convex_hull(void)
            for p1, p2 in geom.pairwise(void):
                isect = geom.nearest_point_in_segment(p1, p2, (x, y))
                if isect is not None:
                    ix, iy = isect
                    di = math.sqrt((ix - x)**2 + (iy - y)**2)
                    if di <= self.__ctrlpoint_grab_radius:
                        newcol = self.get_color_at_position(ix, iy)
                        self.__tmp_new_ctrlpoint = newcol
                        mask.remove(colors)
                        mask.insert(0, colors)
                        self.__active_shape = colors
                        self.__set_cursor(None)
                        return

            # If the mouse is within a mask void, then dragging would move that
            # shape around within the mask.
            if geom.point_in_convex_poly((x, y), void):
                mask.remove(colors)
                mask.insert(0, colors)
                self.__active_shape = colors
                self.__set_cursor(None)
                return

        # Away from shapes, clicks and drags manipulate the entire mask: adding
        # cutout voids to it, or rotating the whole mask around its central
        # axis.
        alloc = self.get_allocation()
        cx, cy = self.get_center(alloc=alloc)
        radius = self.get_radius(alloc=alloc)
        dx, dy = x - cx, y - cy
        r = math.sqrt(dx**2 + dy**2)
        if r < radius * (1.0 - self.min_shape_size):
            if len(mask) < self.__max_num_shapes:
                d = self.__dist_to_nearest_shape(x, y)
                minsize = radius * self.min_shape_size
                if d is None or d > minsize:
                    # Clicking will result in a new void
                    self.__set_cursor(self.__add_cursor)
        else:
            # Click-drag to rotate the entire mask
            self.__set_cursor(self.__rotate_cursor)