26 #ifndef EDELSBRUNNER96_LINE_WALKER_HPP_
27 #define EDELSBRUNNER96_LINE_WALKER_HPP_
35 namespace edelsbrunner96 {
41 template<
typename Traits>
42 typename Traits::SimplexRef
LineWalk(
typename Traits::Storage& storage,
43 typename Traits::SimplexRef s0_ref,
44 const typename Traits::Point& pt) {
45 typedef typename Traits::Scalar Scalar;
46 typedef typename Traits::PointRef PointRef;
47 typedef typename Traits::SimplexRef SimplexRef;
48 typedef typename Traits::Simplex Simplex;
50 typedef Eigen::Matrix<Scalar, Traits::NDim, Traits::NDim> MatrixN;
51 typedef Eigen::Matrix<Scalar, Traits::NDim, 1> VectorN;
53 Simplex& s0 = storage[s0_ref];
54 SimplexRef result = storage.NullSimplex();
57 VectorN ps = VectorN::Zero();
58 for (PointRef pr : s0.V) {
59 ps += (1.0 / (Traits::NDim + 1)) * storage[pr];
63 typedef std::pair<Scalar, SimplexRef> QueueElement;
64 std::list<QueueElement> simplex_queue;
67 std::list<SimplexRef> marked;
71 marked.push_back(s0_ref);
72 simplex_queue.push_back(QueueElement(0, s0_ref));
75 while (!simplex_queue.empty()) {
76 QueueElement e = simplex_queue.front();
77 Scalar s_min = e.first;
78 SimplexRef simplex_ref = e.second;
79 Simplex& simplex = storage[simplex_ref];
80 simplex_queue.pop_front();
85 if (simplex.V[0] == storage.NullPoint()) {
93 typedef std::pair<Scalar, int> FacetElement;
94 typedef std::set<FacetElement> FacetSet;
97 for (
int i = 0; i < Traits::NDim + 1; i++) {
101 for (
int j = 0; j < Traits::NDim + 1; j++) {
105 A.row(k++) = storage[simplex.V[j]] - ps;
108 VectorN normal = A.fullPivLu().solve(b).normalized();
109 Scalar offset = normal.dot(A.row(0));
118 Scalar
s = offset / (pt - ps).
dot(normal);
130 facet_set.insert(FacetElement(s, i));
134 if (facet_set.empty()) {
138 FacetElement first_element = *facet_set.begin();
139 if (first_element.first > 1) {
140 result = simplex_ref;
147 for (
const FacetElement element : facet_set) {
148 if (std::abs(element.first - first_element.first) < 1e-9) {
149 SimplexRef neighbor_ref = simplex.N[element.second];
150 Simplex& neighbor = storage[neighbor_ref];
152 simplex_queue.push_back(QueueElement(element.first, neighbor_ref));
154 marked.push_back(neighbor_ref);
161 for (SimplexRef
s : marked) {
167 template <
typename Traits,
typename InputIterator,
typename OutputIterator>
169 typename Traits::SimplexRef s_0,
170 InputIterator Vf_begin, InputIterator Vf_end,
171 OutputIterator out) {
172 typedef typename Traits::PointRef PointRef;
173 typedef typename Traits::SimplexRef SimplexRef;
177 int n_vertices = (Vf_end - Vf_begin);
184 std::list<SimplexRef> bfs_queue;
186 bfs_queue.push_back(s_0);
189 std::vector<PointRef> V;
190 V.reserve(Traits::NDim + 1 - n_vertices);
192 for (
auto queue_iter = bfs_queue.begin(); queue_iter != bfs_queue.end();
194 SimplexRef s_ref = *queue_iter;
202 std::set_difference(storage[s_ref].V.begin(),
203 storage[s_ref].V.end(),
204 Vf_begin, Vf_end, std::back_inserter(V));
207 assert(V.size() + n_vertices == Traits::NDim+1);
211 for (PointRef v : V) {
212 SimplexRef neighbor_ref = storage[s_ref].NeighborAcross(v);
215 bfs_queue.push_back(neighbor_ref);
221 for(SimplexRef s_ref : bfs_queue) {
226 template <
typename Traits,
class OutputIterator>
228 const typename Traits::SimplexRef s_0,
229 const typename Traits::Point& x_q,
230 const typename Traits::Scalar epsilon,
231 std::list<typename Traits::SimplexRef>& search_queue,
232 OutputIterator out) {
233 typedef typename Traits::SimplexRef SimplexRef;
234 typedef typename Traits::Scalar Scalar;
235 typedef typename Traits::Point Point;
236 typedef typename Traits::PointRef PointRef;
239 search_queue.push_back(s_0);
241 std::vector<PointRef> V_feature;
242 V_feature.reserve(Traits::NDim+1);
244 for (
auto queue_iter = search_queue.begin(); queue_iter != search_queue.end();
247 Scalar dist = SimplexDistance<Traits>(storage, x_q, *queue_iter, &x_proj,
248 std::back_inserter(V_feature));
252 if (storage[*queue_iter].V[0] == storage.NullPoint()) {
256 if (dist < epsilon || IsVisible<Traits>(storage, *queue_iter, x_q)) {
257 *out++ = *queue_iter;
259 for (SimplexRef s_ref : storage[*queue_iter].N) {
262 search_queue.push_back(s_ref);
269 if (dist < epsilon) {
270 *out++ = *queue_iter;
271 for (SimplexRef s_ref : storage[*queue_iter].N) {
274 search_queue.push_back(s_ref);
279 std::list<SimplexRef> link;
280 std::sort(V_feature.begin(), V_feature.end());
281 FeatureWalk<Traits>(storage, *queue_iter, V_feature.begin(),
282 V_feature.end(), std::back_inserter(link));
283 for (SimplexRef s_ref : link) {
286 search_queue.push_back(s_ref);
293 for(SimplexRef s_ref : search_queue) {
298 template <
typename Traits,
class OutputIterator>
300 const typename Traits::SimplexRef s_0,
301 const typename Traits::Point& x_q,
302 const typename Traits::Scalar epsilon,
303 OutputIterator out) {
304 typedef typename Traits::SimplexRef SimplexRef;
305 std::list<SimplexRef> search_queue;
306 FuzzyWalk_<Traits>(storage, s_0, x_q, epsilon, search_queue, out);
309 template <
class Traits>
311 typename Traits::SimplexRef s_ref,
312 const typename Traits::Point& x_q,
313 typename Traits::Scalar epsilon) {
314 typedef typename Traits::Scalar Scalar;
315 typedef typename Traits::PointRef PointRef;
316 typedef typename Traits::Point Point;
317 typedef typename Traits::SimplexRef SimplexRef;
318 typedef typename Traits::Simplex Simplex;
320 Simplex& simplex = storage[s_ref];
321 SimplexRef interior_ref = simplex.N[0];
322 Simplex& interior_simplex = storage[interior_ref];
326 PointRef interior_peak_ref;
327 std::set_difference(interior_simplex.V.begin(), interior_simplex.V.end(),
328 simplex.V.begin(), simplex.V.end(), &interior_peak_ref);
332 typedef Eigen::Matrix<Scalar, Traits::NDim, Traits::NDim> MatrixN;
333 typedef Eigen::Matrix<Scalar, Traits::NDim, 1> VectorN;
334 const Point& interior_point = storage[interior_peak_ref];
336 for (
int i = 1; i < Traits::NDim + 1; i++) {
337 A.row(i - 1) = storage[simplex.V[i]] - interior_point;
341 VectorN normal = A.fullPivLu().solve(b).normalized();
342 Scalar offset = normal.dot(A.row(0));
352 return (normal.dot(x_q - interior_point) - offset > -epsilon);
355 template<
class Traits,
class OutputIterator>
357 typename Traits::Storage& storage,
typename Traits::SimplexRef s_0,
358 const typename Traits::Point& x_q,
359 OutputIterator out) {
360 typedef typename Traits::Scalar Scalar;
361 typedef typename Traits::PointRef PointRef;
362 typedef typename Traits::Point Point;
363 typedef typename Traits::SimplexRef SimplexRef;
364 typedef typename Traits::Simplex Simplex;
366 typedef Eigen::Matrix<Scalar, Traits::NDim, Traits::NDim> MatrixN;
367 typedef Eigen::Matrix<Scalar, Traits::NDim, 1> VectorN;
369 std::list<SimplexRef> visible_list;
370 std::list<SimplexRef> marked_list;
373 visible_list.push_back(s_0);
375 marked_list.push_back(s_0);
377 typename std::list<SimplexRef>::iterator iter = visible_list.begin();
378 for (; iter != visible_list.end(); ++iter) {
379 SimplexRef simplex_ref = *iter;
380 Simplex& simplex = storage[simplex_ref];
387 for (
int i = 1; i < Traits::NDim + 1; i++) {
388 SimplexRef neighbor_ref = simplex.N[i];
389 Simplex& neighbor_simplex = storage[neighbor_ref];
392 marked_list.push_back(neighbor_ref);
393 SimplexRef interior_ref = neighbor_simplex.N[0];
394 Simplex& interior_simplex = storage[interior_ref];
398 PointRef interior_peak_ref;
400 interior_simplex.V.begin(), interior_simplex.V.end(),
401 neighbor_simplex.V.begin(), neighbor_simplex.V.end(),
406 typedef Eigen::Matrix<Scalar, Traits::NDim, Traits::NDim> MatrixN;
407 typedef Eigen::Matrix<Scalar, Traits::NDim, 1> VectorN;
408 const Point& interior_point = storage[interior_peak_ref];
410 for (
int i = 1; i < Traits::NDim + 1; i++) {
411 A.row(i - 1) = storage[neighbor_simplex.V[i]] - interior_point;
415 VectorN normal = A.fullPivLu().solve(b).normalized();
416 Scalar offset = normal.dot(A.row(0));
426 if (normal.dot(x_q - interior_point) > offset) {
427 visible_list.push_back(neighbor_ref);
434 for (SimplexRef s_ref : marked_list) {
439 for (SimplexRef s_ref : visible_list) {
444 template <
class Traits,
class OutputIterator>
446 typename Traits::SimplexRef simplex_ref,
447 OutputIterator out) {
448 typedef typename Traits::Simplex Simplex;
449 typedef typename Traits::SimplexRef SimplexRef;
451 std::list<SimplexRef> bfs_queue;
452 bfs_queue.push_back(simplex_ref);
455 typename std::list<SimplexRef>::iterator iter = bfs_queue.begin();
456 for (; iter != bfs_queue.end(); ++iter) {
457 SimplexRef simplex_ref = *iter;
458 *out++ = simplex_ref;
459 Simplex& simplex = storage[simplex_ref];
460 for (SimplexRef neighbor_ref : simplex.N) {
461 Simplex& neighbor = storage[neighbor_ref];
464 bfs_queue.push_back(neighbor_ref);
469 for (SimplexRef simplex_ref : bfs_queue) {
476 #endif // EDELSBRUNNER96_LINE_WALKER_HPP_
void FeatureWalk(typename Traits::Storage &storage, typename Traits::SimplexRef s_0, InputIterator Vf_begin, InputIterator Vf_end, OutputIterator out)
Given a sub-simplex feature and a simplex adjacent to that feature, enumerate all simplices that are ...
simplex has been touched during a fuzzy walk
bool IsVisible(typename Traits::Storage &storage, typename Traits::SimplexRef s_ref, const typename Traits::Point &x_q, typename Traits::Scalar epsilon=0.0)
Given a hull simplex, return true if it is visible by the query point.
has been queud in breadth-first search
simplex has been touched during feature walk
void FuzzyWalk_(typename Traits::Storage &storage, const typename Traits::SimplexRef s_0, const typename Traits::Point &x_q, const typename Traits::Scalar epsilon, std::list< typename Traits::SimplexRef > &search_queue, OutputIterator out)
Implementation, exposed so that the search_queue can be examined in tests.
Traits::SimplexRef LineWalk(typename Traits::Storage &storage, typename Traits::SimplexRef s_0, const typename Traits::Point &p)
Starting at the median point of simplex s_0, walk the triangulation in the direction of p until the s...
simplex has been touched during hull walk
void GetVisibleHull(typename Traits::Storage &storage, typename Traits::SimplexRef s_0, const typename Traits::Point &x_q, OutputIterator out)
Starting at some x-visible hull simplex, return a list of all x-visible hull simplices.
uint_t sort(KeyType *d_DstKey, ValueType *d_DstVal, KeyType *d_SrcKey, ValueType *d_SrcVal, uint_t arrayLength, uint_t sharedLength, Direction dir, uint_t globalThread)
kernel launcher, sorts an array of key/value pairs using the bitonic sort algorithm ...
__device__ __host__ Scalar dot(const RValue< Scalar, ROWS, 1, ExpA > &A, const RValue< Scalar, ROWS, 1, ExpB > &B)
compute the DOT
void FuzzyWalk(typename Traits::Storage &storage, const typename Traits::SimplexRef s_0, const typename Traits::Point &x_q, const typename Traits::Scalar epsilon, OutputIterator out)
Given a simplex in a triangulation and a query point, walk the triangulation in the direction of x_q ...
void BreadthFirstSearch(typename Traits::Storage &storage, typename Traits::SimplexRef simplex_ref, OutputIterator out)
Get a list of all simplices by breadth first search starting at simplex_ref.
simplex has been touched during line walk