26 #ifndef EDELSBRUNNER96_SIMPLEX_HPP_
27 #define EDELSBRUNNER96_SIMPLEX_HPP_
34 namespace edelsbrunner96 {
36 template<
class Traits>
47 inline void pass(std::initializer_list<int>&&) {}
49 template<
class Traits>
50 template<
typename ... PointRefs>
62 template<
class Traits>
63 template<
typename Container>
72 template<
class Traits>
81 template <
class Traits>
88 template<
class Traits>
94 template<
class Traits>
97 const auto iter = std::lower_bound(V.begin(), V.end(), v);
98 return iter - V.begin();
101 template <
class Traits>
102 Eigen::Matrix<typename Traits::Scalar, Traits::NDim, 1>
104 const typename Traits::Point& xq)
const {
105 typedef Eigen::Matrix<Scalar, Traits::NDim, Traits::NDim>
Matrix;
108 const Point& v0 = storage[V[0]];
109 for (
int i = 0; i < Traits::NDim; i++) {
110 A.col(i) = storage[V[i + 1]] - v0;
114 Eigen::FullPivLU<Matrix> LU(A.transpose());
118 return LU.solve(xq - v0);
121 template <
class Traits>
122 Eigen::Matrix<typename Traits::Scalar, Traits::NDim + 1, 1>
124 Storage& storage,
const typename Traits::Point& xq)
const {
125 typedef Eigen::Matrix<Scalar, Traits::NDim + 1, Traits::NDim + 1>
Matrix;
128 for (
int i = 0; i < Traits::NDim + 1; i++) {
129 A.template block<Traits::NDim, 1>(0, i) = storage[V[i]];
130 A(Traits::NDim, i) = 1;
134 Eigen::FullPivLU < Matrix > LU(A);
138 Eigen::Matrix<Scalar, Traits::NDim + 1, 1> xq_raised;
139 xq_raised.template head<Traits::NDim>() = xq;
140 xq_raised[Traits::NDim] = 1;
142 return LU.solve(xq_raised);
145 template<
class Traits>
149 return this->BarycentricCoordinates(storage, xq).minCoeff() > 0;
152 template<
class Traits>
154 typedef Eigen::Matrix<Scalar, Traits::NDim, Traits::NDim>
Matrix;
155 typedef Eigen::Matrix<Scalar, Traits::NDim, 1> Vector;
162 const Point& v0 = storage[V[0]];
163 for (
int i = 0; i < Traits::NDim; i++) {
164 Vector dv = storage[V[i + 1]] - v0;
166 b[i] = storage[V[i + 1]].squaredNorm() - v0.squaredNorm();
170 c = A.fullPivLu().solve(b);
173 r2 = (c - v0).squaredNorm();
176 template <
class Traits,
class Derived,
class Iterator>
178 typename Traits::Storage& storage,
const typename Traits::Point&
x,
179 Iterator begin, Iterator end,
180 Eigen::MatrixBase<Derived>* L,
181 typename Traits::Point* x_proj) {
183 typedef typename Traits::Scalar Scalar;
184 typedef Eigen::Matrix<Scalar, Traits::NDim, Eigen::Dynamic>
Matrix;
185 typedef Eigen::Matrix<Scalar, Traits::NDim, 1> Vector;
189 Index n = (end - begin);
191 assert(n <= Traits::NDim + 1);
193 Vector v0 = storage[*begin++];
195 L->derived().resize(1,1);
196 (*L)[0] = Scalar(1.0);
201 Matrix V(
int(Traits::NDim), n - 1);
202 L->derived().resize(n, 1);
203 for (
int i = 0; begin != end; ++begin, ++i) {
204 V.col(i) = (storage[*begin] - v0);
206 auto full_piv_lu = (V.transpose() * V).fullPivLu();
207 L->template tail(n-1) = full_piv_lu.solve(V.transpose() * (x - v0));
208 (*L)[0] = Scalar(1.0) - L->template tail(n-1).sum();
209 *x_proj = V * (L->template tail(n - 1)) + v0;
212 template <
class Traits,
class OutputIterator>
214 const typename Traits::Point&
x,
215 const typename Traits::SimplexRef s_ref,
216 typename Traits::Point* x_proj,
217 OutputIterator V_out) {
218 typedef typename Traits::PointRef PointRef;
219 typedef typename Traits::Point Point;
220 typedef typename Traits::Scalar Scalar;
224 std::array<PointRef, Traits::NDim + 1> V;
225 std::copy(storage[s_ref].V.begin(), storage[s_ref].V.end(), V.begin());
226 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> L;
229 auto begin = V.begin();
230 if(*begin == storage.NullPoint()) {
235 for (; end <= V.end(); ++end) {
238 BarycentricProjection<Traits>(storage,
x, begin, end, &L, x_proj);
242 if (L.minCoeff() < 0) {
243 std::swap(*begin, *(end-1));
245 BarycentricProjection<Traits>(storage,
x, begin, end, &L, x_proj);
252 return (*x_proj - x).norm();
257 auto iter_nearest = end;
258 Scalar dist_nearest = (storage[*iter_nearest] -
x).
dot(normal);
259 for (
auto iter = iter_nearest + 1; iter != V.end(); ++iter) {
261 Scalar dist = (storage[*iter] -
x).
dot(normal);
262 if (dist < dist_nearest) {
270 if (dist_nearest > (*x_proj - x).dot(normal)) {
274 return (*x_proj - x).norm();
278 std::swap(*end, *iter_nearest);
285 return (*x_proj - x).norm();
290 #endif // EDELSBRUNNER96_SIMPLEX_HPP_
Eigen::Matrix< typename Traits::Scalar, Traits::NDim+1, 1 > BarycentricCoordinates(Storage &storage, const typename Traits::Point &xq) const
Given a simplex as the convex hull of the points in V, compute the barycentric coordinates of the poi...
A convenience for setting vertices of a simplex.
Eigen::Matrix< typename Traits::Scalar, Traits::NDim, 1 > CoordinatesOf(Storage &storage, const typename Traits::Point &xq) const
Given a simplex as the convex hull of the points in V, compute the coordinates of the point xq on the...
void SetNeighborAcross(PointRef q, SimplexRef n)
set the neighbor across the specified vertex
Traits::PointRef PointRef
void ComputeCenter(Storage &storage)
called after vertices are filled computes the circumcenter
SimplexBase()
initializes version and flags; in debug mode, also zeros out arrays
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 ...
bool Contains(Storage &storage, const typename Traits::Point &xq) const
Interference test, return true if the query point lies inside the closed hull of the point set...
__host__ __device__ Normalized< Scalar, Exp, Spec > normalized(const RValue< Scalar, Exp, Spec > &exp)
Traits::SimplexRef SimplexRef
void pass(std::initializer_list< int > &&)
A trick to allow parameter pack expansion for filling.
Char8_t * copy(const Char8_t *s)
__device__ __host__ Scalar dot(const RValue< Scalar, ROWS, 1, ExpA > &A, const RValue< Scalar, ROWS, 1, ExpB > &B)
compute the DOT
void SetVertices(PointRefs...refs)
Set the vertices of a simplex directly from a list of point refs.
uint8_t IndexOf(PointRef v) const
return the index of the specified vertex
void PushBack(PointRef p)
void BarycentricProjection(typename Traits::Storage &storage, const typename Traits::Point &x, Iterator begin, Iterator end, Eigen::MatrixBase< Derived > *L, typename Traits::Point *x_proj)
Given a query point, x and a set of vertex points, V, return the point y in hull(V) which is closest ...
SimplexRef NeighborAcross(PointRef q) const
return the neighbor across the specified vertex
Traits::Scalar SimplexDistance(typename Traits::Storage &storage, const typename Traits::Point &x, const typename Traits::SimplexRef s_ref, typename Traits::Point *x_proj, OutputIterator V_out)
Given a set of <= NDim+1 vertices, compute the distance of the query point to the convex hull of the ...