1 #ifndef BASICTOOL_GEOALGO_CXX 2 #define BASICTOOL_GEOALGO_CXX 15 std::vector<Point_t> result;
19 static std::vector<Point_t> min_plane_n;
20 static std::vector<Point_t> max_plane_n;
21 if(!min_plane_n.size()) {
22 min_plane_n.reserve(3);
23 min_plane_n.push_back(
Vector_t(-1,0,0));
24 min_plane_n.push_back(
Vector_t(0,-1,0));
25 min_plane_n.push_back(
Vector_t(0,0,-1));
26 max_plane_n.reserve(3);
27 max_plane_n.push_back(
Vector_t(1,0,0));
28 max_plane_n.push_back(
Vector_t(0,1,0));
29 max_plane_n.push_back(
Vector_t(0,0,1));
32 auto const& min_pt = box.
Min();
33 auto const& max_pt = box.
Max();
35 auto const& start = line.
Start();
39 for(
size_t i=0; i<min_pt.size(); ++i) {
41 (start[i] <= min_pt[i] || max_pt[i] <= start[i]) )
45 for(
size_t i=0; i<3; ++i) {
46 auto const& normal = min_plane_n[i];
47 double s = (-1.) * ( normal * (start - min_pt) ) / (normal *
dir);
49 auto xs = start +
dir *
s;
52 for(
size_t sur_axis=0; sur_axis<3; ++sur_axis) {
53 if(sur_axis==i)
continue;
54 if(xs[sur_axis] < min_pt[sur_axis] || max_pt[sur_axis] < xs[sur_axis]) {
59 if(on_surface && xs != xs1) {
61 if(!(xs1.
IsValid()))
for(
size_t j=0; j<3; ++j) xs1[j]=xs[j];
64 for(
size_t j=0; j<3; ++j) xs2[j]=xs[j];
73 result.push_back(xs1);
74 result.push_back(xs2);
78 for(
size_t i=0; i<3; ++i) {
79 auto const& normal = max_plane_n[i];
80 double s = (-1.) * ( normal * (start - max_pt) ) / (normal *
dir);
82 auto xs = start +
dir *
s;
84 for(
size_t sur_axis=0; sur_axis<3; ++sur_axis) {
85 if(sur_axis==i)
continue;
86 if(xs[sur_axis] < min_pt[sur_axis] || max_pt[sur_axis] < xs[sur_axis]) {
91 if(on_surface && xs != xs1) {
92 if(!(xs1.
IsValid()))
for(
size_t j=0; j<3; ++j) xs1[j]=xs[j];
94 for(
size_t j=0; j<3; ++j) xs2[j]=xs[j];
99 if(!xs1.
IsValid())
return result;
103 result.push_back(xs1);
104 result.push_back(xs2);
107 result.push_back(xs1);
115 auto const& st = line.
Start();
116 auto const& ed = line.
End();
119 hline.
Start(st[0],st[1],st[2]);
120 hline.
Dir(ed[0]-st[0],ed[1]-st[1],ed[2]-st[2]);
124 if(!hline_result.size())
return hline_result;
127 std::vector<Point_t> result;
128 auto length = st._SqDist_(ed);
129 for(
auto const&
pt : hline_result)
130 if(st._SqDist_(
pt) < length) result.push_back(
pt);
139 std::vector<Point_t> result;
140 if(trj.size() < 2)
return result;
145 for(
size_t i=0; i<trj.size()-1; ++i) {
147 auto const& st = trj[i];
148 auto const& ed = trj[i+1];
149 hline.
Start(st[0],st[1],st[2]);
150 hline.
Dir(ed[0]-st[0],ed[1]-st[1],ed[2]-st[2]);
154 if(!hline_result.size())
continue;
157 auto length = st._SqDist_(ed);
158 for(
auto const&
pt : hline_result)
159 if(st._SqDist_(
pt) < length) result.push_back(
pt);
226 double s = (b*f-c*
e)/d;
227 double t = (a*f-b*c)/d;
277 double s = (b*f-c*
e)/d;
278 double t = (a*f-b*c)/d;
310 auto const d1 = hline.
Dir();
311 auto const d2 = seg.
End()-seg.
Start();
329 if ( sDist <= eDist ) {
342 double s = (b*f-c*
e)/d;
358 double t = (a*f-b*c)/d;
360 if ( (t < 1) and (t > 0) ){
376 auto const ab = line_e - line_s;
377 auto const ac = pt - line_s;
378 auto const bc = pt - line_e;
380 if(
e <= 0. )
return ac.SqLength();
381 auto f = ab.SqLength();
382 if(
e >=
f )
return bc.SqLength();
383 return (ac.SqLength() -
e *
e /
f);
390 auto const& ab = line.
Dir();
392 auto t = ((pt - line.
Start()) * ab);
394 if( t <= 0. )
return line.
Start();
398 if( t>= denom )
return line.
End();
400 else return (line.
Start() + ab * (t/denom));
407 auto const& ab = line.
Dir();
408 auto const ac = pt - line.
Start();
409 auto const bc = ac - ab;
412 if(
e <= 0. )
return (ac * ac);
413 auto f = ab.SqLength();
414 return (ac.SqLength() -
e *
e /
f);
421 auto const& ab = line.
Dir();
422 auto t = (pt - line.
Start()) * ab;
423 if( t <= 0. )
return line.
Start();
426 return (line.
Start() + ab * (t/denom));
433 auto const ab = line.
Pt2()-line.
Pt1();
434 auto const ac = pt - line.
Pt1();
435 auto const bc = ac - ab;
438 auto f = ab.SqLength();
439 return (ac.SqLength() -
e *
e /
f);
445 auto const& ab = line.
Pt2()-line.
Pt1();
446 auto t = (pt - line.
Pt1()) * ab;
448 return (line.
Pt1() + ab * (t/denom));
460 auto const& pt_min = box.
Min();
461 auto const& pt_max = box.
Max();
463 double dist_to_yz = pt[0] - pt_min[0];
464 if( dist_to_yz > (pt_max[0] - pt[0]) ) dist_to_yz = pt_max[0] - pt[0];
467 double dist_to_zx = pt[1] - pt_min[1];
468 if( dist_to_zx > (pt_max[1] - pt[1]) ) dist_to_zx = pt_max[1] - pt[1];
471 double dist_to_xy = pt[2] - pt_min[2];
472 if( dist_to_xy > (pt_max[2] - pt[2]) ) dist_to_xy = pt_max[2] - pt[2];
475 dist = ( dist_to_yz < dist_to_zx ? dist_to_yz : dist_to_zx );
476 dist = ( dist < dist_to_xy ? dist : dist_to_xy );
485 for(
size_t i=0; i<pt.size(); ++i) {
487 auto const& v_pt = pt[i];
488 auto const& v_max = box.
Max()[i];
489 auto const& v_min = box.
Min()[i];
491 if(v_pt < v_min) dist += (v_min - v_pt) * (v_min - v_pt);
492 if(v_pt > v_max) dist += (v_pt - v_max) * (v_pt - v_max);
505 for(
size_t i=0; i<pt.size(); ++i) {
506 auto const& v_pt = pt[i];
507 auto const& v_min = box.
Min()[i];
508 auto const& v_max = box.
Max()[i];
510 if( v_pt < v_min ) res[i] = v_min;
511 if( v_pt > v_max ) res[i] = v_max;
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; }
554 for (
size_t t=0; t < trj.size(); t++){
558 double tmpDist =
SqDist(pt, trj[t]);
559 if (tmpDist < minDist){
587 for (
size_t l=0; l < trj.size()-1; l++){
588 double distTmp =
_SqDist_(pt,trj[l],trj[l+1]);
589 if (distTmp < distMin) { distMin = distTmp; idx = l; }
610 for (
size_t t=0; t < trj.size(); t++){
617 double tmpDist =
SqDist(pt, trj[t]);
618 if (tmpDist < minDist){
649 for (
size_t l=0; l < trj.size()-1; l++){
651 double distTmp =
_SqDist_(segTmp, seg, c1min, c2min);
652 if ( distTmp < distMin ){
670 if ( !trj1.size() or !trj2.size() )
682 for (
size_t l1=0; l1 < trj1.size()-1; l1++){
683 for (
size_t l2=0; l2 < trj2.size()-1; l2++){
686 double distTmp =
_SqDist_(segTmp1, segTmp2, c1min, c2min);
687 if ( distTmp < distMin ){
717 for (
size_t l=0; l < trj.size()-1; l++){
719 double distTmp =
_SqDist_(hline, segTmp, c1min, c2min);
720 if ( distTmp < distMin ){
744 for (
size_t t=0; t < trj.size(); t++){
751 double tmpDist =
SqDist(seg, trj[t], c1min, c2min);
754 if (tmpDist < minDist){
773 auto const& s1 = seg1.
Start();
774 auto const& s2 = seg2.
Start();
775 auto const& e1 = seg1.
End();
776 auto const& e2 = seg2.
End();
783 double e = d2.SqLength();
787 if ( (a <= 0) and (e <= 0) ){
811 double denom = (a*
e)-(b*b);
814 t1 =
_Clamp_((b*f-c*e)/denom, 0., 1.);
846 if (n < min) {
return min; }
847 if (n > max) {
return max; }
886 origin = (pt1+pt2)/2.;
900 return vec1.
Dot(dir1) + vec2.
Dot(dir2);
942 origin = (pt1+pt2)/2.;
956 return vec1.Dot(lin1.
Dir()) + vec2.Dot(lin2.
Dir());
987 HalfLine_t lin1(trj1.front(),trj1.back()-trj1.front());
989 HalfLine_t lin2(trj2.front(),trj2.back()-trj2.front());
997 HalfLine_t lin1(trj.front(),trj.back()-trj.front());
1007 HalfLine_t lin2(trj.front(),trj.back()-trj.front());
1018 std::vector<Point_t> copyPts = {pts[0]};
1019 for(
size_t p1=0; p1 < pts.size(); p1++){
1022 for (
size_t p2 =0; p2 < copyPts.size(); p2++)
1023 if (pts[p1] == copyPts[p2]) { found =
true;
break; }
1025 copyPts.push_back(pts[p1]);
1029 if (copyPts.size() < 5)
1032 size_t npoints = copyPts.size();
1033 std::vector<Point_t> points4 = {copyPts[npoints-1],copyPts[npoints-2],copyPts[npoints-3],copyPts[npoints-4]};
1055 if (remaining.size() == 0)
1060 auto const& lastPoint = remaining.back();
1063 if ( thisSphere.
Contain(lastPoint) ){
1064 remaining.pop_back();
1069 double dist = lastPoint.Dist(thisSphere.
Center());
1081 double shift = (dist-thisSphere.
Radius())/2.;
1082 if (shift < 0) { shift *= -1; }
1084 double newRadius = thisSphere.
Radius()+shift;
1087 Sphere_t newsphere(newCenter,newRadius);
1090 remaining.pop_back();
1097 std::vector<Point_t> sosPts)
const 1103 int index = numPts-1;
1107 if ( smallestSphere.
Contain(pts[index]) )
1108 return smallestSphere;
1110 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
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...
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