Easy3D 2.5.3
line.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#ifndef EASY3D_CORE_LINE_H
28#define EASY3D_CORE_LINE_H
29
30#include <easy3d/core/vec.h>
31
32
33namespace easy3d {
34
35
38
39 template <int DIM, typename FT>
41 public:
42 typedef Vec<DIM, FT> Point;
43 typedef Vec<DIM, FT> Vector;
45
46 public:
48 static GenericLine from_point_and_direction(const Point& p, const Vector& dir) { return GenericLine(p, dir); }
50 static GenericLine from_two_points(const Point& p, const Point& q) { return GenericLine(p, q - p); }
51
53 GenericLine() = default;
54
56 void set(const Point& p, const Vector& dir) {
57 p_ = p;
58 dir_ = normalize(dir);
59 }
60
62 const Vector& direction() const { return dir_; }
63
65 const Point& point() const { return p_; }
66
68 Point projection(const Point &p) const { return p_ + dir_ * dot(p - p_, dir_); }
69
71 FT squared_distance(const Point &p) const { return length2(projection(p) - p); }
72
79 bool feet(const thisclass& other, Point& p1, Point& p2) const;
80
81 private: // Ambiguities exist for this one.
82 GenericLine(const Point & p, const Vector & dir);
83
84 private:
85 Point p_;
86 Vector dir_;
87 };
88
89
90 template <int DIM, typename FT> inline
91 GenericLine<DIM, FT>::GenericLine(const Point & p, const Vector & dir) : p_(p) {
92 dir_ = normalize(dir);
93 LOG_IF(length(dir_) < 1e-15, ERROR)
94 << "degenerate line constructed from point (" << p << ") and direction (" << dir << ")";
95 }
96
97
98 template <int DIM, typename FT> inline
99 bool GenericLine<DIM, FT>::feet(const thisclass& other, Point& p1, Point& p2) const {
100 // See the derivation: https://www.jianshu.com/p/34a7c4e1f3f5
101 FT a = dot(dir_, other.direction());
102 FT b = dot(dir_, dir_);
103 FT c = dot(other.direction(), other.direction());
104 if (std::abs(a * a - b * c) < epsilon<FT>()) // the two lines are colinear or parallel
105 return false;
106 FT d = dot(other.point() - p_, dir_);
107 FT e = dot(other.point() - p_, other.direction());
108 FT t1 = 0;
109 FT t2 = 0;
110 if (a == 0) {
111 t1 = d / b;
112 t2 = -e / c;
113 }
114 else {
115 t1 = (a * e - c * d) / (a * a - b * c);
116 t2 = b / a * t1 - d / a;
117 }
118 p1 = p_ + t1 * dir_;
119 p2 = other.point() + t2 * other.direction();
120 return true;
121 }
122
123
125 template <int DIM, typename FT> inline
126 std::ostream& operator<<(std::ostream& os, const GenericLine<DIM, FT>& line) {
127 return os << line.point() << " " << line.direction();
128 }
129
130
132 template <int DIM, typename FT> inline
133 std::istream& operator>>(std::istream& is, GenericLine<DIM, FT>& line) {
135 typename GenericLine<DIM, FT>::Vector dir;
136 is >> p >> dir;
137 line.set(p, dir);
138 return is;
139 }
140
141}
142
143#endif // EASY3D_CORE_LINE_H
144
A generic line representation, which supports both 2D and 3D lines.
Definition: line.h:40
GenericLine()=default
Default constructor.
FT squared_distance(const Point &p) const
Returns the squared distance of a point p to this line.
Definition: line.h:71
static GenericLine from_two_points(const Point &p, const Point &q)
Constructs a line from two points p and q.
Definition: line.h:50
void set(const Point &p, const Vector &dir)
Sets a line from a point p and its direction dir.
Definition: line.h:56
Point projection(const Point &p) const
Returns the projection of a point p on this line.
Definition: line.h:68
const Vector & direction() const
Returns the direction of a line.
Definition: line.h:62
const Point & point() const
Returns an arbitrary point on a line.
Definition: line.h:65
static GenericLine from_point_and_direction(const Point &p, const Vector &dir)
Constructs a line from a point p and its direction dir.
Definition: line.h:48
bool feet(const thisclass &other, Point &p1, Point &p2) const
Computes the perpendicular feet with another line.
Definition: line.h:99
Definition: collider.cpp:182
std::istream & operator>>(std::istream &is, GenericLine< DIM, FT > &line)
Definition: line.h:133
T length(const Vec< N, T > &v)
Computes the length/magnitude of a vector.
Definition: vec.h:289
std::ostream & operator<<(std::ostream &os, Graph::Vertex v)
Definition: graph.h:920
FT dot(const std::vector< FT > &, const std::vector< FT > &)
Inner product for vectors.
Definition: matrix.h:1803
Vec< N, T > normalize(const Vec< N, T > &v)
Computes and returns the normalized vector (Note: the input vector is not modified).
Definition: vec.h:299
T length2(const Vec< N, T > &v)
Computes the squared length/magnitude of a vector.
Definition: vec.h:293