18 #include <Eigen/Dense>
25 template <
class TScalar,
int kN>
29 template <
class TScalar>
31 template <
class TScalar>
37 template <
class TScalar,
int kN>
47 [[nodiscard]]
auto origin() const ->
Eigen::Matrix<TScalar, kN, 1> const& {
50 [[nodiscard]]
auto origin() -> Eigen::Matrix<TScalar, kN, 1>& {
61 [[nodiscard]]
auto pointAt(TScalar lambda)
const
62 -> Eigen::Matrix<TScalar, kN, 1> {
63 return this->origin_ + lambda * this->direction_.params();
68 Eigen::Matrix<TScalar, kN, 1>
point;
71 [[nodiscard]]
auto intersect(Eigen::Hyperplane<TScalar, kN>
const& plane)
72 const -> std::optional<IntersectionResult> {
74 TScalar dot_prod = plane.normal().dot(this->direction_.vector());
75 if (abs(dot_prod) < sophus::kEpsilon<TScalar>) {
80 -(plane.offset() + plane.normal().dot(this->origin_)) / dot_prod;
85 [[nodiscard]]
auto projection(Eigen::Matrix<TScalar, kN, 1>
const& point)
86 const -> Eigen::Matrix<TScalar, kN, 1> {
88 direction_.getVector().dot(point - origin_) * direction_.vector();
92 Eigen::Matrix<TScalar, kN, 1> origin_;
101 bar_from_foo * ray_foo.origin(),
102 bar_from_foo.so2() * ray_foo.direction());
110 bar_from_foo * ray_foo.origin(),
111 bar_from_foo.so3() * ray_foo.direction());
120 return Ray<TT, 3>(bar_from_foo.translation(), bar_from_foo.so3() * v_foo);
126 return Ray2<TT>(b_from_a * ray_a.origin(), b_from_a * ray_a.direction());
132 return Ray3<TT>(b_from_a * ray_a.origin(), b_from_a * ray_a.direction());
153 -> std::optional<ClosestApproachResult<TT>> {
164 Eigen::Vector<TT, 3>
const d0_cross_d1 =
165 line_0.direction().params().cross(line_1.direction().params());
167 TT
const d0_cross_s1_length = d0_cross_d1.norm();
169 if (d0_cross_s1_length < kEpsilon<TT>) {
174 Eigen::Matrix<TT, 3, 3> mat_a;
175 mat_a << line_0.direction().params(), -line_1.direction().params(),
178 Eigen::Vector<TT, 3>
const b = line_1.origin() - line_0.origin();
180 Eigen::Vector<TT, 3>
const x = mat_a.lu().solve(b);
181 TT
const lambda0 = x[0];
182 TT
const lambda1 = x[1];
183 TT
const min_distance = d0_cross_s1_length * x[2];
196 -> std::optional<Eigen::Vector3<TT>> {
201 return (line_0.pointAt(maybe_result->lambda0) +
202 line_1.pointAt(maybe_result->lambda1)) /
203 static_cast<TT
>(2.0);