#pragma once #include "vde/core/point.h" namespace vde::core { template class Line3D { public: Line3D() = default; Line3D(const Point3D& origin, const Vector3D& direction) : origin_(origin), direction_(direction.normalized()) {} [[nodiscard]] const Point3D& origin() const { return origin_; } [[nodiscard]] const Vector3D& direction() const { return direction_; } [[nodiscard]] Point3D point_at(T t) const { return origin_ + direction_ * t; } private: Point3D origin_{0,0,0}; Vector3D direction_{1,0,0}; }; template class Segment3D { public: Segment3D() = default; Segment3D(const Point3D& p0, const Point3D& p1) : p0_(p0), p1_(p1) {} [[nodiscard]] const Point3D& p0() const { return p0_; } [[nodiscard]] const Point3D& p1() const { return p1_; } [[nodiscard]] Vector3D direction() const { return p1_ - p0_; } [[nodiscard]] T length() const { return direction().norm(); } private: Point3D p0_{0,0,0}, p1_{0,0,0}; }; template class Ray3D { public: Ray3D() = default; Ray3D(const Point3D& origin, const Vector3D& direction) : origin_(origin), direction_(direction.normalized()) {} [[nodiscard]] const Point3D& origin() const { return origin_; } [[nodiscard]] const Vector3D& direction() const { return direction_; } [[nodiscard]] Point3D point_at(T t) const { return origin_ + direction_ * t; } private: Point3D origin_{0,0,0}; Vector3D direction_{1,0,0}; }; using Line3Dd = Line3D; using Segment3Dd = Segment3D; using Ray3Dd = Ray3D; } // namespace vde::core