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();
36 auto dir = line.Dir();
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];
72 if(xs1._SqDist_(start) > xs2._SqDist_(start)) std::swap(xs1,xs2);
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;
102 if(xs1._SqDist_(start) > xs2._SqDist_(start)) std::swap(xs1,xs2);
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;
142 trj.compat(box.Min());
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);
184 if ( box.Contain(trj[0])
and box.Contain(trj.back()) )
226 double s = (b*f-c*
e)/d;
227 double t = (a*f-b*c)/d;
233 L1 = l1.Pt1() + ( l1.Pt2()-l1.Pt1() )*s;
234 L2 = l2.Pt1() + ( l2.Pt2()-l2.Pt1() )*t;
237 double dist = L1._SqDist_(L2);
274 return L1._SqDist_(L2);
277 double s = (b*f-c*
e)/d;
278 double t = (a*f-b*c)/d;
288 L1 = l1.Start() + l1.Dir()*
s;
289 L2 = l2.Start() + l2.Dir()*t;
292 double dist = L1._SqDist_(L2);
310 auto const d1 = hline.Dir();
311 auto const d2 = seg.End()-seg.Start();
312 auto const r = hline.Start()-seg.Start();
327 double sDist =
_SqDist_(seg.Start(),hline);
328 double eDist =
_SqDist_(seg.End(),hline);
329 if ( sDist <= eDist ) {
342 double s = (b*f-c*
e)/d;
351 return L1._SqDist_(L2);
358 double t = (a*f-b*c)/d;
360 if ( (t < 1)
and (t > 0) ){
361 L1 = hline.Start() + hline.Dir()*
s;
362 L2 = seg.Start() + (seg.End()-seg.Start())*t;
363 return L1._SqDist_(L2);
368 L2 = seg.Start() + (seg.End()-seg.Start())*t;
370 return L1._SqDist_(L2);
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));
458 if(box.Contain(pt)) {
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;
527 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; }
554 for (
size_t t=0; t < trj.size(); t++){
558 double tmpDist =
SqDist(pt, trj[t]);
559 if (tmpDist < minDist){
579 throw GeoAlgoException(
"Trajectory object not properly set...");
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){
638 throw GeoAlgoException(
"Trajectory object not properly set...");
641 trj.compat(seg.Start());
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() )
671 throw GeoAlgoException(
"Trajectory object not properly set...");
674 trj1.compat(trj2[0]);
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 ){
706 throw GeoAlgoException(
"Trajectory object not properly set...");
709 trj.compat(hline.Start());
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();
782 double a = d1.SqLength();
783 double e = d2.SqLength();
787 if ( (a <= 0)
and (e <= 0) ){
793 return distVector.SqLength();
811 double denom = (a*
e)-(b*b);
814 t1 =
_Clamp_((b*f-c*e)/denom, 0., 1.);
836 return distVector.SqLength();
844 double GeoAlgo::_Clamp_(
const double n,
const double min,
const double max)
const
846 if (n < min) {
return min; }
847 if (n > max) {
return max; }
876 Vector_t dir1(lin1.Pt2()-lin1.Pt1());
877 Vector_t dir2(lin2.Pt2()-lin2.Pt1());
882 Point_t pt1(lin1.Pt1().size());
883 Point_t pt2(lin2.Pt1().size());
886 origin = (pt1+pt2)/2.;
900 return vec1.Dot(dir1) + vec2.Dot(dir2);
910 Line_t l1(lin1.Start(),lin1.Start()+lin1.Dir());
911 Line_t l2(lin2.Start(),lin2.Start()+lin2.Dir());
935 HalfLine_t lin1Back(lin1.Start(), lin1.Dir()*(-1));
936 HalfLine_t lin2Back(lin2.Start(), lin2.Dir()*(-1));
938 Point_t pt1(lin1.Start().size());
939 Point_t pt2(lin2.Start().size());
942 origin = (pt1+pt2)/2.;
947 if (lin1.Start() !=
origin)
948 vec1 = lin1.Start()-
origin;
952 if (lin2.Start() !=
origin)
953 vec2 = lin2.Start()-
origin;
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]};
1038 Sphere_t tmpSphere = Sphere(points4);
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]);
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.
double _Clamp_(const double n, const double min, const double max) const
Clamp function: checks if value out of bounds.
double SqDist(const Line_t &line, const Point_t &pt) const
void compat(const Vector &obj) const
Dimensional check for a compatibility.
double _SqDist_(const Vector &obj) const
Compute the squared-distance to another vector w/o dimension check.
recob::tracking::Point_t Point_t
double SqLength() const
Compute the squared length of the vector.
double Length() const
Compute the length of the vector.
LineSegment LineSegment_t
static const double kMAX_DOUBLE
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
Sphere_t _WelzlSphere_(const std::vector< Point_t > &pts, int numPts, std::vector< Point_t > sosPts) const
Sphere_t _boundingSphere_(const std::vector< Point_t > &pts) const
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
then echo File list $list not found else cat $list while read file do echo $file sed s
Vector Dir() const
Return a direction unit vector.
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.
recob::tracking::Vector_t Vector_t
physics associatedGroupsWithLeft p1
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