10 Point::Point(double x, double y) : x_(x), y_(y)
39 Point::min_angle_between(Point const& p1, Point const& p2) const
41 double d1x = p1.x() - this->x();
42 double d1y = p1.y() - this->y();
43 double d2x = p2.x() - p1.x();
44 double d2y = p2.y() - p1.y();
46 double dot = d1x*d2x + d1y*d2y;
47 double d1 = sqrt(d1x*d1x + d1y*d1y);
48 double d2 = sqrt(d2x*d2x + d2y*d2y);
50 double delta = acos(dot / (d1 * d2));
51 return std::min(delta, M_PI - delta);
55 Point::inside_of(std::vector<Point> const& poly) const
57 unsigned int num = poly.size();
58 unsigned int j = num - 1;
60 for (unsigned int i = 0; i < num; i++) {
61 if (this->x() == poly[i].x() && this->y() == poly[i].y()) {
64 if ((poly[i].y() > this->y()) != (poly[j].y() > this->y())) {
65 auto slope1 = this->x() - poly[i].x();
66 slope1 *= poly[j].y() - poly[i].y();
67 auto slope2 = poly[j].x() - poly[i].x();
68 slope2 *= this->y() - poly[i].y();
69 auto slope = slope1 - slope2;
73 if ((slope < 0.0) != (poly[j].y() < poly[i].y())) {
83 Point::on_right_side_of(Line const& li) const
91 if (sgn((x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1)) < 0.0) {
99 Point::translate(Point const& p)
106 Point::rotate(Point const& c, double const angl)
108 double px = this->x();
109 double py = this->y();
112 double nx = px * cos(angl) - py * sin(angl);
113 double ny = px * sin(angl) + py * cos(angl);
119 Point::reflect(Line const& li)
121 this->rotate(li.b(), -li.h());
122 this->y_ -= li.b().y();
124 this->y_ += li.b().y();
125 this->rotate(li.b(), li.h());
129 Point::edist(Point const& p) const
131 return sqrt(pow(p.x() - this->x_, 2.0) + pow(p.y() - this->y_, 2.0));
135 Point::operator==(Point const& p)
137 return this->x() == p.x() && this->y() == p.y();
141 operator<<(std::ostream& out, Point const& p)
143 out << "[" << p.x() << "," << p.y() << "]";
147 Line::Line(Point const& b, Point const& e): b_(b), e_(e)
166 return Point((this->b_.x() + this->e_.x()) / 2.0,
167 (this->b_.y() + this->e_.y()) / 2.0);
183 Line::intersects_with(Line const& li)
185 auto x1 = this->b_.x();
186 auto y1 = this->b_.y();
187 auto x2 = this->e_.x();
188 auto y2 = this->e_.y();
189 auto x3 = li.b().x();
190 auto y3 = li.b().y();
191 auto x4 = li.e().x();
192 auto y4 = li.e().y();
193 double deno = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
197 double t = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4);
199 double u = (x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3);
202 if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0) {
205 this->i1_.x(x1 + t * (x2 - x1));
206 this->i1_.y(y1 + t * (y2 - y1));
211 Line::intersects_with(Point const& c, double const r)
213 auto x1 = this->b_.x();
214 auto y1 = this->b_.y();
215 auto x2 = this->e_.x();
216 auto y2 = this->e_.y();
228 double dr = sqrt(dx*dx + dy*dy);
229 double D = x1*y2 - x2*y1;
230 if (r*r * dr*dr - D*D < 0.0) {
233 // intersection coordinates
234 double ix1 = (D*dy + sgn(dy)*dx*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
236 double ix2 = (D*dy - sgn(dy)*dx*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
238 double iy1 = (-D*dx + std::abs(dy)*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
240 double iy2 = (-D*dx - std::abs(dy)*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
252 return this->b_.edist(this->e_);
258 return atan2(this->e_.y() - this->b_.y(), this->e_.x() - this->b_.x());
262 operator<<(std::ostream& out, Line const& li)
264 out << "[" << li.b_ << "," << li.e_ << "]";
268 Pose::Pose(double x, double y, double h) : Point(x, y), h_(h)
291 Pose::set_pose(Pose const& p)
299 Pose::rotate(Point const& c, double const angl)
301 Point::rotate(c, angl);
302 this->h(this->h() + angl);
306 Pose::reflect(Line const& li)
309 double dh = li.h() - this->h();
310 this->h(this->h() + 2.0 * dh);
314 Pose::operator==(Pose const& p)
316 return this->x() == p.x() && this->y() == p.y() && this->h() == p.h();
320 operator<<(std::ostream& out, Pose const& p)
322 out << "[" << p.x() << "," << p.y() << "," << p.h() << "]";
330 double bpbx = this->bp_.x() - clen * cos(this->bp_.h());
331 double bpby = this->bp_.y() - clen * sin(this->bp_.h());
332 double bpfx = this->bp_.x() + clen * cos(this->bp_.h());
333 double bpfy = this->bp_.y() + clen * sin(this->bp_.h());
334 Line li1(Point(bpbx, bpby), Point(bpfx, bpfy));
335 double epbx = this->ep_.x() - clen * cos(this->ep_.h());
336 double epby = this->ep_.y() - clen * sin(this->ep_.h());
337 double epfx = this->ep_.x() + clen * cos(this->ep_.h());
338 double epfy = this->ep_.y() + clen * sin(this->ep_.h());
339 Line li2(Point(epbx, epby), Point(epfx, epfy));
340 li1.intersects_with(li2);
341 this->x(li1.i1().x());
342 this->y(li1.i1().y());
343 double bh = this->b();
348 double eh = this->e();
353 this->h((this->b() + this->e()) / 2.0);
356 PoseRange::PoseRange(Pose bp, Pose ep) : bp_(bp), ep_(ep)
358 if (this->bp_ == this->ep_) {
359 this->set_pose(this->ep_);
365 PoseRange::PoseRange(double x, double y, double b, double e)
366 : PoseRange(Pose(x, y, b), Pose(x, y, e))
371 PoseRange::bp() const
377 PoseRange::ep() const
385 return std::min(this->bp_.h(), this->ep_.h());
391 return std::max(this->bp_.h(), this->ep_.h());
395 PoseRange::translate(Point const& p)
397 this->bp_.translate(p);
398 this->ep_.translate(p);
403 PoseRange::rotate(Point const& c, double const angl)
405 this->bp_.rotate(c, angl);
406 this->ep_.rotate(c, angl);
411 PoseRange::reflect(Line const& li)
413 this->bp_.reflect(li);
414 this->ep_.reflect(li);
419 operator<<(std::ostream& out, PoseRange const& p)
421 out << "[" << p.x() << "," << p.y() << "," << p.b() << "," << p.e();
429 return this->curb_to_curb_;
433 CarSize::ctc(double ctc)
435 this->curb_to_curb_ = ctc;
441 return this->wheelbase_;
445 CarSize::wb(double wb)
447 this->wheelbase_ = wb;
465 return this->length_;
469 CarSize::len(double len)
477 return this->distance_to_front_;
481 CarSize::df(double df)
483 this->distance_to_front_ = df;
489 return this->len() - this->df();
495 auto ctc2 = pow(this->ctc() / 2.0, 2.0);
496 auto wb2 = pow(this->wb(), 2.0);
497 return sqrt(ctc2 - wb2) - this->w() / 2.0;
501 CarSize::iradi() const
503 return this->mtr() - this->w() / 2;
507 CarSize::ofradi() const
509 auto mtrw2 = pow(this->mtr() + this->w() / 2.0, 2.0);
510 auto df2 = pow(this->df(), 2.0);
511 return sqrt(mtrw2 + df2);
515 CarSize::orradi() const
517 auto mtrw2 = pow(this->mtr() + this->w() / 2.0, 2.0);
518 auto dr2 = pow(this->dr(), 2.0);
519 return sqrt(mtrw2 + dr2);
523 CarSize::perfect_parking_slot_len() const
525 auto r = this->ctc() / 2.0;
527 auto k = this->df() - this->wb();
529 auto r2l2 = r * r - l * l;
530 auto s = r2l2 + pow(l + k, 2.0) - pow(sqrt(r2l2) - w, 2.0);
531 return this->len() + sqrt(s) - l - k;
541 CarMove::sp(double sp)
553 CarMove::st(double st)
559 BicycleCar::drivable(Pose const& p) const
561 return this->drivable(PoseRange(p, p));
565 BicycleCar::drivable(PoseRange const& p) const
567 double a_1 = atan2(p.y() - this->y(), p.x() - this->x()) - this->h();
572 double h_d = p.h() - this->h();
578 if (h_d == 0 && (a_1 == 0 || a_2 == M_PI || a_2 == -M_PI)) {
580 } else if (0 < a_1 && a_1 <= M_PI/2) { // left front
581 BicycleCar z(*this); // zone border
583 h_d = p.h() - this->h();
584 z.rotate(this->ccl(), h_d);
585 // assert z.h() == p.h()
586 if (p.y() == z.y() && p.x() == z.x()) // p on zone border
588 a_2 = atan2(p.y() - z.y(), p.x() - z.x());
593 if (z.h() >= a_2 && a_2 >= this->h())
595 } else if (M_PI/2 < a_1 && a_1 <= M_PI) { // left rear
596 BicycleCar z(*this); // zone border
598 h_d = p.h() - this->h();
599 z.rotate(this->ccl(), h_d);
600 // assert z.h() == p.h()
601 if (p.y() == z.y() && p.x() == z.x()) // p on zone border
603 a_2 = atan2(p.y() - z.y(), p.x() - z.x());
609 if (this->h() >= a_2 && a_2 >= z.h())
611 } else if (0 > a_1 && a_1 >= -M_PI/2) { // right front
612 BicycleCar z(*this); // zone border
614 h_d = p.h() - this->h();
615 z.rotate(this->ccr(), h_d);
616 // assert z.h() == p.h()
617 if (p.y() == z.y() && p.x() == z.x()) // p on zone border
619 a_2 = atan2(p.y() - z.y(), p.x() - z.x());
624 if (this->h() >= a_2 && a_2 >= z.h())
626 } else if (-M_PI/2 > a_1 && a_1 >= -M_PI) { // right rear
627 BicycleCar z(*this); // zone border
629 h_d = p.h() - this->h();
630 z.rotate(this->ccr(), h_d);
631 // assert z.h() == p.h()
632 if (p.y() == z.y() && p.x() == z.x()) // p on zone border
634 a_2 = atan2(p.y() - z.y(), p.x() - z.x());
640 if (z.h() >= a_2 && a_2 >= this->h())
643 // Not happenning, as ``-pi <= a <= pi``.
649 BicycleCar::set_max_steer()
651 this->st(atan(this->wb() / this->mtr()));
655 BicycleCar::lfx() const
657 double lfx = this->x();
658 lfx += (this->w() / 2.0) * cos(this->h() + M_PI / 2.0);
659 lfx += this->df() * cos(this->h());
664 BicycleCar::lfy() const
666 double lfy = this->y();
667 lfy += (this->w() / 2.0) * sin(this->h() + M_PI / 2.0);
668 lfy += this->df() * sin(this->h());
673 BicycleCar::lrx() const
675 double lrx = this->x();
676 lrx += (this->w() / 2.0) * cos(this->h() + M_PI / 2.0);
677 lrx += -this->dr() * cos(this->h());
682 BicycleCar::lry() const
684 double lry = this->y();
685 lry += (this->w() / 2.0) * sin(this->h() + M_PI / 2.0);
686 lry += -this->dr() * sin(this->h());
691 BicycleCar::rrx() const
693 double rrx = this->x();
694 rrx += (this->w() / 2.0) * cos(this->h() - M_PI / 2.0);
695 rrx += -this->dr() * cos(this->h());
700 BicycleCar::rry() const
702 double rry = this->y();
703 rry += (this->w() / 2.0) * sin(this->h() - M_PI / 2.0);
704 rry += -this->dr() * sin(this->h());
709 BicycleCar::rfx() const
711 double rfx = this->x();
712 rfx += (this->w() / 2.0) * cos(this->h() - M_PI / 2.0);
713 rfx += this->df() * cos(this->h());
718 BicycleCar::rfy() const
720 double rfy = this->y();
721 rfy += (this->w() / 2.0) * sin(this->h() - M_PI / 2.0);
722 rfy += this->df() * sin(this->h());
727 BicycleCar::lf() const
729 return Point(this->lfx(), this->lfy());
733 BicycleCar::lr() const
735 return Point(this->lrx(), this->lry());
739 BicycleCar::rr() const
741 return Point(this->rrx(), this->rry());
745 BicycleCar::rf() const
747 return Point(this->rfx(), this->rfy());
751 BicycleCar::left() const
753 return Line(this->lr(), this->lf());
757 BicycleCar::rear() const
759 return Line(this->lr(), this->rr());
763 BicycleCar::right() const
765 return Line(this->rr(), this->rf());
769 BicycleCar::front() const
771 return Line(this->rf(), this->lf());
775 BicycleCar::ralx() const
777 double lrx = this->x();
778 lrx += (this->w() / 2.0) * cos(this->h() + M_PI / 2.0);
782 BicycleCar::raly() const
784 double lry = this->y();
785 lry += (this->w() / 2.0) * sin(this->h() + M_PI / 2.0);
790 BicycleCar::rarx() const
792 double rrx = this->x();
793 rrx += (this->w() / 2.0) * cos(this->h() - M_PI / 2.0);
798 BicycleCar::rary() const
800 double rry = this->y();
801 rry += (this->w() / 2.0) * sin(this->h() - M_PI / 2.0);
806 BicycleCar::ccl() const
809 this->x() + this->mtr() * cos(this->h() + M_PI / 2.0),
810 this->y() + this->mtr() * sin(this->h() + M_PI / 2.0)
815 BicycleCar::ccr() const
818 this->x() + this->mtr() * cos(this->h() - M_PI / 2.0),
819 this->y() + this->mtr() * sin(this->h() - M_PI / 2.0)
826 this->x(this->x() + this->sp() * cos(this->h()));
827 this->y(this->y() + this->sp() * sin(this->h()));
828 this->h(this->h() + this->sp() / this->wb() * tan(this->st()));