16 std::vector<Point_t> result;
20 static std::vector<Point_t> min_plane_n;
21 static std::vector<Point_t> max_plane_n;
22 if (!min_plane_n.size()) {
23 min_plane_n.reserve(3);
24 min_plane_n.push_back(
Vector_t(-1, 0, 0));
25 min_plane_n.push_back(
Vector_t(0, -1, 0));
26 min_plane_n.push_back(
Vector_t(0, 0, -1));
27 max_plane_n.reserve(3);
28 max_plane_n.push_back(
Vector_t(1, 0, 0));
29 max_plane_n.push_back(
Vector_t(0, 1, 0));
30 max_plane_n.push_back(
Vector_t(0, 0, 1));
33 auto const& min_pt = box.
Min();
34 auto const& max_pt = box.
Max();
36 auto const& start = line.
Start();
40 for (
size_t i = 0; i < min_pt.size(); ++i) {
41 if (
dir[i] == 0 && (start[i] <= min_pt[i] || max_pt[i] <= start[i]))
return result;
44 for (
size_t i = 0; i < 3; ++i) {
45 auto const& normal = min_plane_n[i];
46 double s = (-1.) * (normal * (start - min_pt)) / (normal *
dir);
48 auto xs = start +
dir * s;
50 bool on_surface =
true;
51 for (
size_t sur_axis = 0; sur_axis < 3; ++sur_axis) {
52 if (sur_axis == i)
continue;
53 if (xs[sur_axis] < min_pt[sur_axis] || max_pt[sur_axis] < xs[sur_axis]) {
58 if (on_surface && xs != xs1) {
61 for (
size_t j = 0; j < 3; ++j)
65 for (
size_t j = 0; j < 3; ++j)
75 result.push_back(xs1);
76 result.push_back(xs2);
80 for (
size_t i = 0; i < 3; ++i) {
81 auto const& normal = max_plane_n[i];
82 double s = (-1.) * (normal * (start - max_pt)) / (normal *
dir);
84 auto xs = start +
dir * s;
85 bool on_surface =
true;
86 for (
size_t sur_axis = 0; sur_axis < 3; ++sur_axis) {
87 if (sur_axis == i)
continue;
88 if (xs[sur_axis] < min_pt[sur_axis] || max_pt[sur_axis] < xs[sur_axis]) {
93 if (on_surface && xs != xs1) {
95 for (
size_t j = 0; j < 3; ++j)
98 for (
size_t j = 0; j < 3; ++j)
104 if (!xs1.
IsValid())
return result;
108 result.push_back(xs1);
109 result.push_back(xs2);
112 result.push_back(xs1);
119 auto const& st = line.
Start();
120 auto const& ed = line.
End();
123 hline.
Start(st[0], st[1], st[2]);
124 hline.
Dir(ed[0] - st[0], ed[1] - st[1], ed[2] - st[2]);
128 if (!hline_result.size())
return hline_result;
131 std::vector<Point_t> result;
132 auto length = st._SqDist_(ed);
133 for (
auto const&
pt : hline_result)
134 if (st._SqDist_(
pt) < length) result.push_back(
pt);
142 std::vector<Point_t> result;
143 if (trj.size() < 2)
return result;
148 for (
size_t i = 0; i < trj.size() - 1; ++i) {
150 auto const& st = trj[i];
151 auto const& ed = trj[i + 1];
152 hline.
Start(st[0], st[1], st[2]);
153 hline.
Dir(ed[0] - st[0], ed[1] - st[1], ed[2] - st[2]);
157 if (!hline_result.size())
continue;
160 auto length = st._SqDist_(ed);
161 for (
auto const&
pt : hline_result)
162 if (st._SqDist_(
pt) < length) result.push_back(
pt);
172 if (xs_v.size() == 2)
return LineSegment_t(xs_v[0], xs_v[1]);
216 double d = a * e - b * b;
227 double s = (b * f - c *
e) / d;
228 double t = (a * f - b * c) / d;
234 L1 = l1.
Pt1() + (l1.
Pt2() - l1.
Pt1()) * s;
235 L2 = l2.
Pt1() + (l2.
Pt2() - l2.
Pt1()) * t;
267 double d = a * e - b * b;
280 double s = (b * f - c *
e) / d;
281 double t = (a * f - b * c) / d;
314 auto const d1 = hline.
Dir();
315 auto const d2 = seg.
End() - seg.
Start();
324 double d = a * e - b * b;
333 if (sDist <= eDist) {
346 double s = (b * f - c *
e) / d;
361 double t = (a * f - b * c) / d;
363 if ((t < 1) and (t > 0)) {
364 L1 = hline.
Start() + hline.
Dir() * s;
379 auto const ab = line_e - line_s;
380 auto const ac = pt - line_s;
381 auto const bc = pt - line_e;
383 if (
e <= 0.)
return ac.SqLength();
384 auto f = ab.SqLength();
385 if (
e >=
f)
return bc.SqLength();
386 return (ac.SqLength() -
e *
e /
f);
393 auto const& ab = line.
Dir();
395 auto t = ((pt - line.
Start()) * ab);
402 if (t >= denom)
return line.
End();
405 return (line.
Start() + ab * (t / denom));
412 auto const& ab = line.
Dir();
413 auto const ac = pt - line.
Start();
414 auto const bc = ac - ab;
417 if (
e <= 0.)
return (ac * ac);
418 auto f = ab.SqLength();
419 return (ac.SqLength() -
e *
e /
f);
425 auto const& ab = line.
Dir();
426 auto t = (pt - line.
Start()) * ab;
431 return (line.
Start() + ab * (t / denom));
438 auto const ab = line.
Pt2() - line.
Pt1();
439 auto const ac = pt - line.
Pt1();
440 auto const bc = ac - ab;
443 auto f = ab.SqLength();
444 return (ac.SqLength() -
e *
e /
f);
450 auto const& ab = line.
Pt2() - line.
Pt1();
451 auto t = (pt - line.
Pt1()) * ab;
453 return (line.
Pt1() + ab * (t / denom));
464 auto const& pt_min = box.
Min();
465 auto const& pt_max = box.
Max();
467 double dist_to_yz = pt[0] - pt_min[0];
468 if (dist_to_yz > (pt_max[0] - pt[0])) dist_to_yz = pt_max[0] - pt[0];
471 double dist_to_zx = pt[1] - pt_min[1];
472 if (dist_to_zx > (pt_max[1] - pt[1])) dist_to_zx = pt_max[1] - pt[1];
475 double dist_to_xy = pt[2] - pt_min[2];
476 if (dist_to_xy > (pt_max[2] - pt[2])) dist_to_xy = pt_max[2] - pt[2];
479 dist = (dist_to_yz < dist_to_zx ? dist_to_yz : dist_to_zx);
480 dist = (dist < dist_to_xy ? dist : dist_to_xy);
488 for (
size_t i = 0; i < pt.size(); ++i) {
490 auto const& v_pt = pt[i];
491 auto const& v_max = box.
Max()[i];
492 auto const& v_min = box.
Min()[i];
494 if (v_pt < v_min) dist += (v_min - v_pt) * (v_min - v_pt);
495 if (v_pt > v_max) dist += (v_pt - v_max) * (v_pt - v_max);
508 for (
size_t i = 0; i < pt.size(); ++i) {
509 auto const& v_pt = pt[i];
510 auto const& v_min = box.
Min()[i];
511 auto const& v_max = box.
Max()[i];
513 if (v_pt < v_min) res[i] = v_min;
514 if (v_pt > v_max) res[i] = v_max;
527 if (!trj.size())
throw GeoAlgoException(
"Trajectory object not properly set...");
534 for (
size_t l = 0; l < trj.size() - 1; l++) {
535 double distTmp =
_SqDist_(pt, trj[l], trj[l + 1]);
536 if (distTmp < distMin) { distMin = distTmp; }
546 const std::vector<Trajectory_t>& trj,
554 for (
size_t t = 0; t < trj.size(); t++) {
558 double tmpDist =
SqDist(pt, trj[t]);
559 if (tmpDist < minDist) {
576 if (!trj.size())
throw GeoAlgoException(
"Trajectory object not properly set...");
584 for (
size_t l = 0; l < trj.size() - 1; l++) {
585 double distTmp =
_SqDist_(pt, trj[l], trj[l + 1]);
586 if (distTmp < distMin) {
603 const std::vector<Trajectory_t>& trj,
611 for (
size_t t = 0; t < trj.size(); t++) {
618 double tmpDist =
SqDist(pt, trj[t]);
619 if (tmpDist < minDist) {
640 if (!trj.size())
throw GeoAlgoException(
"Trajectory object not properly set...");
651 for (
size_t l = 0; l < trj.size() - 1; l++) {
653 double distTmp =
_SqDist_(segTmp, seg, c1min, c2min);
654 if (distTmp < distMin) {
674 if (!trj1.size() or !trj2.size())
686 for (
size_t l1 = 0; l1 < trj1.size() - 1; l1++) {
687 for (
size_t l2 = 0; l2 < trj2.size() - 1; l2++) {
690 double distTmp =
_SqDist_(segTmp1, segTmp2, c1min, c2min);
691 if (distTmp < distMin) {
712 if (!trj.size())
throw GeoAlgoException(
"Trajectory object not properly set...");
723 for (
size_t l = 0; l < trj.size() - 1; l++) {
725 double distTmp =
_SqDist_(hline, segTmp, c1min, c2min);
726 if (distTmp < distMin) {
741 const std::vector<Trajectory_t>& trj,
753 for (
size_t t = 0; t < trj.size(); t++) {
760 double tmpDist =
SqDist(seg, trj[t], c1min, c2min);
763 if (tmpDist < minDist) {
784 auto const& s1 = seg1.
Start();
785 auto const& s2 = seg2.
Start();
786 auto const& e1 = seg1.
End();
787 auto const& e2 = seg2.
End();
793 double a = d1.SqLength();
794 double e = d2.SqLength();
798 if ((a <= 0) and (e <= 0)) {
822 double denom = (a *
e) - (b * b);
825 t1 =
_Clamp_((b * f - c * e) / denom, 0., 1.);
829 t2 = (b * t1 +
f) / e;
837 t1 =
_Clamp_((b - c) / a, 0., 1.);
854 if (n < min) {
return min; }
855 if (n > max) {
return max; }
893 origin = (
pt1 +
pt2) / 2.;
905 return vec1.
Dot(dir1) + vec2.
Dot(dir2);
912 bool backwards)
const 949 origin = (
pt1 +
pt2) / 2.;
961 return vec1.Dot(lin1.
Dir()) + vec2.Dot(lin2.
Dir());
972 bool backwards)
const 984 bool backwards)
const 998 bool backwards)
const 1001 HalfLine_t lin1(trj1.front(), trj1.back() - trj1.front());
1003 HalfLine_t lin2(trj2.front(), trj2.back() - trj2.front());
1011 bool backwards)
const 1014 HalfLine_t lin1(trj.front(), trj.back() - trj.front());
1024 bool backwards)
const 1027 HalfLine_t lin2(trj.front(), trj.back() - trj.front());
1037 std::vector<Point_t> copyPts = {pts[0]};
1038 for (
size_t p1 = 0; p1 < pts.size(); p1++) {
1041 for (
size_t p2 = 0; p2 < copyPts.size(); p2++)
1042 if (pts[p1] == copyPts[p2]) {
1046 if (!found) copyPts.push_back(pts[p1]);
1050 if (copyPts.size() < 5)
return Sphere_t(copyPts);
1052 size_t npoints = copyPts.size();
1053 std::vector<Point_t> points4 = {
1054 copyPts[npoints - 1], copyPts[npoints - 2], copyPts[npoints - 3], copyPts[npoints - 4]};
1075 if (remaining.size() == 0)
return thisSphere;
1079 auto const& lastPoint = remaining.back();
1082 if (thisSphere.
Contain(lastPoint)) {
1083 remaining.pop_back();
1088 double dist = lastPoint.Dist(thisSphere.
Center());
1100 double shift = (dist - thisSphere.
Radius()) / 2.;
1101 if (shift < 0) { shift *= -1; }
1103 double newRadius = thisSphere.
Radius() + shift;
1106 Sphere_t newsphere(newCenter, newRadius);
1109 remaining.pop_back();
1116 std::vector<Point_t> sosPts)
const 1119 if (numPts == 0)
return Sphere_t(sosPts);
1121 int index = numPts - 1;
1125 if (smallestSphere.
Contain(pts[index]))
return smallestSphere;
1127 sosPts.push_back(pts[index]);
bool Contain(const Point_t &p) const
Judge if a point is contained within a sphere.
Point_t ClosestPt(const Line_t &line, const Point_t &pt) const
double _SqDist_(const Line_t &l1, const Line_t &l2, Point_t &L1, Point_t &L2) const
Line & Line distance w/o dimensionality check.
const Point_t & Start() const
Start getter.
double _Clamp_(const double n, const double min, const double max) const
Clamp function: checks if value out of bounds.
void compat(const Point_t &obj) const
Dimensionality check function w/ Trajectory.
double SqDist(const Line_t &line, const Point_t &pt) const
Class def header for a class GeoAlgoException.
Representation of a simple 3D line segment Defines a finite 3D straight line by having the start and ...
Representation of a 3D rectangular box which sides are aligned w/ coordinate axis. A representation of an Axis-Aligned-Boundary-Box, a simple & popular representation of 3D boundary box for collision detection. The concept was taken from the reference, Real-Time-Collision-Detection (RTCD), and in particular Ch. 4.2 (page 77): .
double _SqDist_(const Vector &obj) const
Compute the squared-distance to another vector w/o dimension check.
const Point_t & Pt2() const
Direction getter.
const Vector_t Dir() const
Direction getter.
const Point_t & Min() const
Minimum point getter.
void Normalize()
Normalize itself.
double SqLength() const
Compute the squared length of the vector.
double Length() const
Compute the length of the vector.
LineSegment LineSegment_t
double Dot(const Vector &obj) const
bool Contain(const Point_t &pt) const
Test if a point is contained within the box.
static const double kMAX_DOUBLE
bool IsValid() const
Check if point is valid.
const Point_t & Pt1() const
Start getter.
const Point_t & End() const
End getter.
Representation of a 3D infinite line. Defines an infinite 3D line by having 2 points which completely...
double Radius() const
Radius getter.
Sphere_t _WelzlSphere_(const std::vector< Point_t > &pts, int numPts, std::vector< Point_t > sosPts) const
const Vector_t & Dir() const
Direction getter.
const Point_t & Center() const
Center getter.
const Point_t & Start() const
Start getter.
Sphere_t _boundingSphere_(const std::vector< Point_t > &pts) const
Representation of a 3D semi-infinite line. Defines a semi-infinite 3D line by having a start point (P...
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Sphere_t _RemainingPoints_(std::vector< Point_t > &remaining, const Sphere_t &thisSphere) const
Class def header for a class GeoAlgo.
const Point_t & Max() const
Maximum point getter.
Vector Vector_t
Point has same feature as Vector.
LineSegment_t BoxOverlap(const AABox_t &box, const HalfLine_t &line) const
LineSegment sub-segment of HalfLine inside an AABox.
static const double kINVALID_DOUBLE
std::vector< Point_t > Intersection(const AABox_t &box, const HalfLine_t &line, bool back=false) const
Intersection between a HalfLine and an AABox.
double _commonOrigin_(const Line_t &lin1, const Line_t &lin2, Point_t &origin) const
Common origin: Line & Line. Keep track of origin.
constexpr Point origin()
Returns a origin position with a point of the specified type.
Point_t _ClosestPt_(const Point_t &pt, const LineSegment_t &line) const