Collision Checker
raytrace_utils.cc
Go to the documentation of this file.
2 
3 #include <math.h>
4 #include <Eigen/Dense>
5 
9 
11 
12 namespace collision {
13 namespace raytrace {
14 
16  bool operator()(const Eigen::Vector2d &i, const Eigen::Vector2d &j) {
17  return (i[0] <= j[0]);
18  }
20 
22  bool operator()(const Eigen::Vector2d &i, const Eigen::Vector2d &j) {
23  return (i[1] <= j[1]);
24  }
26 
29  return (i.point1().x <= j.point1().x);
30  }
31 } startsSortX;
32 
35  return (i.point1().x >= j.point1().x);
36  }
38 
41  return (i.point1().y <= j.point1().y);
42  }
43 } startsSortY;
44 
47  return (i.point1().y >= j.point1().y);
48  }
50 
53  return (i.point2().x <= j.point2().x);
54  }
55 } endsSortX;
56 
59  return (i.point2().x >= j.point2().x);
60  }
62 
65  return (i.point2().y <= j.point2().y);
66  }
67 } endsSortY;
68 
71  return (i.point2().y >= j.point2().y);
72  }
74 
76  std::vector<collision::CollisionObjectConstPtr> collision_objects,
77  const Eigen::Vector2d &point1, const Eigen::Vector2d &point2,
78  std::vector<LineSegment> &intersect, bool remove_overlaps) {
79  bool res = false;
80  std::vector<LineSegment> res2; // intersecting segments storage
81  int counter = 0;
82  for (auto &obj : collision_objects) {
83  res = obj->rayTrace(point1, point2, res2) || res;
84  counter++;
85  }
86 
87 #if RAYTRACE_DEBUG
88  std::stringstream out;
89  out << "[Raytrace] Obstacle CollisionObjects count: " << counter << std::endl;
90  out << "[Raytrace] Returned segments: " << res2.size() << std::endl;
91  raytrace::RaytraceDebugOutput(out.str().c_str());
92 #endif
93 
94  if (remove_overlaps) {
95  int axis =
96  (fabs(point1[0] - point2[0]) <=
97  fabs(point1[1] - point2[1])); // 0 - greater in X axis projection
98  collision::raytrace::rayTraceRemoveOverlaps(res2, intersect, axis);
99  } else {
100  intersect.insert(intersect.end(), res2.begin(), res2.end());
101  }
102  return res;
103 }
104 
105 bool rayTracePostprocess(const Eigen::Vector2d &point1,
106  const Eigen::Vector2d &point2,
107  std::vector<Eigen::Vector2d> inters1,
108  std::vector<LineSegment> &intersect,
109  const collision::CollisionObject *obj) {
110  double eps = 0.0000001;
111 
112 #if RAYTRACE_DEBUG
113  std::stringstream out;
114  out << "[Raytrace] Postprocessing points: " << inters1.size() << std::endl;
115  raytrace::RaytraceDebugOutput(out.str().c_str());
116 #endif
117 
118  if (inters1.size() == 2) {
119  intersect.push_back(LineSegment(inters1[0], inters1[1]));
120  return true;
121  } else if (inters1.size() == 1) {
123  intersect.push_back(LineSegment(point2, inters1[0]));
124  return true;
125  } else {
126  if (obj->collide(collision::Point(point1),
127  CollisionRequest(COL_DEFAULT))) // optional
128  {
129  intersect.push_back(LineSegment(point1, inters1[0]));
130  return true;
131  }
132  }
133  } else if (inters1.size() == 0) {
134  // second check optional
137  intersect.push_back(LineSegment(point1, point2));
138  return true;
139  }
140  } else {
141  // more than two points returned - must filter duplicates
142 
143  // std::vector<Eigen::Vector2d> inters1_copy;
144  // inters1_copy=inters1;
145 
146  // std::sort(inters1_copy.begin(),inters1_copy.end(), vector2dSortX);
147 
148  int numFound = 0;
149  std::vector<Eigen::Vector2d> inters2;
150  // raytrace::RaiseRaytraceError();
151 
152 #if RAYTRACE_DEBUG
153  std::ostringstream debugO;
154  debugO << "[RayTrace] [Raytrace Point]" << inters1[0][0] << " ";
155  debugO << inters1[0][1] << " ;";
156 #endif
157  unsigned int cc1 = 1;
158  for (; cc1 < inters1.size(); cc1++) {
159  if ((pow(inters1[cc1][0] - inters1[0][0], 2) +
160  pow(inters1[cc1][1] - inters1[0][1], 2)) >= eps) {
161  if (numFound < 1) {
162  numFound++;
163  inters2.push_back(inters1[cc1]);
164 #if RAYTRACE_DEBUG
165  debugO << "[RayTrace] [Raytrace Point]" << inters1[cc1][0] << " ";
166  debugO << inters1[cc1][1] << " ;";
167 #endif
168 
169  } else {
170  // raytrace::RaiseRaytraceError("more than two points found after
171  // LineSegment intersect postprocessing\n");
172 
173  // obj->to_string(debugO);
174  // debugO << "[RayTrace] [Raytrace Point]" << inters1[cc1][0] << " ";
175  // debugO << inters1[cc1][1] << " ;";
176 
177  break;
178  }
179  }
180  }
181 #if RAYTRACE_DEBUG
182  raytrace::RaytraceDebugOutput(debugO.str().c_str());
183 #endif
184 
185  if (numFound >= 1) {
186  intersect.push_back(LineSegment(inters1[0], inters2[0]));
187  } else {
188  inters2.push_back(inters1[0]); // only one point in intersection
189  return rayTracePostprocess(point1, point2, inters2, intersect, obj);
190  }
191 
192  return true;
193  }
194  return true;
195 }
196 
197 int rayTraceRemoveOverlaps(std::vector<LineSegment> intersect,
198  std::vector<LineSegment> &out_vec, int axis) {
199  std::vector<LineSegment> starts = intersect;
200  std::vector<LineSegment> ends = intersect;
201  std::vector<bool> remove_its(intersect.size());
202  // todo zeromemory?
203 
204  for (auto &it : starts) {
205  if (it.point1().getCoord(axis) > it.point2().getCoord(axis)) {
206  it.swap();
207  }
208  }
209  if (!axis) {
210  std::sort(starts.begin(), starts.end(), startsSortX);
211  } else {
212  std::sort(starts.begin(), starts.end(), startsSortY);
213  }
214  // std::sort(ends.begin(), ends.end(), endsSortX);
215 
216  std::vector<LineSegment>::iterator starts_it = starts.begin();
217  while (starts_it < starts.end()) {
218  bool repeat = 1;
219  auto starts_it2 = starts_it + 1;
220 
221  while (repeat) {
222  std::vector<LineSegment>::iterator maxend = starts_it;
223  while ((starts_it2 < starts.end()) &&
224  (starts_it2)->point1().getCoord(axis) <=
225  (starts_it)->point2().getCoord(axis)) {
226  remove_its[starts_it2 - starts.begin()] = true;
227  if ((starts_it2)->point2().getCoord(axis) >=
228  maxend->point2().getCoord(axis)) {
229  maxend = starts_it2;
230  }
231  starts_it2++;
232  }
233  if (maxend != starts_it) {
234  starts_it->set_point_2(maxend->point2());
235  } else {
236  starts_it = starts_it2;
237  repeat = 0;
238  }
239  }
240  }
241 
242  for (unsigned int cc1 = 0; cc1 < starts.size(); cc1++) {
243  if (!remove_its[cc1]) {
244  out_vec.push_back(starts[cc1]);
245  }
246  }
247 
248  return 0;
249 }
250 
251 } // namespace raytrace
252 } // namespace collision
struct collision::raytrace::EndsLineSegmentSort_X endsSortX
bool operator()(LineSegment i, LineSegment j)
bool operator()(LineSegment i, LineSegment j)
struct collision::raytrace::StartsLineSegmentSort_X startsSortX
bool operator()(LineSegment i, LineSegment j)
struct collision::raytrace::EndsLineSegmentSort_Y_goe endsSortY_goe
struct collision::raytrace::Vector2dSort_X vector2dSortX
bool rayTracePostprocess(const Eigen::Vector2d &point1, const Eigen::Vector2d &point2, std::vector< Eigen::Vector2d > inters1, std::vector< LineSegment > &intersect, const collision::CollisionObject *obj)
bool operator()(LineSegment i, LineSegment j)
void RaytraceDebugOutput(const char *)
raytrace::Point point2() const
Definition: line_segment.h:30
bool operator()(const Eigen::Vector2d &i, const Eigen::Vector2d &j)
struct collision::raytrace::StartsLineSegmentSort_Y startsSortY
bool operator()(LineSegment i, LineSegment j)
virtual bool collide(const CollisionObject &c, const collision::CollisionRequest &req=CollisionRequest()) const =0
int rayTraceRemoveOverlaps(std::vector< LineSegment > intersect, std::vector< LineSegment > &out_vec, int axis=0)
bool rayTracePrimitive(std::vector< collision::CollisionObjectConstPtr > collision_objects, const Eigen::Vector2d &point1, const Eigen::Vector2d &point2, std::vector< LineSegment > &intersect, bool remove_overlaps)
struct collision::raytrace::EndsLineSegmentSort_Y endsSortY
Universal structure specifying collision request properties.
struct collision::raytrace::StartsLineSegmentSort_Y_goe startsSortY_goe
bool operator()(LineSegment i, LineSegment j)
raytrace::Point point1() const
Definition: line_segment.h:28
struct collision::raytrace::EndsLineSegmentSort_X_goe endsSortX_goe
struct collision::raytrace::StartsLineSegmentSort_X_goe startsSortXgoe
struct collision::raytrace::Vector2dSort_Y vector2dSortY
bool operator()(LineSegment i, LineSegment j)
Base class for CollisionObjects and some of their groups.
A point in space.
Definition: point.h:18
bool operator()(const Eigen::Vector2d &i, const Eigen::Vector2d &j)
bool operator()(LineSegment i, LineSegment j)