15 const auto diff = seg.
diff();
16 const auto len2 = diff.squaredNorm();
19 const auto t = std::max(0.0, std::min(1.0, (
p - seg.first).dot(diff)/len2));
20 const Point projection = seg.first + t*diff;
22 return (
p - projection).norm();
26 root_(
std::move(segs)) {}
31 const auto n = segs.size();
33 if (n <= leaf_capacity)
35 segments_ = std::move(segs);
41 for (
const auto &seg : segs)
43 pivot_ += (seg.first[Axis] + seg.second[Axis]);
48 auto first_left_seg = std::partition(segs.begin(), segs.end(),
51 return (seg.first[Axis] < pivot_) != (seg.second[Axis] < pivot_);
54 auto first_right_seg = std::partition(first_left_seg, segs.end(),
57 return seg.first[Axis] < pivot_;
60 std::vector<Segment> right_segs(first_right_seg, segs.end());
61 segs.erase(first_right_seg, segs.end());
63 for (
auto i = segs.begin(); i != first_left_seg; ++i)
67 const auto diff = i->diff();
68 const double factor = (pivot_ - i->first[Axis])/diff[Axis];
70 Segment left{i->first, i->first + diff*factor};
71 Segment right{i->first + diff*factor, i->second};
74 if (diff[Axis] < 0) std::swap(left, right);
78 right_segs.push_back(right);
81 if (segs.size()) left_.reset(
new ChildNode(std::move(segs)));
82 if (right_segs.size()) right_.reset(
new ChildNode(std::move(right_segs)));
86 template<
class Callback>
88 Point p,
double radius,
const Callback &cb)
const
90 for (
const auto& seg : segments_)
94 if (left_ &&
p[Axis] - radius <= pivot_)
95 left_->segments_within(
p, radius, cb);
97 if (right_ &&
p[Axis] + radius >= pivot_)
98 right_->segments_within(
p, radius, cb);
103 std::vector<Segment> ret;
113 template<
class Callback>
116 if (left_) left_->traverse(cb, depth+1);
117 cb(segments_, pivot_, Axis, depth);
118 if (right_) right_->traverse(cb, depth+1);
124 const double pivot,
int axis,
int depth)
126 os << std::string(10+depth*2,
' ');
128 os << segs.size() <<
" segments";
130 os << axis <<
":" << pivot;