segment_handling.py
Go to the documentation of this file.
1 import math
2 import numpy as np
3 from scipy.spatial import ConvexHull
4 
5 
6 class Segment:
7  def __init__(self):
8  # input parameters
9  self.id = -1 # segemnt id, should correspond to the label
10  self.feature = False # flag distinguisihing features from walls (will be used later)
11  self.cells = np.array([]) # cells ids in the map
12  # pre-processed data
13  self.cells_corners = np.empty((0, 2), float) # cells' corners as used for are computation
14  # descriptor
15  self.convex_hull = list([]) # vertices of a convex hull of segemnt
16  self.minimal_bounding_box = list([]) # vertices of a convex of minimal bounding box
17  self.rectangle_direction = [] # vector in the direction of longer edge of rectangle
18  self.rectangle_orthogonal = [] # vector in the ortogonal direction
19  self.center = [] # center of mass of MBB
20  self.angle = []
21  self.mbb_area = []
22 
23  @staticmethod
24  def polygon_area(x, y):
25  return 0.5 * np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1)))
26 
27  @staticmethod
29  return (math.atan2(x[0], x[1]) + 2 * math.pi) % (2 * math.pi)
30 
31  @staticmethod
32  def compute_corner(a, corner):
33  return [a[0] + corner[0], a[1] + corner[1]]
34 
35  @staticmethod
36  def orthogonal_vector(vector):
37  # from vector returns a orthogonal/perpendicular vector of equal length
38  return -1 * vector[1], vector[0]
39 
40  @staticmethod
41  def unit_vector(pt0, pt1):
42  # returns an unit vector that points in the direction of pt0 to pt1
43  dis_0_to_1 = math.sqrt((pt0[0] - pt1[0]) ** 2 + (pt0[1] - pt1[1]) ** 2)
44  return (pt1[0] - pt0[0]) / dis_0_to_1, (pt1[1] - pt0[1]) / dis_0_to_1
45 
46  @staticmethod
47  def bounding_area(index, hull):
48  unit_vector_p = Segment.unit_vector(hull[index, :], hull[index + 1, :])
49  unit_vector_o = Segment.orthogonal_vector(unit_vector_p)
50 
51  dis_p = tuple(np.dot(unit_vector_p, pt) for pt in hull)
52  dis_o = tuple(np.dot(unit_vector_o, pt) for pt in hull)
53 
54  min_p = min(dis_p)
55  min_o = min(dis_o)
56  len_p = max(dis_p) - min_p
57  len_o = max(dis_o) - min_o
58 
59  return {'area': len_p * len_o,
60  'length_parallel': len_p,
61  'length_orthogonal': len_o,
62  'rectangle_center': (min_p + len_p / 2, min_o + len_o / 2),
63  'unit_vector': unit_vector_p,
64  'orthogonal_vector': unit_vector_o
65  }
66 
67  @staticmethod
68  def rotate_points(center_of_rotation, angle, points):
69  # Requires: center_of_rotation to be a 2d vector. ex: (1.56, -23.4)
70  # angle to be in radians
71  # points to be a list or tuple of points. ex: ((1.56, -23.4), (1.56, -23.4))
72  # Effects: rotates a point cloud around the center_of_rotation point by angle
73  rot_points = []
74  ang = []
75  for pt in points:
76  diff = tuple([pt[d] - center_of_rotation[d] for d in range(2)])
77  diff_angle = math.atan2(diff[1], diff[0]) + angle
78  ang.append(diff_angle)
79  diff_length = math.sqrt(sum([d ** 2 for d in diff]))
80  rot_points.append((center_of_rotation[0] + diff_length * math.cos(diff_angle),
81  center_of_rotation[1] + diff_length * math.sin(diff_angle)))
82 
83  return rot_points
84 
85  @staticmethod
86  def sorted_rect(vec):
87  # returns vec in clockwise order, starting with topleft
88  normd = vec - np.average(vec, axis=0) # vertices relative to centroid
89  k = np.apply_along_axis(Segment.sorting_criterion, axis=1, arr=normd)
90  order = np.argsort(k)
91  return vec[order]
92 
93  @staticmethod
94  def to_xy_coordinates(unit_vector_angle, point):
95  # returns converted unit vector coordinates in x, y coordinates
96  angle_orthogonal = unit_vector_angle + math.pi / 2
97  return point[0] * math.cos(unit_vector_angle) + point[1] * math.cos(angle_orthogonal), \
98  point[0] * math.sin(unit_vector_angle) + point[1] * math.sin(angle_orthogonal)
99 
100  @staticmethod
101  def rectangle_corners(rectangle):
102  # Requires: the output of mon_bounding_rectangle
103  # Effects: returns the corner locations of the bounding rectangle
104  corner_points = []
105  for i1 in (.5, -.5):
106  for i2 in (i1, -1 * i1):
107  corner_points.append((rectangle['rectangle_center'][0] + i1 * rectangle['length_parallel'],
108  rectangle['rectangle_center'][1] + i2 * rectangle['length_orthogonal']))
109 
110  r_points = Segment.rotate_points(rectangle['rectangle_center'], rectangle['unit_vector_angle'], corner_points)
111 
112  asort = set(r_points)
113  local_poly = np.array(list(asort))
114  local_poly = np.column_stack((local_poly[:, 0], local_poly[:, 1]))
115  local_poly_sort = Segment.sorted_rect(local_poly)
116 
117  local_poly_sort = np.append(local_poly_sort, [local_poly_sort[0, :]], axis=0)
118  return local_poly_sort
119 
120  def add_cells(self, cells):
121  self.cells = cells
122 
123  corners = np.array([[0.5, 0.5],
124  [-0.5, 0.5],
125  [-0.5, -0.5],
126  [0.5, -0.5]])
127  for corner in corners:
128  new = np.apply_along_axis(Segment.compute_corner, 1, self.cells, corner = corner)
129  self.cells_corners = np.append(self.cells_corners, np.array(new), axis=0)
130 
131  def compute_hull(self):
132  hull_ordered = [self.cells_corners[index] for index in ConvexHull(self.cells_corners).vertices]
133  hull_ordered.append(hull_ordered[0])
134  self.convex_hull = np.array(hull_ordered)
135 
136  def compute_mbb(self):
137  if not self.convex_hull.size == 0:
138  self.compute_hull()
139  min_rectangle = Segment.bounding_area(0, self.convex_hull)
140 
141  for i in range(1, len(self.convex_hull) - 1):
142  rectangle = Segment.bounding_area(i, self.convex_hull)
143  if rectangle['area'] < min_rectangle['area']:
144  min_rectangle = rectangle
145 
146  min_rectangle['unit_vector_angle'] = math.atan2(min_rectangle['unit_vector'][1],
147  min_rectangle['unit_vector'][0])
148  min_rectangle['rectangle_center'] = Segment.to_xy_coordinates(min_rectangle['unit_vector_angle'],
149  min_rectangle['rectangle_center'])
150 
151  self.minimal_bounding_box = Segment.rectangle_corners(min_rectangle)
152 
153  self.center = min_rectangle['rectangle_center']
154 
155  self.mbb_area = Segment.polygon_area(self.minimal_bounding_box[:, 0], self.minimal_bounding_box[:, 1])
156 
157  if min_rectangle['length_parallel'] < min_rectangle['length_orthogonal']:
158  self.rectangle_direction = min_rectangle[
159  'orthogonal_vector'] # np.array([min_rectangle['unit_vector'][1], -min_rectangle['unit_vector'][0]])
160  self.rectangle_orthogonal = min_rectangle['unit_vector']
161  else:
162  self.rectangle_direction = min_rectangle['unit_vector']
163  self.rectangle_orthogonal = min_rectangle[
164  'orthogonal_vector'] # np.array([min_rectangle['unit_vector'][1], -min_rectangle['unit_vector'][0]])
165  self.angle = np.arctan2(self.rectangle_direction[1], self.rectangle_direction[0])
segment_handling.Segment
Definition: segment_handling.py:6
segment_handling.Segment.id
id
Definition: segment_handling.py:9
segment_handling.Segment.compute_hull
def compute_hull(self)
Definition: segment_handling.py:131
segment_handling.Segment.__init__
def __init__(self)
Definition: segment_handling.py:7
segment_handling.Segment.mbb_area
mbb_area
Definition: segment_handling.py:21
segment_handling.Segment.bounding_area
def bounding_area(index, hull)
Definition: segment_handling.py:47
segment_handling.Segment.feature
feature
Definition: segment_handling.py:10
segment_handling.Segment.convex_hull
convex_hull
Definition: segment_handling.py:15
segment_handling.Segment.compute_mbb
def compute_mbb(self)
Definition: segment_handling.py:136
segment_handling.Segment.unit_vector
def unit_vector(pt0, pt1)
Definition: segment_handling.py:41
segment_handling.Segment.angle
angle
Definition: segment_handling.py:20
segment_handling.Segment.polygon_area
def polygon_area(x, y)
Definition: segment_handling.py:24
segment_handling.Segment.rectangle_orthogonal
rectangle_orthogonal
Definition: segment_handling.py:18
segment_handling.Segment.cells
cells
Definition: segment_handling.py:11
segment_handling.Segment.minimal_bounding_box
minimal_bounding_box
Definition: segment_handling.py:16
segment_handling.Segment.sorting_criterion
def sorting_criterion(x)
Definition: segment_handling.py:28
segment_handling.Segment.sorted_rect
def sorted_rect(vec)
Definition: segment_handling.py:86
segment_handling.Segment.compute_corner
def compute_corner(a, corner)
Definition: segment_handling.py:32
segment_handling.Segment.rectangle_direction
rectangle_direction
Definition: segment_handling.py:17
segment_handling.Segment.cells_corners
cells_corners
Definition: segment_handling.py:13
segment_handling.Segment.add_cells
def add_cells(self, cells)
Definition: segment_handling.py:120
segment_handling.Segment.center
center
Definition: segment_handling.py:19
segment_handling.Segment.orthogonal_vector
def orthogonal_vector(vector)
Definition: segment_handling.py:36
segment_handling.Segment.rotate_points
def rotate_points(center_of_rotation, angle, points)
Definition: segment_handling.py:68
segment_handling.Segment.to_xy_coordinates
def to_xy_coordinates(unit_vector_angle, point)
Definition: segment_handling.py:94
segment_handling.Segment.rectangle_corners
def rectangle_corners(rectangle)
Definition: segment_handling.py:101


rose2
Author(s): Gabriele Somaschini, Matteo Luperto
autogenerated on Wed Jun 28 2023 02:21:53