17 #ifndef GZ_MATH_LINE3_HH_
18 #define GZ_MATH_LINE3_HH_
22 #include <gz/math/config.hh>
27 inline namespace GZ_MATH_VERSION_NAMESPACE {
47 this->Set(_ptA, _ptB);
55 public:
Line3(
const double _x1,
const double _y1,
56 const double _x2,
const double _y2)
58 this->Set(_x1, _y1, _x2, _y2);
68 public:
Line3(
const double _x1,
const double _y1,
69 const double _z1,
const double _x2,
70 const double _y2,
const double _z2)
72 this->Set(_x1, _y1, _z1, _x2, _y2, _z2);
107 public:
void Set(
const double _x1,
const double _y1,
108 const double _x2,
const double _y2,
112 static_cast<T
>(_x1),
static_cast<T
>(_y1),
static_cast<T
>(_z));
114 static_cast<T
>(_x2),
static_cast<T
>(_y2),
static_cast<T
>(_z));
124 public:
void Set(
const double _x1,
const double _y1,
125 const double _z1,
const double _x2,
126 const double _y2,
const double _z2)
129 static_cast<T
>(_x1),
static_cast<T
>(_y1),
static_cast<T
>(_z1));
131 static_cast<T
>(_x2),
static_cast<T
>(_y2),
static_cast<T
>(_z2));
138 return (this->pts[1] - this->pts[0]).Normalize();
145 return static_cast<T
>(this->pts[0].Distance(this->pts[1]));
159 const double _epsilon = 1e-6)
const
164 if (std::abs(p43.
X()) < _epsilon && std::abs(p43.
Y()) < _epsilon &&
165 std::abs(p43.
Z()) < _epsilon)
172 if (std::abs(p21.
X()) < _epsilon && std::abs(p21.
Y()) < _epsilon &&
173 std::abs(p21.
Z()) < _epsilon)
178 double d1343 = p13.
Dot(p43);
179 double d4321 = p43.
Dot(p21);
180 double d1321 = p13.
Dot(p21);
181 double d4343 = p43.
Dot(p43);
182 double d2121 = p21.
Dot(p21);
184 double denom = d2121 * d4343 - d4321 * d4321;
188 if (std::abs(denom) < _epsilon)
190 double d1 = this->pts[0].Distance(_line[0]);
191 double d2 = this->pts[0].Distance(_line[1]);
193 double d3 = this->pts[1].Distance(_line[0]);
194 double d4 = this->pts[1].Distance(_line[1]);
196 if (d1 <= d2 && d1 <= d3 && d1 <= d4)
198 _result.
SetA(this->pts[0]);
199 _result.
SetB(_line[0]);
201 else if (d2 <= d3 && d2 <= d4)
203 _result.
SetA(this->pts[0]);
204 _result.
SetB(_line[1]);
208 _result.
SetA(this->pts[1]);
209 _result.
SetB(_line[0]);
213 _result.
SetA(this->pts[1]);
214 _result.
SetB(_line[1]);
220 double numer = d1343 * d4321 - d1321 * d4343;
222 double mua =
clamp(numer / denom, 0.0, 1.0);
223 double mub =
clamp((d1343 + d4321 * mua) / d4343, 0.0, 1.0);
225 _result.
Set(this->pts[0] + (p21 *
static_cast<T
>(mua)),
226 _line[0] + (p43 *
static_cast<T
>(mub)));
236 auto line = this->pts[1] - this->pts[0];
237 auto ptTo0 = _pt - this->pts[0];
238 auto ptTo1 = _pt - this->pts[1];
241 if (ptTo0.Dot(line) <=
static_cast<T
>(0))
247 if (ptTo1.Dot(line) >=
static_cast<T
>(0))
249 return ptTo1.Length();
255 auto d = ptTo0.Cross(line);
256 auto lineLength = line.Length();
257 assert(lineLength > 0);
258 return d.Length() / lineLength;
267 double _epsilon = 1e-6)
const
270 return this->Intersect(_line, ignore, _epsilon);
279 const double _epsilon = 1e-6)
const
281 return std::abs((_line[0] - this->pts[0]).Dot(
282 (this->pts[1] - this->pts[0]).Cross(_line[1] - _line[0])))
292 const double _epsilon = 1e-6)
const
294 return (this->pts[1] - this->pts[0]).Cross(
295 _line[1] - _line[0]).Length() <= _epsilon;
307 double _epsilon = 1e-6)
const
310 if (this->Parallel(_line, _epsilon))
313 if (this->Within(_line[0], _epsilon))
319 else if (this->Within(_line[1], _epsilon))
331 this->Distance(_line, distLine, _epsilon);
335 if (distLine.
Length() < _epsilon)
351 double _epsilon = 1e-6)
const
353 auto eps =
static_cast<T
>(_epsilon);
354 return _pt.
X() <=
std::max(this->pts[0].X(),
355 this->pts[1].X()) + eps &&
357 this->pts[1].X()) - eps &&
359 this->pts[1].Y()) + eps &&
361 this->pts[1].Y()) - eps &&
363 this->pts[1].Z()) + eps &&
365 this->pts[1].Z()) - eps;
373 return this->pts[0] == _line[0] && this->pts[1] == _line[1];
381 return !(*
this == _line);
399 _out << _line[0] <<
" " << _line[1];