/* * searchTree implementation * * Copyright (C) Jan Elseberg, Andreas Nuechter * * Released under the GPL version 3. * */ /** * @file * @brief Representation of a general search trees * @author Jan Elseberg. Jacobs University Bremen gGmbH, Germany * @author Andreas Nuechter. Jacobs University Bremen gGmbH, Germany */ #include "slam6d/searchTree.h" #include "slam6d/scan.h" #include "slam6d/globals.icc" #include double *SearchTree::FindClosestAlongDir(double *_p, double *_dir, double maxdist2, int threadNum) const { throw std::runtime_error("Method FindClosestAlongDir is not implemented"); } void SearchTree::getPtPairs(vector *pairs, double *source_alignxf, // source double * const *q_points, unsigned int startindex, unsigned int endindex, // target int thread_num, int rnd, double max_dist_match2, double &sum, double *centroid_m, double *centroid_d) { // prepare this tree for resource access in FindClosest lock(); double local_alignxf_inv[16]; M4inv(source_alignxf, local_alignxf_inv); // t is the original point from target, s is the (inverted) query point from target and then // the closest point in source double t[3], s[3]; for (unsigned int i = startindex; i < endindex; i++) { if (rnd > 1 && rand(rnd) != 0) continue; // take about 1/rnd-th of the numbers only t[0] = q_points[i][0]; t[1] = q_points[i][1]; t[2] = q_points[i][2]; transform3(local_alignxf_inv, t, s); double *closest = this->FindClosest(s, max_dist_match2, thread_num); if (closest) { transform3(source_alignxf, closest, s); // This should be right, model=Source=First=not moving centroid_m[0] += s[0]; centroid_m[1] += s[1]; centroid_m[2] += s[2]; centroid_d[0] += t[0]; centroid_d[1] += t[1]; centroid_d[2] += t[2]; PtPair myPair(s, t); double p12[3] = { myPair.p1.x - myPair.p2.x, myPair.p1.y - myPair.p2.y, myPair.p1.z - myPair.p2.z }; sum += Len2(p12); pairs->push_back(myPair); /*cout << "PTPAIR" << i << " " << p[0] << " " << p[1] << " " << p[2] << " - " << q_points[i][0] << " " << q_points[i][1] << " " << q_points[i][2] << " " << Len2(p12) << endl; */ } } // release resource access lock unlock(); return; } void SearchTree::getPtPairs(vector *pairs, double *source_alignxf, // source const DataXYZ& xyz_r, const DataNormal& normal_r, unsigned int startindex, unsigned int endindex, // target int thread_num, int rnd, double max_dist_match2, double &sum, double *centroid_m, double *centroid_d, PairingMode pairing_mode) { // prepare this tree for resource access in FindClosest lock(); double local_alignxf_inv[16]; M4inv(source_alignxf, local_alignxf_inv); // t is the original point from target, s is the (inverted) query point from target and then // the closest point in source double t[3], s[3], normal[3]; for (unsigned int i = startindex; i < endindex; i++) { if (rnd > 1 && rand(rnd) != 0) continue; // take about 1/rnd-th of the numbers only t[0] = xyz_r[i][0]; t[1] = xyz_r[i][1]; t[2] = xyz_r[i][2]; transform3(local_alignxf_inv, t, s); double *closest; if (pairing_mode != CLOSEST_POINT) { normal[0] = normal_r[i][0]; normal[1] = normal_r[i][1]; normal[2] = normal_r[i][2]; Normalize3(normal); } if (pairing_mode == CLOSEST_POINT_ALONG_NORMAL) { transform3normal(local_alignxf_inv, normal); closest = this->FindClosestAlongDir(s, normal, max_dist_match2, thread_num); // discard points farther than 20 cm if (closest && sqrt(Dist2(closest, s)) > 20) closest = NULL; } else { closest = this->FindClosest(s, max_dist_match2, thread_num); } if (closest) { transform3(source_alignxf, closest, s); if (pairing_mode == CLOSEST_PLANE) { // need to mutate s if we are looking for closest point-to-plane // s_ = (n,s-t)*n + t // to find the projection of s onto plane formed by normal n and point t double tmp[3], s_[3]; double dot; sub3(s, t, tmp); dot = Dot(normal, tmp); scal_mul3(normal, dot, tmp); add3(tmp, t, s_); s[0] = s_[0]; s[1] = s_[1]; s[2] = s_[2]; } // This should be right, model=Source=First=not moving centroid_m[0] += s[0]; centroid_m[1] += s[1]; centroid_m[2] += s[2]; centroid_d[0] += t[0]; centroid_d[1] += t[1]; centroid_d[2] += t[2]; PtPair myPair(s, t); double p12[3] = { myPair.p1.x - myPair.p2.x, myPair.p1.y - myPair.p2.y, myPair.p1.z - myPair.p2.z }; sum += Len2(p12); pairs->push_back(myPair); /*cout << "PTPAIR" << i << " " << p[0] << " " << p[1] << " " << p[2] << " - " << q_points[i][0] << " " << q_points[i][1] << " " << q_points[i][2] << " " << Len2(p12) << endl; */ } } // release resource access lock unlock(); return; }