3 // kinematic constraints
4 bool BicycleCar::drivable(const BicycleCar &bc) const
6 double a_1 = atan2(bc.y() - this->y(), bc.x() - this->x()) - this->h();
11 double h_d = bc.h() - this->h();
17 if (h_d == 0 && (a_1 == 0 || a_2 == M_PI || a_2 == -M_PI)) {
19 } else if (0 < a_1 && a_1 <= M_PI/2) { // left front
20 BicycleCar z(*this); // zone border
21 z.rotate(this->ccl().x(), this->ccl().y(), h_d);
22 // assert z.h() == bc.h()
23 if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
25 a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
30 if (z.h() >= a_2 && a_2 >= this->h())
32 } else if (M_PI/2 < a_1 && a_1 <= M_PI) { // left rear
33 BicycleCar z(*this); // zone border
34 z.rotate(this->ccl().x(), this->ccl().y(), h_d);
35 // assert z.h() == bc.h()
36 if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
38 a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
44 if (this->h() >= a_2 && a_2 >= z.h())
46 } else if (0 > a_1 && a_1 >= -M_PI/2) { // right front
47 BicycleCar z(*this); // zone border
48 z.rotate(this->ccr().x(), this->ccr().y(), h_d);
49 // assert z.h() == bc.h()
50 if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
52 a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
57 if (this->h() >= a_2 && a_2 >= z.h())
59 } else if (-M_PI/2 > a_1 && a_1 >= -M_PI) { // right rear
60 BicycleCar z(*this); // zone border
61 z.rotate(this->ccr().x(), this->ccr().y(), h_d);
62 // assert z.h() == bc.h()
63 if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
65 a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
71 if (z.h() >= a_2 && a_2 >= this->h())
74 // Not happenning, as ``-pi <= a <= pi``.
79 double BicycleCar::iradi() const
81 return this->mtr() - this->w() / 2;
84 double BicycleCar::ofradi() const
86 return sqrt(pow(this->mtr() + this->w() / 2, 2) + pow(this->df(), 2));
89 double BicycleCar::orradi() const
91 return sqrt(pow(this->mtr() + this->w() / 2, 2) + pow(this->dr(), 2));
94 double BicycleCar::perfect_parking_slot_len() const
96 // see Simon R. Blackburn *The Geometry of Perfect Parking*
97 // see https://www.ma.rhul.ac.uk/SRBparking
98 double r = this->ctc() / 2;
99 double l = this->wb();
100 double k = this->df() - this->wb();
101 double w = this->w();
107 - pow(sqrt(r*r - l*l) - w, 2)
114 void BicycleCar::set_max_steer()
116 this->st(atan(this->wb() / this->mtr()));
120 double BicycleCar::lfx() const
122 double lfx = this->x();
123 lfx += (this->w() / 2) * cos(this->h() + M_PI / 2);
124 lfx += this->df() * cos(this->h());
125 lfx += this->sd() * cos(this->h());
129 double BicycleCar::lfy() const
131 double lfy = this->y();
132 lfy += (this->w() / 2) * sin(this->h() + M_PI / 2);
133 lfy += this->df() * sin(this->h());
134 lfy += this->sd() * sin(this->h());
138 double BicycleCar::lrx() const
140 double lrx = this->x();
141 lrx += (this->w() / 2) * cos(this->h() + M_PI / 2);
142 lrx += -this->dr() * cos(this->h());
143 lrx += -this->sd() * cos(this->h());
147 double BicycleCar::lry() const
149 double lry = this->y();
150 lry += (this->w() / 2) * sin(this->h() + M_PI / 2);
151 lry += -this->dr() * sin(this->h());
152 lry += -this->sd() * sin(this->h());
156 double BicycleCar::rrx() const
158 double rrx = this->x();
159 rrx += (this->w() / 2) * cos(this->h() - M_PI / 2);
160 rrx += -this->dr() * cos(this->h());
161 rrx += -this->sd() * cos(this->h());
165 double BicycleCar::rry() const
167 double rry = this->y();
168 rry += (this->w() / 2) * sin(this->h() - M_PI / 2);
169 rry += -this->dr() * sin(this->h());
170 rry += -this->sd() * sin(this->h());
174 double BicycleCar::rfx() const
176 double rfx = this->x();
177 rfx += (this->w() / 2) * cos(this->h() - M_PI / 2);
178 rfx += this->df() * cos(this->h());
179 rfx += this->sd() * cos(this->h());
183 double BicycleCar::rfy() const
185 double rfy = this->y();
186 rfy += (this->w() / 2) * sin(this->h() - M_PI / 2);
187 rfy += this->df() * sin(this->h());
188 rfy += this->sd() * sin(this->h());
192 double BicycleCar::ralx() const
194 double lrx = this->x();
195 lrx += (this->w() / 2) * cos(this->h() + M_PI / 2);
198 double BicycleCar::raly() const
200 double lry = this->y();
201 lry += (this->w() / 2) * sin(this->h() + M_PI / 2);
205 double BicycleCar::rarx() const
207 double rrx = this->x();
208 rrx += (this->w() / 2) * cos(this->h() - M_PI / 2);
212 double BicycleCar::rary() const
214 double rry = this->y();
215 rry += (this->w() / 2) * sin(this->h() - M_PI / 2);
219 BicycleCar BicycleCar::ccl() const
222 bc.x(this->x() + this->mtr() * cos(this->h() + M_PI / 2));
223 bc.y(this->y() + this->mtr() * sin(this->h() + M_PI / 2));
228 BicycleCar BicycleCar::ccr() const
231 bc.x(this->x() + this->mtr() * cos(this->h() - M_PI / 2));
232 bc.y(this->y() + this->mtr() * sin(this->h() - M_PI / 2));
238 void BicycleCar::next()
240 this->x(this->x() + this->sp() * cos(this->h()));
241 this->y(this->y() + this->sp() * sin(this->h()));
242 this->h(this->h() + this->sp() / this->wb() * tan(this->st()));
245 void BicycleCar::rotate(double cx, double cy, double angl)
247 double px = this->x();
248 double py = this->y();
251 double nx = px * cos(angl) - py * sin(angl);
252 double ny = px * sin(angl) + py * cos(angl);
253 this->h(this->h() + angl);
258 BicycleCar::BicycleCar()
260 // TODO according to mtr_ FIXME
269 std::tuple<bool, unsigned int, unsigned int> collide(
270 std::vector<std::tuple<double, double>> &p1,
271 std::vector<std::tuple<double, double>> &p2
274 for (unsigned int i = 0; i < p1.size() - 1; i++) {
275 for (unsigned int j = 0; j < p2.size() - 1; j++) {
279 std::get<0>(p1[i + 1]),
280 std::get<1>(p1[i + 1]),
283 std::get<0>(p2[j + 1]),
284 std::get<1>(p2[j + 1])
287 return std::make_tuple(true, i, j);
290 return std::make_tuple(false, 0, 0);
293 bool inside(double x, double y, std::vector<std::tuple<double, double>> &poly)
298 for (i = 0; i < 4; i++) {
300 (std::get<1>(poly[i]) > y) != (std::get<1>(poly[j]) > y)
302 x < std::get<0>(poly[i])
303 + (std::get<0>(poly[j]) - std::get<0>(poly[i]))
304 * (y - std::get<1>(poly[i]))
305 / (std::get<1>(poly[j]) - std::get<1>(poly[i]))
314 std::tuple<bool, double, double> intersect(
315 double x1, double y1,
316 double x2, double y2,
317 double x3, double y3,
321 double deno = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
323 return std::make_tuple(false, 0, 0);
324 double t = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4);
326 double u = (x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3);
329 if (t < 0 || t > 1 || u < 0 || u > 1)
330 return std::make_tuple(false, 0, 0);
331 return std::make_tuple(true, x1 + t * (x2 - x1), y1 + t * (y2 - y1));