23#include "absl/strings/str_cat.h"
33bool IsWithin(
double val,
double bound1,
double bound2) {
34 if (bound1 > bound2) {
35 std::swap(bound1, bound2);
45 : start_(start), end_(end) {
46 const double dx = end_.
x() - start_.
x();
47 const double dy = end_.
y() - start_.
y();
48 length_ = hypot(dx, dy);
51 :
Vec2d(dx / length_, dy / length_));
52 heading_ = unit_direction_.
Angle();
56 Vec2d diff_vec = end_ - start_;
58 return start_ + diff_vec;
69 const double x0 = point.
x() - start_.
x();
70 const double y0 = point.
y() - start_.
y();
71 const double proj = x0 * unit_direction_.
x() + y0 * unit_direction_.
y();
75 if (proj >= length_) {
78 return std::abs(x0 * unit_direction_.
y() - y0 * unit_direction_.
x());
82 Vec2d *
const nearest_pt)
const {
83 CHECK_NOTNULL(nearest_pt);
88 const double x0 = point.
x() - start_.
x();
89 const double y0 = point.
y() - start_.
y();
90 const double proj = x0 * unit_direction_.
x() + y0 * unit_direction_.
y();
99 *nearest_pt = start_ + unit_direction_ * proj;
100 return std::abs(x0 * unit_direction_.
y() - y0 * unit_direction_.
x());
107 const double x0 = point.
x() - start_.
x();
108 const double y0 = point.
y() - start_.
y();
109 const double proj = x0 * unit_direction_.
x() + y0 * unit_direction_.
y();
113 if (proj >= length_) {
116 return Square(x0 * unit_direction_.
y() - y0 * unit_direction_.
x());
120 Vec2d *
const nearest_pt)
const {
121 CHECK_NOTNULL(nearest_pt);
123 *nearest_pt = start_;
126 const double x0 = point.
x() - start_.
x();
127 const double y0 = point.
y() - start_.
y();
128 const double proj = x0 * unit_direction_.
x() + y0 * unit_direction_.
y();
130 *nearest_pt = start_;
133 if (proj >= length_) {
137 *nearest_pt = start_ + unit_direction_ * proj;
138 return Square(x0 * unit_direction_.
y() - y0 * unit_direction_.
x());
146 const double prod =
CrossProd(point, start_, end_);
150 return IsWithin(point.
x(), start_.
x(), end_.
x()) &&
151 IsWithin(point.
y(), start_.
y(), end_.
y());
155 return unit_direction_.
InnerProd(point - start_);
159 return unit_direction_.
CrossProd(point - start_);
168 Vec2d *
const point)
const {
169 CHECK_NOTNULL(point);
171 *point = other_segment.
start();
175 *point = other_segment.
end();
189 const double cc1 =
CrossProd(start_, end_, other_segment.
start());
190 const double cc2 =
CrossProd(start_, end_, other_segment.
end());
201 const double ratio = cc4 / (cc4 - cc3);
202 *point =
Vec2d(start_.
x() * ratio + end_.
x() * (1.0 - ratio),
203 start_.
y() * ratio + end_.
y() * (1.0 - ratio));
209 Vec2d *
const foot_point)
const {
210 CHECK_NOTNULL(foot_point);
212 *foot_point = start_;
215 const double x0 = point.
x() - start_.
x();
216 const double y0 = point.
y() - start_.
y();
217 const double proj = x0 * unit_direction_.
x() + y0 * unit_direction_.
y();
218 *foot_point = start_ + unit_direction_ * proj;
219 return std::abs(x0 * unit_direction_.
y() - y0 * unit_direction_.
x());
223 return absl::StrCat(
"segment2d ( start = ", start_.
DebugString(),
double DistanceSquareTo(const Vec2d &point) const
Compute the square of the shortest distance from a point on the line segment to a point in 2-D.
bool HasIntersect(const LineSegment2d &other_segment) const
Check if the line segment has an intersect with another line segment in 2-D.
const Vec2d & end() const
Get the end point.
double GetPerpendicularFoot(const Vec2d &point, Vec2d *const foot_point) const
Compute perpendicular foot of a point in 2-D on the straight line expanded from the line segment.
double ProjectOntoUnit(const Vec2d &point) const
Compute the projection of a vector onto the line segment.
double ProductOntoUnit(const Vec2d &point) const
Compute the cross product of a vector onto the line segment.
Vec2d rotate(const double angle)
Get a new line-segment with the same start point, but rotated counterclock-wise by the given amount.
double length() const
Get the length of the line segment.
LineSegment2d()
Empty constructor.
bool GetIntersect(const LineSegment2d &other_segment, Vec2d *const point) const
Compute the intersect with another line segment in 2-D if any.
double DistanceTo(const Vec2d &point) const
Compute the shortest distance from a point on the line segment to a point in 2-D.
const Vec2d & start() const
Get the start point.
double length_sqr() const
Get the square of length of the line segment.
std::string DebugString() const
Get the debug string including the essential information.
bool IsPointIn(const Vec2d &point) const
Check if a point is within the line segment.
Implements a class of 2-dimensional vectors.
void SelfRotate(const double angle)
rotate the vector itself by angle.
double DistanceSquareTo(const Vec2d &other) const
Returns the squared distance to the given vector
double InnerProd(const Vec2d &other) const
Returns the inner product between these two Vec2d.
std::string DebugString() const
Returns a human-readable string representing this object
double y() const
Getter for y component
double Angle() const
Gets the angle between the vector and the positive x semi-axis
double DistanceTo(const Vec2d &other) const
Returns the distance to the given vector
double x() const
Getter for x component
double CrossProd(const Vec2d &other) const
Returns the "cross" product between these two Vec2d (non-standard).
Define the LineSegment2d class.
Math-related util functions.
constexpr double kMathEpsilon
double CrossProd(const Vec2d &start_point, const Vec2d &end_point_1, const Vec2d &end_point_2)
Cross product between two 2-D vectors from the common start point, and end at two other points.
T Square(const T value)
Compute squared value.