47 #include <ilqgames/constraint/polyline2_signed_distance_constraint.h> 48 #include <ilqgames/geometry/line_segment2.h> 49 #include <ilqgames/geometry/polyline2.h> 50 #include <ilqgames/utils/types.h> 52 #include <glog/logging.h> 58 float Polyline2SignedDistanceConstraint::Evaluate(
const VectorXf& input)
const {
59 CHECK_LT(xidx_, input.size());
60 CHECK_LT(yidx_, input.size());
63 float signed_distance_sq;
64 polyline_.ClosestPoint(Point2(input(xidx_), input(yidx_)),
nullptr,
nullptr,
67 const float value = signed_sqrt(signed_distance_sq) - threshold_;
68 return (keep_left_) ? value : -value;
71 void Polyline2SignedDistanceConstraint::Quadraticize(Time t,
72 const VectorXf& input,
74 VectorXf* grad)
const {
75 CHECK_LT(xidx_, input.size());
76 CHECK_LT(yidx_, input.size());
79 CHECK_EQ(hess->rows(), input.size());
80 CHECK_EQ(hess->cols(), input.size());
81 CHECK_EQ(grad->size(), input.size());
86 LineSegment2 closest_segment(Point2::Zero(), Point2::Ones());
87 float signed_distance_sq;
88 const Point2 closest_point =
89 polyline_.ClosestPoint(Point2(input(xidx_), input(yidx_)), &is_vertex,
90 &closest_segment, &signed_distance_sq);
91 const float s = sgn(signed_distance_sq);
94 const float x = input(xidx_);
95 const float y = input(yidx_);
96 float px = closest_segment.FirstPoint().x();
97 float py = closest_segment.FirstPoint().y();
100 float d_sq = rx * rx + ry * ry;
101 float d = std::sqrt(d_sq);
102 const float ux = closest_segment.UnitDirection().x();
103 const float uy = closest_segment.UnitDirection().y();
104 const float sign = (keep_left_) ? 1.0 : -1.0;
107 const float g = (keep_left_) ? signed_sqrt(signed_distance_sq) - threshold_
108 : threshold_ - signed_sqrt(signed_distance_sq);
111 float dx = sign * uy;
113 float dy = -sign * ux;
119 px = closest_point.x();
120 py = closest_point.y();
123 d_sq = (rx * rx + ry * ry);
126 dx = sign * s * rx / d;
127 ddx = sign * s * (d_sq - px * px - x * x + 2 * px * x) / (d_sq * d);
128 dxdy = -sign * s * rx * ry / (d_sq * d);
129 dy = sign * s * ry / d;
130 ddy = sign * s * (d_sq - py * py - y * y + 2 * py * y) / (d_sq * d);
134 ModifyDerivatives(t, g, &dx, &ddx, &dy, &ddy, &dxdy);
137 (*grad)(xidx_) += dx;
138 (*grad)(yidx_) += dy;
140 (*hess)(xidx_, xidx_) += ddx;
141 (*hess)(xidx_, yidx_) += dxdy;
142 (*hess)(yidx_, xidx_) += dxdy;
143 (*hess)(yidx_, yidx_) += ddy;