g2o
simutils.cpp
Go to the documentation of this file.
1 #include "simutils.h"
2 
3 namespace g2o {
4  // -1: outside
5  // 0: p1Clipped
6  // 1: p2clipped
7  // 2: inside
8  // 3: all clipped
9  using namespace Eigen;
10 
11  int clipSegmentCircle(Eigen::Vector2d& p1, Eigen::Vector2d& p2, double r) {
12  double r2=r*r;
13  Eigen::Vector2d pBase=p1;
14  Eigen::Vector2d dp=p2-p1;
15  double length=dp.norm();
16  dp.normalize();
17  double p=2*dp.dot(p1);
18  double q=p1.squaredNorm()-r2;
19  double disc = p*p - 4*q;
20 
21  if (disc<=0) { // no intersection or single point intersection
22  return -1;
23  }
24  disc = sqrt(disc);
25 
26  double t1=.5*(-p-disc);
27  double t2=.5*(-p+disc);
28 
29  if ( t1 > length || t2 <0 )
30  return -1; // no intersection
31  bool clip1=false;
32  bool clip2=false;
33  if ( t1 > 0 ) {
34  p1 = pBase + dp*t1;
35  clip1 = true;
36  }
37  if ( t2 < length ) {
38  p2 = pBase + dp*t1;
39  clip2 = true;
40  }
41  if (clip1)
42  if (clip2) return 3;
43  else return 0;
44  else
45  if (clip2) return 1;
46  return 2;
47  }
48 
49  // -1: outside
50  // 0: p1Clipped
51  // 1: p2clipped
52  // 2: inside
53 
54  int clipSegmentLine(Eigen::Vector2d& p1, Eigen::Vector2d& p2, double a, double b, double c ){
55  bool p1inside = true;
56  bool p2inside = true;
57  if (a*p1.x()+b*p1.y()+c < 0){
58  p1inside=false;
59  }
60  if (a*p2.x()+b*p2.y()+c < 0){
61  p2inside=false;
62  }
63  if (p1inside && p2inside)
64  return 2;
65  if (!p1inside && !p2inside)
66  return -1;
67 
68  Eigen::Vector2d dp=p2-p1;
69  double den=a*dp.x()+b*dp.y();
70  if (den==0)
71  return -1;
72  double num = c + a*p1.x()+b*p1.y();
73  double t = - num/den;
74  if (p1inside){
75  p2=p1+dp*t;
76  return 1;
77  }
78  p1=p1+dp*t;
79  return 0;
80  }
81 
82  int clipSegmentFov(Eigen::Vector2d& p1, Eigen::Vector2d& p2, double min, double max){
83  bool clip1 = false, clip2 = false;
84  // normal to the first line
85  double amin = sin(min), bmin = -cos(min);
86  int minClip=clipSegmentLine(p1,p2,amin,bmin,0);
87  switch(minClip){
88  case -1:
89  return -1;
90  case 0:
91  clip1 = true;
92  break;
93  case 1:
94  clip2 = true;
95  break;
96  default:;
97  }
98  // normal to the second line
99  double amax = -sin(max), bmax = cos(max);
100  int maxClip=clipSegmentLine(p1,p2,amax,bmax,0);
101  switch(maxClip){
102  case -1:
103  return -1;
104  case 0:
105  clip1 = true;
106  break;
107  case 1:
108  clip2 = true;
109  break;
110  default:;
111  }
112  if (clip1)
113  if (clip2) return 3;
114  else return 0;
115  else
116  if (clip2) return 1;
117  return 2;
118  }
119 
120  Eigen::Vector2d computeLineParameters(const Eigen::Vector2d& p1, const Eigen::Vector2d& p2){
121  Eigen::Vector2d lp;
122  Eigen::Vector2d dp=p2-p1;
123  lp[0]=atan2(-dp.x(), dp.y());
124  Eigen::Vector2d n(cos(lp[0]), sin(lp[0]));
125  lp[1]=n.dot(p1+p2)*.5;
126  return lp;
127  }
128 } // end namespace
Eigen::Vector2d computeLineParameters(const Eigen::Vector2d &p1, const Eigen::Vector2d &p2)
Definition: simutils.cpp:120
int clipSegmentLine(Eigen::Vector2d &p1, Eigen::Vector2d &p2, double a, double b, double c)
Definition: simutils.cpp:54
int clipSegmentCircle(Eigen::Vector2d &p1, Eigen::Vector2d &p2, double r)
Definition: simutils.cpp:11
int clipSegmentFov(Eigen::Vector2d &p1, Eigen::Vector2d &p2, double min, double max)
Definition: simutils.cpp:82