SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BiArc.cpp
Go to the documentation of this file.
1 #include "BiArc.h"
2 #include <cassert>
3 #include <cmath> // added for cygwin build 2015-06-10 MB
4 
6 {
7  double k1, k2, k3, k4;
8  double L1, L2, L3, L4;
9 
10  double t0 = params.start_angle;
11  double t2 = params.end_angle;
12  double tjoin;
13 
15 
16  //degenerate case
17  if (L<eA){
18  params.K1 = HUGE;
19  params.K2 = HUGE;
20  params.E = HUGE;
21  return;
22  }
23 
24  double psi = atan2(params.end_pt.y()-params.start_pt.y(),params.end_pt.x()-params.start_pt.x());
25  if (psi<0) psi+=2*M_PI; //psi = [0,2*pi)
26 
27  params.flag = 0;
28 
29  L1 = -10;
30  L2 = -10;
31 
32  // due to the 0-2*pi discontinuity even for perfect arcs,
33  // (psi-(t2+t0)/2)~{-pi,0, pi} for cocircular solutions
34  // if (abs(mod(psi -(t2+t0)/2, pi))<eA) % this condition is not correct
35 
36  if (fabs(psi-(t2+t0)/2)<eA || fabs(psi-(t2+t0)/2+M_PI)<eA || fabs(psi-(t2+t0)/2-M_PI)<eA){
37  if (fabs(fmod(psi-t0,2*M_PI))<eA){ // straight line (still need to check mod 2*pi)
38  k1 = 0;
39  k2 = 0;
40  L1 = L;
41  L2 = 0;
42  }
43  else { // single arc
44  k1 = -4*sin((3*t0+t2)/4 - psi)*cos((t2-t0)/4)/L;
45  k2 = 0;
46  L1 = compute_arclength(t0,t2,k1);
47  L2 = 0;
48  }
49  //record the solutions the parameters
50  params.L1 = L1;
51  params.L2 = L2;
52  params.K1 = k1;
53  params.K2 = k2;
54  params.E = 0;
56  return;
57  }
58  else {
59  params.flag = 1; //truly a biarc
60 
61  k1 = -4*sin((3*t0+t2)/4 - psi)*cos((t2-t0)/4)/L;
62  k2 = 4*sin((t0+3*t2)/4 - psi)*cos((t2-t0)/4)/L;
63 
64  if (fabs(k1)<eK){
65  k1 = 0;
66  L1 = L*sin((t2+t0)/2-psi)/sin((t2-t0)/2);
67  L2 = compute_arclength(t0,t2,k2);
68  }
69  else {
70  if (fabs(k2)<eK){
71  k2 = 0;
72  L2 = L*sin((t2+t0)/2-psi)/sin((t0-t2)/2);
73  L1 = compute_arclength(t0,t2,k1);
74  }
75  else {
76  // tjoin will be incorrect if k1~0 or k2~0
77  tjoin = compute_join_theta(k1,k2);
78  L1 = compute_arclength(t0,tjoin,k1);
79  L2 = compute_arclength(tjoin,t2,k2);
80  }
81  }
82 
83  // the other possible biarc
84  L3 = -10;
85  L4 = -10;
86 
87  k3 = 4*cos((3*t0+t2)/4 - psi)*sin((t2-t0)/4)/L;
88  k4 = 4*cos((t0+3*t2)/4 - psi)*sin((t2-t0)/4)/L;
89 
90  // since this solution picks the biarc with the bigger turn
91  // the curvature solutions can still be close to zero
92  if ( (fabs(k3)>eK || fabs(k4)>eK) && fabs(k4-k3)>eK){
93  if (fabs(k3)<eK){
94  k3 = 0;
95  L3 = L*sin((t2+t0)/2-psi)/sin((t2-t0)/2);
96  L4 = compute_arclength(t0,t2,k4);
97  }
98  else {
99  if (fabs(k4)<eK){
100  k4 = 0;
101  L4 = L*sin((t2+t0)/2-psi)/sin((t0-t2)/2);
102  L3 = compute_arclength(t0,t2,k3);
103  }
104  else {
105  tjoin = compute_join_theta(k3,k4);
106  L3 = compute_arclength(t0,tjoin,k3);
107  L4 = compute_arclength(tjoin,t2,k4);
108  }
109  }
110  }
111 
112  // choose the smaller one
113  // but due to the epsilon settings (eA and eK) we could still get an incorrect solution
114  // this could be caught by looking at the signs of Ls.
115 
116  if ((L1>0 && L2>0) && ((L3<0 || L4<0) || (L1+L2)<(L3+L4))){
117  //k1 and k2 are the correct solutions
118  params.L1 = L1;
119  params.L2 = L2;
120  params.K1 = k1;
121  params.K2 = k2;
122  params.E = (k2-k1)*(k2-k1);
123  }
124  else {
125  if (L3>0 && L4>0){
126  params.L1 = L3;
127  params.L2 = L4;
128  params.K1 = k3;
129  params.K2 = k4;
130  params.E = (k3-k4)*(k3-k4);
131  }
132  else {
133  //this should never happen
134  assert(false);
135  }
136  }
137  }
139 }
140 
142 {
143  if (params.K1 != 0){
144  params.R1 = fabs(1/params.K1);
147  double dt = params.L1*params.K1;
150  }
151  else {
154  params.R1 = HUGE;
155  }
156 
157  if (params.K2 != 0){
158  params.R2 = fabs(1/params.K2);
161  }
162  else {
163  params.R2 = HUGE;
164  }
165 
166  params.dir1 = params.K1<0 ? -1 : 1;//sign(params.K1); //CCW=+1
167  params.dir2 = params.K2<0 ? -1 : 1;//sign(params.K2);
168 }
169 
170 /* ---------------- BiArc support Functions --------------------- */
171 
172 double BiArc::compute_join_theta(double k1, double k2)
173 {
174  // compute the theta at which the two arcs meet
175  double x0=params.start_pt.x();
176  double y0=params.start_pt.y();
177  double x2=params.end_pt.x();
178  double y2=params.end_pt.y();
179  double t0=params.start_angle;
180  double t2=params.end_angle;
181 
182  double sin_join_theta = (k1*k2*(x2-x0)+k2*sin(t0)-k1*sin(t2))/(k2-k1);
183  double cos_join_theta = (-k1*k2*(y2-y0)+k2*cos(t0)-k1*cos(t2))/(k2-k1);
184 
185  double join_theta = atan2(sin_join_theta, cos_join_theta);
186  if (join_theta<0) join_theta += 2*M_PI;
187 
188  return join_theta;
189 }
190 
191 double BiArc::compute_arclength(double t0, double t1, double k)
192 {
193  double num = (t1-t0);
194 
195  if (k<0 && (t1-t0)>0)
196  num = num-2*M_PI;
197  else if (k>0 && (t1-t0)<0)
198  num = num+2*M_PI;
199 
200  return num/k;
201 }
#define eA
Definition: BiArc.h:34
double K2
Definition: BiArc.h:50
void compute_other_stuff()
Definition: BiArc.cpp:141
void setY(coord_type ny)
Definition: points.h:100
#define M_PI
Definition: angles.h:37
int flag
Definition: BiArc.h:41
double E
Definition: BiArc.h:55
Point2D< double > mid_pt
Definition: BiArc.h:63
double L1
Definition: BiArc.h:52
double start_angle
Definition: BiArc.h:46
#define eK
Definition: BiArc.h:35
double euc_distance(Point2D< point_type1 > pt1, Point2D< point_type2 > pt2)
Definition: points.h:245
Point2D< double > start_pt
Definition: BiArc.h:43
coord_type x() const
Definition: points.h:96
void compute_biarc_params()
Definition: BiArc.cpp:5
double L2
Definition: BiArc.h:53
double R1
Definition: BiArc.h:57
double K1
Definition: BiArc.h:49
BiArcParams params
Definition: BiArc.h:168
Point2D< double > end_pt
Definition: BiArc.h:44
double R2
Definition: BiArc.h:58
double compute_arclength(double theta0, double theta2, double k)
Definition: BiArc.cpp:191
double compute_join_theta(double k1, double k2)
Definition: BiArc.cpp:172
double end_angle
Definition: BiArc.h:47
int dir2
Definition: BiArc.h:61
void setX(coord_type nx)
Definition: points.h:99
Point2D< double > center1
Definition: BiArc.h:64
coord_type y() const
Definition: points.h:97
int dir1
Definition: BiArc.h:60
Point2D< double > center2
Definition: BiArc.h:65