]> rtime.felk.cvut.cz Git - hubacji1/bcar.git/blobdiff - src/bcar.cc
Change spacing
[hubacji1/bcar.git] / src / bcar.cc
index cd317a409ad20978a12ec6f62accccc0181b0d36..248ea49b3f31449ddd75dfa4750050c2632681a5 100644 (file)
@@ -8,403 +8,403 @@ bool BicycleCar::drivable(const BicycleCar &bc) const
 }
 bool BicycleCar::drivable(const BicycleCar &bc, double b, double e) const
 {
-        // assert bc.h() == (b + e) / 2.0
-        double a_1 = atan2(bc.y() - this->y(), bc.x() - this->x()) - this->h();
-        while (a_1 < -M_PI)
-                a_1 += 2 * M_PI;
-        while (a_1 > +M_PI)
-                a_1 -= 2 * M_PI;
-        double h_d = bc.h() - this->h();
-        while (h_d < -M_PI)
-                h_d += 2 * M_PI;
-        while (h_d > +M_PI)
-                h_d -= 2 * M_PI;
-        double a_2 = 0;
-        if (h_d == 0 && (a_1 == 0 || a_2 == M_PI || a_2 == -M_PI)) {
-                return true;
-        } else if (0 < a_1 && a_1 <= M_PI/2) { // left front
-                BicycleCar z(*this); // zone border
-                z.h(e);
-                h_d = bc.h() - this->h();
-                z.rotate(this->ccl().x(), this->ccl().y(), h_d);
-                // assert z.h() == bc.h()
-                if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
-                        return true;
-                a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
-                while (a_2 < -M_PI)
-                        a_2 += 2 * M_PI;
-                while (a_2 > +M_PI)
-                        a_2 -= 2 * M_PI;
-                if (z.h() >= a_2 && a_2 >= this->h())
-                        return true;
-        } else if (M_PI/2 < a_1 && a_1 <= M_PI) { // left rear
-                BicycleCar z(*this); // zone border
-                z.h(e);
-                h_d = bc.h() - this->h();
-                z.rotate(this->ccl().x(), this->ccl().y(), h_d);
-                // assert z.h() == bc.h()
-                if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
-                        return true;
-                a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
-                a_2 -= M_PI;
-                while (a_2 < -M_PI)
-                        a_2 += 2 * M_PI;
-                while (a_2 > +M_PI)
-                        a_2 -= 2 * M_PI;
-                if (this->h() >= a_2 && a_2 >= z.h())
-                        return true;
-        } else if (0 > a_1 && a_1 >= -M_PI/2) { // right front
-                BicycleCar z(*this); // zone border
-                z.h(b);
-                h_d = bc.h() - this->h();
-                z.rotate(this->ccr().x(), this->ccr().y(), h_d);
-                // assert z.h() == bc.h()
-                if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
-                        return true;
-                a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
-                while (a_2 < -M_PI)
-                        a_2 += 2 * M_PI;
-                while (a_2 > +M_PI)
-                        a_2 -= 2 * M_PI;
-                if (this->h() >= a_2 && a_2 >= z.h())
-                        return true;
-        } else if (-M_PI/2 > a_1 && a_1 >= -M_PI) { // right rear
-                BicycleCar z(*this); // zone border
-                z.h(b);
-                h_d = bc.h() - this->h();
-                z.rotate(this->ccr().x(), this->ccr().y(), h_d);
-                // assert z.h() == bc.h()
-                if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
-                        return true;
-                a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
-                a_2 -= M_PI;
-                while (a_2 < -M_PI)
-                        a_2 += 2 * M_PI;
-                while (a_2 > +M_PI)
-                        a_2 -= 2 * M_PI;
-                if (z.h() >= a_2 && a_2 >= this->h())
-                        return true;
-        } else {
-                // Not happenning, as ``-pi <= a <= pi``.
-        }
-        return false;
+       // assert bc.h() == (b + e) / 2.0
+       double a_1 = atan2(bc.y() - this->y(), bc.x() - this->x()) - this->h();
+       while (a_1 < -M_PI)
+               a_1 += 2 * M_PI;
+       while (a_1 > +M_PI)
+               a_1 -= 2 * M_PI;
+       double h_d = bc.h() - this->h();
+       while (h_d < -M_PI)
+               h_d += 2 * M_PI;
+       while (h_d > +M_PI)
+               h_d -= 2 * M_PI;
+       double a_2 = 0;
+       if (h_d == 0 && (a_1 == 0 || a_2 == M_PI || a_2 == -M_PI)) {
+               return true;
+       } else if (0 < a_1 && a_1 <= M_PI/2) { // left front
+               BicycleCar z(*this); // zone border
+               z.h(e);
+               h_d = bc.h() - this->h();
+               z.rotate(this->ccl().x(), this->ccl().y(), h_d);
+               // assert z.h() == bc.h()
+               if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
+                       return true;
+               a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
+               while (a_2 < -M_PI)
+                       a_2 += 2 * M_PI;
+               while (a_2 > +M_PI)
+                       a_2 -= 2 * M_PI;
+               if (z.h() >= a_2 && a_2 >= this->h())
+                       return true;
+       } else if (M_PI/2 < a_1 && a_1 <= M_PI) { // left rear
+               BicycleCar z(*this); // zone border
+               z.h(e);
+               h_d = bc.h() - this->h();
+               z.rotate(this->ccl().x(), this->ccl().y(), h_d);
+               // assert z.h() == bc.h()
+               if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
+                       return true;
+               a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
+               a_2 -= M_PI;
+               while (a_2 < -M_PI)
+                       a_2 += 2 * M_PI;
+               while (a_2 > +M_PI)
+                       a_2 -= 2 * M_PI;
+               if (this->h() >= a_2 && a_2 >= z.h())
+                       return true;
+       } else if (0 > a_1 && a_1 >= -M_PI/2) { // right front
+               BicycleCar z(*this); // zone border
+               z.h(b);
+               h_d = bc.h() - this->h();
+               z.rotate(this->ccr().x(), this->ccr().y(), h_d);
+               // assert z.h() == bc.h()
+               if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
+                       return true;
+               a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
+               while (a_2 < -M_PI)
+                       a_2 += 2 * M_PI;
+               while (a_2 > +M_PI)
+                       a_2 -= 2 * M_PI;
+               if (this->h() >= a_2 && a_2 >= z.h())
+                       return true;
+       } else if (-M_PI/2 > a_1 && a_1 >= -M_PI) { // right rear
+               BicycleCar z(*this); // zone border
+               z.h(b);
+               h_d = bc.h() - this->h();
+               z.rotate(this->ccr().x(), this->ccr().y(), h_d);
+               // assert z.h() == bc.h()
+               if (bc.y() == z.y() && bc.x() == z.x()) // bc on zone border
+                       return true;
+               a_2 = atan2(bc.y() - z.y(), bc.x() - z.x());
+               a_2 -= M_PI;
+               while (a_2 < -M_PI)
+                       a_2 += 2 * M_PI;
+               while (a_2 > +M_PI)
+                       a_2 -= 2 * M_PI;
+               if (z.h() >= a_2 && a_2 >= this->h())
+                       return true;
+       } else {
+               // Not happenning, as ``-pi <= a <= pi``.
+       }
+       return false;
 }
 
 double BicycleCar::iradi() const
 {
-        return this->mtr() - this->w() / 2;
+       return this->mtr() - this->w() / 2;
 }
 
 double BicycleCar::ofradi() const
 {
-        return sqrt(pow(this->mtr() + this->w() / 2, 2) + pow(this->df(), 2));
+       return sqrt(pow(this->mtr() + this->w() / 2, 2) + pow(this->df(), 2));
 }
 
 double BicycleCar::orradi() const
 {
-        return sqrt(pow(this->mtr() + this->w() / 2, 2) + pow(this->dr(), 2));
+       return sqrt(pow(this->mtr() + this->w() / 2, 2) + pow(this->dr(), 2));
 }
 
 double BicycleCar::perfect_parking_slot_len() const
 {
-        // see Simon R. Blackburn *The Geometry of Perfect Parking*
-        // see https://www.ma.rhul.ac.uk/SRBparking
-        double r = this->ctc() / 2;
-        double l = this->wb();
-        double k = this->df() - this->wb();
-        double w = this->w();
-        return
-                this->l()
-                + sqrt(
-                        (r*r - l*l)
-                        + pow(l + k, 2)
-                        - pow(sqrt(r*r - l*l) - w, 2)
-                )
-                - l
-                - k
-        ;
+       // see Simon R. Blackburn *The Geometry of Perfect Parking*
+       // see https://www.ma.rhul.ac.uk/SRBparking
+       double r = this->ctc() / 2;
+       double l = this->wb();
+       double k = this->df() - this->wb();
+       double w = this->w();
+       return
+               this->l()
+               + sqrt(
+                       (r*r - l*l)
+                       + pow(l + k, 2)
+                       - pow(sqrt(r*r - l*l) - w, 2)
+               )
+               - l
+               - k
+       ;
 }
 
 void BicycleCar::set_max_steer()
 {
-        this->st(atan(this->wb() / this->mtr()));
+       this->st(atan(this->wb() / this->mtr()));
 }
 
 // car frame
 double BicycleCar::lfx() const
 {
-        double lfx = this->x();
-        lfx += (this->w() / 2) * cos(this->h() + M_PI / 2);
-        lfx += this->df() * cos(this->h());
-        lfx += this->sd() * cos(this->h());
-        return lfx;
+       double lfx = this->x();
+       lfx += (this->w() / 2) * cos(this->h() + M_PI / 2);
+       lfx += this->df() * cos(this->h());
+       lfx += this->sd() * cos(this->h());
+       return lfx;
 }
 
 double BicycleCar::lfy() const
 {
-        double lfy = this->y();
-        lfy += (this->w() / 2) * sin(this->h() + M_PI / 2);
-        lfy += this->df() * sin(this->h());
-        lfy += this->sd() * sin(this->h());
-        return lfy;
+       double lfy = this->y();
+       lfy += (this->w() / 2) * sin(this->h() + M_PI / 2);
+       lfy += this->df() * sin(this->h());
+       lfy += this->sd() * sin(this->h());
+       return lfy;
 }
 
 double BicycleCar::lrx() const
 {
-        double lrx = this->x();
-        lrx += (this->w() / 2) * cos(this->h() + M_PI / 2);
-        lrx += -this->dr() * cos(this->h());
-        lrx += -this->sd() * cos(this->h());
-        return lrx;
+       double lrx = this->x();
+       lrx += (this->w() / 2) * cos(this->h() + M_PI / 2);
+       lrx += -this->dr() * cos(this->h());
+       lrx += -this->sd() * cos(this->h());
+       return lrx;
 }
 
 double BicycleCar::lry() const
 {
-        double lry = this->y();
-        lry += (this->w() / 2) * sin(this->h() + M_PI / 2);
-        lry += -this->dr() * sin(this->h());
-        lry += -this->sd() * sin(this->h());
-        return lry;
+       double lry = this->y();
+       lry += (this->w() / 2) * sin(this->h() + M_PI / 2);
+       lry += -this->dr() * sin(this->h());
+       lry += -this->sd() * sin(this->h());
+       return lry;
 }
 
 double BicycleCar::rrx() const
 {
-        double rrx = this->x();
-        rrx += (this->w() / 2) * cos(this->h() - M_PI / 2);
-        rrx += -this->dr() * cos(this->h());
-        rrx += -this->sd() * cos(this->h());
-        return rrx;
+       double rrx = this->x();
+       rrx += (this->w() / 2) * cos(this->h() - M_PI / 2);
+       rrx += -this->dr() * cos(this->h());
+       rrx += -this->sd() * cos(this->h());
+       return rrx;
 }
 
 double BicycleCar::rry() const
 {
-        double rry = this->y();
-        rry += (this->w() / 2) * sin(this->h() - M_PI / 2);
-        rry += -this->dr() * sin(this->h());
-        rry += -this->sd() * sin(this->h());
-        return rry;
+       double rry = this->y();
+       rry += (this->w() / 2) * sin(this->h() - M_PI / 2);
+       rry += -this->dr() * sin(this->h());
+       rry += -this->sd() * sin(this->h());
+       return rry;
 }
 
 double BicycleCar::rfx() const
 {
-        double rfx = this->x();
-        rfx += (this->w() / 2) * cos(this->h() - M_PI / 2);
-        rfx += this->df() * cos(this->h());
-        rfx += this->sd() * cos(this->h());
-        return rfx;
+       double rfx = this->x();
+       rfx += (this->w() / 2) * cos(this->h() - M_PI / 2);
+       rfx += this->df() * cos(this->h());
+       rfx += this->sd() * cos(this->h());
+       return rfx;
 }
 
 double BicycleCar::rfy() const
 {
-        double rfy = this->y();
-        rfy += (this->w() / 2) * sin(this->h() - M_PI / 2);
-        rfy += this->df() * sin(this->h());
-        rfy += this->sd() * sin(this->h());
-        return rfy;
+       double rfy = this->y();
+       rfy += (this->w() / 2) * sin(this->h() - M_PI / 2);
+       rfy += this->df() * sin(this->h());
+       rfy += this->sd() * sin(this->h());
+       return rfy;
 }
 
 double BicycleCar::ralx() const
 {
-        double lrx = this->x();
-        lrx += (this->w() / 2) * cos(this->h() + M_PI / 2);
-        return lrx;
+       double lrx = this->x();
+       lrx += (this->w() / 2) * cos(this->h() + M_PI / 2);
+       return lrx;
 }
 double BicycleCar::raly() const
 {
-        double lry = this->y();
-        lry += (this->w() / 2) * sin(this->h() + M_PI / 2);
-        return lry;
+       double lry = this->y();
+       lry += (this->w() / 2) * sin(this->h() + M_PI / 2);
+       return lry;
 }
 
 double BicycleCar::rarx() const
 {
-        double rrx = this->x();
-        rrx += (this->w() / 2) * cos(this->h() - M_PI / 2);
-        return rrx;
+       double rrx = this->x();
+       rrx += (this->w() / 2) * cos(this->h() - M_PI / 2);
+       return rrx;
 }
 
 double BicycleCar::rary() const
 {
-        double rry = this->y();
-        rry += (this->w() / 2) * sin(this->h() - M_PI / 2);
-        return rry;
+       double rry = this->y();
+       rry += (this->w() / 2) * sin(this->h() - M_PI / 2);
+       return rry;
 }
 
 BicycleCar BicycleCar::ccl() const
 {
-        BicycleCar bc;
-        bc.x(this->x() + this->mtr() * cos(this->h() + M_PI / 2));
-        bc.y(this->y() + this->mtr() * sin(this->h() + M_PI / 2));
-        bc.h(this->h());
-        return bc;
+       BicycleCar bc;
+       bc.x(this->x() + this->mtr() * cos(this->h() + M_PI / 2));
+       bc.y(this->y() + this->mtr() * sin(this->h() + M_PI / 2));
+       bc.h(this->h());
+       return bc;
 }
 
 BicycleCar BicycleCar::ccr() const
 {
-        BicycleCar bc;
-        bc.x(this->x() + this->mtr() * cos(this->h() - M_PI / 2));
-        bc.y(this->y() + this->mtr() * sin(this->h() - M_PI / 2));
-        bc.h(this->h());
-        return bc;
+       BicycleCar bc;
+       bc.x(this->x() + this->mtr() * cos(this->h() - M_PI / 2));
+       bc.y(this->y() + this->mtr() * sin(this->h() - M_PI / 2));
+       bc.h(this->h());
+       return bc;
 }
 
 // moving
 void BicycleCar::next()
 {
-        this->x(this->x() + this->sp() * cos(this->h()));
-        this->y(this->y() + this->sp() * sin(this->h()));
-        this->h(this->h() + this->sp() / this->wb() * tan(this->st()));
+       this->x(this->x() + this->sp() * cos(this->h()));
+       this->y(this->y() + this->sp() * sin(this->h()));
+       this->h(this->h() + this->sp() / this->wb() * tan(this->st()));
 }
 
 void BicycleCar::rotate(double cx, double cy, double angl)
 {
-        double px = this->x();
-        double py = this->y();
-        px -= cx;
-        py -= cy;
-        double nx = px * cos(angl) - py * sin(angl);
-        double ny = px * sin(angl) + py * cos(angl);
-        this->h(this->h() + angl);
-        this->x(nx + cx);
-        this->y(ny + cy);
+       double px = this->x();
+       double py = this->y();
+       px -= cx;
+       py -= cy;
+       double nx = px * cos(angl) - py * sin(angl);
+       double ny = px * sin(angl) + py * cos(angl);
+       this->h(this->h() + angl);
+       this->x(nx + cx);
+       this->y(ny + cy);
 }
 
 BicycleCar::BicycleCar()
 {
-        // TODO according to mtr_ FIXME
-        this->mtr_ = sqrt(
-                        pow(10.82 / 2, 2)
-                        - pow(this->wb(), 2)
-                )
-                - this->w() / 2
-        ;
+       // TODO according to mtr_ FIXME
+       this->mtr_ = sqrt(
+                       pow(10.82 / 2, 2)
+                       - pow(this->wb(), 2)
+               )
+               - this->w() / 2
+       ;
 }
 
 std::tuple<bool, unsigned int, unsigned int>
 collide(
-        std::vector<std::tuple<double, double>> &p1,
-        std::vector<std::tuple<double, double>> &p2
+       std::vector<std::tuple<double, double>> &p1,
+       std::vector<std::tuple<double, double>> &p2
 )
 {
-        for (unsigned int i = 0; i < p1.size() - 1; i++) {
-                for (unsigned int j = 0; j < p2.size() - 1; j++) {
-                        auto x = intersect(
-                                std::get<0>(p1[i]),
-                                std::get<1>(p1[i]),
-                                std::get<0>(p1[i + 1]),
-                                std::get<1>(p1[i + 1]),
-                                std::get<0>(p2[j]),
-                                std::get<1>(p2[j]),
-                                std::get<0>(p2[j + 1]),
-                                std::get<1>(p2[j + 1])
-                        );
-                        if (std::get<0>(x))
-                                return std::make_tuple(true, i, j);
-                }
-        }
-        return std::make_tuple(false, 0, 0);
+       for (unsigned int i = 0; i < p1.size() - 1; i++) {
+               for (unsigned int j = 0; j < p2.size() - 1; j++) {
+                       auto x = intersect(
+                               std::get<0>(p1[i]),
+                               std::get<1>(p1[i]),
+                               std::get<0>(p1[i + 1]),
+                               std::get<1>(p1[i + 1]),
+                               std::get<0>(p2[j]),
+                               std::get<1>(p2[j]),
+                               std::get<0>(p2[j + 1]),
+                               std::get<1>(p2[j + 1])
+                       );
+                       if (std::get<0>(x))
+                               return std::make_tuple(true, i, j);
+               }
+       }
+       return std::make_tuple(false, 0, 0);
 }
 
 bool
 inside(double x, double y, std::vector<std::tuple<double, double>> &poly)
 {
-        unsigned int i = 0;
-        unsigned int j = 3;
-        bool inside = false;
-        for (i = 0; i < 4; i++) {
-                if (
-                        (std::get<1>(poly[i]) > y) != (std::get<1>(poly[j]) > y)
-                        && (
-                                x < std::get<0>(poly[i])
-                                + (std::get<0>(poly[j]) - std::get<0>(poly[i]))
-                                * (y - std::get<1>(poly[i]))
-                                / (std::get<1>(poly[j]) - std::get<1>(poly[i]))
-                        )
-                )
-                        inside = !inside;
-                j = i;
-        }
-        return inside;
+       unsigned int i = 0;
+       unsigned int j = 3;
+       bool inside = false;
+       for (i = 0; i < 4; i++) {
+               if (
+                       (std::get<1>(poly[i]) > y) != (std::get<1>(poly[j]) > y)
+                       && (
+                               x < std::get<0>(poly[i])
+                               + (std::get<0>(poly[j]) - std::get<0>(poly[i]))
+                               * (y - std::get<1>(poly[i]))
+                               / (std::get<1>(poly[j]) - std::get<1>(poly[i]))
+                       )
+               )
+                       inside = !inside;
+               j = i;
+       }
+       return inside;
 }
 
 std::tuple<bool, double, double>
 intersect(
-        double x1, double y1,
-        double x2, double y2,
-        double x3, double y3,
-        double x4, double y4
+       double x1, double y1,
+       double x2, double y2,
+       double x3, double y3,
+       double x4, double y4
 )
 {
-        double deno = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-        if (deno == 0)
-                return std::make_tuple(false, 0, 0);
-        double t = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4);
-        t /= deno;
-        double u = (x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3);
-        u *= -1;
-        u /= deno;
-        if (t < 0 || t > 1 || u < 0 || u > 1)
-                return std::make_tuple(false, 0, 0);
-        return std::make_tuple(true, x1 + t * (x2 - x1), y1 + t * (y2 - y1));
+       double deno = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
+       if (deno == 0)
+               return std::make_tuple(false, 0, 0);
+       double t = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4);
+       t /= deno;
+       double u = (x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3);
+       u *= -1;
+       u /= deno;
+       if (t < 0 || t > 1 || u < 0 || u > 1)
+               return std::make_tuple(false, 0, 0);
+       return std::make_tuple(true, x1 + t * (x2 - x1), y1 + t * (y2 - y1));
 }
 
 std::tuple<bool, double, double, double, double>
 intersect(
-        double cx, double cy, double r,
-        double x1, double y1,
-        double x2, double y2
+       double cx, double cy, double r,
+       double x1, double y1,
+       double x2, double y2
 ) {
-        x2 -= cx;
-        x1 -= cx;
-        y2 -= cy;
-        y1 -= cy;
-        if (y1 == y2)
-            y1 += 0.00001;
-        double dx = x2 - x1;
-        double dy = y2 - y1;
-        double dr = sqrt(dx*dx + dy*dy);
-        double D = x1*y2 - x2*y1;
-        if (r*r * dr*dr - D*D < 0)
-        return std::make_tuple(false, 0, 0, 0, 0);
-        // intersection coordinates
-        double ix1 = (D*dy + sgn(dy)*dx*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
-        ix1 += cx;
-        double ix2 = (D*dy - sgn(dy)*dx*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
-        ix2 += cx;
-        double iy1 = (-D*dx + std::abs(dy)*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
-        iy1 += cy;
-        double iy2 = (-D*dx - std::abs(dy)*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
-        iy2 += cy;
-        return std::make_tuple(true, ix1, iy1, ix2, iy2);
+       x2 -= cx;
+       x1 -= cx;
+       y2 -= cy;
+       y1 -= cy;
+       if (y1 == y2)
+           y1 += 0.00001;
+       double dx = x2 - x1;
+       double dy = y2 - y1;
+       double dr = sqrt(dx*dx + dy*dy);
+       double D = x1*y2 - x2*y1;
+       if (r*r * dr*dr - D*D < 0)
+       return std::make_tuple(false, 0, 0, 0, 0);
+       // intersection coordinates
+       double ix1 = (D*dy + sgn(dy)*dx*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
+       ix1 += cx;
+       double ix2 = (D*dy - sgn(dy)*dx*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
+       ix2 += cx;
+       double iy1 = (-D*dx + std::abs(dy)*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
+       iy1 += cy;
+       double iy2 = (-D*dx - std::abs(dy)*sqrt(r*r * dr*dr - D*D)) / (dr*dr);
+       iy2 += cy;
+       return std::make_tuple(true, ix1, iy1, ix2, iy2);
 }
 
 double
 angle_between_three_points(
-        double x1, double y1,
-        double x2, double y2,
-        double x3, double y3
+       double x1, double y1,
+       double x2, double y2,
+       double x3, double y3
 ) {
-        double d1x = x2 - x1;
-        double d1y = y2 - y1;
-        double d2x = x3 - x2;
-        double d2y = y3 - y2;
+       double d1x = x2 - x1;
+       double d1y = y2 - y1;
+       double d2x = x3 - x2;
+       double d2y = y3 - y2;
 
-        double dot = d1x*d2x + d1y*d2y;
-        double d1 = sqrt(d1x*d1x + d1y*d1y);
-        double d2 = sqrt(d2x*d2x + d2y*d2y);
+       double dot = d1x*d2x + d1y*d2y;
+       double d1 = sqrt(d1x*d1x + d1y*d1y);
+       double d2 = sqrt(d2x*d2x + d2y*d2y);
 
-        double delta = acos(dot / (d1 * d2));
-        return std::min(delta, M_PI - delta);
+       double delta = acos(dot / (d1 * d2));
+       return std::min(delta, M_PI - delta);
 }
 
 bool
 right_side_of_line(
-        double x1, double y1,
-        double x2, double y2,
-        double x3, double y3
+       double x1, double y1,
+       double x2, double y2,
+       double x3, double y3
 ) {
-        if (sgn((x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1)) < 0)
-                return false;
-        else
-                return true;
+       if (sgn((x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1)) < 0)
+               return false;
+       else
+               return true;
 }