14 using namespace reach;
15 using namespace numeric;
25 currentCriticalValueList().push_back(dx);
30 return criticalValues;
34 return localCriticalValues.local();
39 const Curve& P = this->P->curve;
40 const Curve& Q = this->Q->curve;
43 criticalValues.clear();
44 if (a) collectCriticalValues_a();
46 collectCriticalValues_b(P,Q);
47 collectCriticalValues_b(Q,P);
50 collectCriticalValues_c(P,Q);
51 collectCriticalValues_c(Q,P);
53 if (d) collectCriticalValues_d();
56 combineCriticalValues();
57 removeDuplicates(criticalValues);
60 std::cout <<
" Data: "<<criticalValues.size()<<
" critical values." << std::endl;
68 std::sort(criticalValues.begin(), criticalValues.end());
76 tbb::parallel_sort(criticalValues.begin(),criticalValues.end());
78 localCriticalValues.clear();
84 double* begin = &vector[0];
85 double* end = begin+vector.size();
96 vector.resize(b+1 - begin);
103 size_t s1 = a.size();
104 size_t s2 = b.size();
106 memcpy(&a[s1], &b[0], s2*
sizeof(
double));
113 const Curve& P = this->P->curve;
114 const Curve& Q = this->Q->curve;
118 if (!P.isClosed() && !Q.isClosed())
120 collectCriticalValue( euclidean_distance<accurate_float>(P.front(),Q.front()));
121 collectCriticalValue( euclidean_distance<accurate_float>(P.back(),Q.back()));
128 for(
int k=1; k < Q.size(); ++k)
130 QLineF segment (Q[k-1],Q[k]);
131 accurate_float dist = segment_distance<accurate_float>(segment,p);
132 collectCriticalValue(dist);
141 for(
int i=0; i < P.length(); ++i)
149 auto lambda = [&](
size_t i) {
154 tbb::parallel_for( (
size_t)0, (
size_t)P.size(), lambda);
165 for(
int k=0; k < Q.size(); ++k) {
166 for (
int l = k+1; l < Q.size(); ++l) {
170 accurate_float dist = bisector_distance<accurate_float> (Q[k], Q[l], segment, 1e-3);
171 collectCriticalValue(dist);
179 for(
int i=1; i < P.length(); ++i) {
180 QLineF segment(P[i-1],P[i]);
187 auto lambda = [&](
size_t i) {
188 QLineF segment(P[i-1],P[i]);
192 tbb::parallel_for( (
size_t)1, (
size_t)P.length(), lambda);
200 const Curve& Q = this->Q->curve;
201 const Polygon& R = this->Q->reflex;
202 Q_ASSERT(R.size() >= 1);
206 for(
int r1=0; r1 < R.size(); ++r1)
208 const Point& q1 = Q[R[r1]];
210 accurate_float dist = segment_distance<accurate_float>(diagonal,q1);
211 collectCriticalValue(dist);
213 for (
int r2 = r1+1; r2 < R.size(); ++r2) {
214 const Point& q2 = Q[R[r2]];
218 dist = bisector_distance<accurate_float> (q1, q2, diagonal, 1e-3);
219 collectCriticalValue(dist);
230 const Curve& P = this->P->curve;
231 for(
const Segment& d : c_diagonals())
233 QLineF diagonal(P[d.first], P[d.second]);
240 const Curve& P = this->P->curve;
241 auto lambda = [&] (
size_t i) {
242 Segment d = c_diagonals_vector[i];
243 QLineF diagonal(P[d.first], P[d.second]);
247 tbb::parallel_for( (
size_t)0, (
size_t)c_diagonals_vector.size(), lambda);
254 Q_ASSERT(canOptimisePoly());
257 setStatus((approximation==0.0) ? RUNNING_OPT_POLY : RUNNING_APPROX_POLY);
264 local_fs.reset(
new FreeSpace(P->curve, Q->curve));
266 if (approximation==0.0)
271 collectCriticalValues(
false,
true,
true,
true);
275 int hi = criticalValues.size();
279 lo = binarySearch<Pointer> (criticalValues, lo, hi,
281 Q_ASSERT(lo >= 0 && lo < criticalValues.size());
284 epsilon = criticalValues[lo];
285 local_fs->calculateFreeSpace(epsilon);
286 result = decidePolygon(local_fs, no_path, epsilon,
false);
288 if (result)
goto label_result;
293 if (hi >= criticalValues.size()) {
294 hi = criticalValues.size();
298 epsilon = criticalValues[hi];
299 local_fs->calculateFreeSpace(epsilon);
300 result = decidePolygon(local_fs, no_path, epsilon,
false);
302 if (result && step == 1)
goto label_result;
312 Q_ASSERT(i >= 0 && i < criticalValues.size());
313 epsilon = criticalValues[i];
321 local_fs->calculateFreeSpace(epsilon);
322 result = decidePolygon(local_fs, no_path, epsilon,
false);
324 if (result)
goto label_result;
329 Q_ASSERT((
bool)result);
337 double repsilon =
round_up(epsilon,32);
338 updatePath(path, boost::static_pointer_cast<Graph>(result),repsilon);
341 setStatus( result ? YES:NO );
344 emit optimisationResult(epsilon);
345 emit pathUpdated((
bool)result);
349 criticalValues.clear();
357 Q_ASSERT(canOptimiseCurve());
359 setStatus((approximation==0.0) ? RUNNING_OPT_CURVE : RUNNING_APPROX_CURVE);
363 local_fs.reset(
new FreeSpace(P->curve, Q->curve));
365 if (approximation==0.0)
369 collectCriticalValues(
true,
true,
true,
false);
371 int i = binarySearch<reach::Pointer> (criticalValues, -1, criticalValues.size(),
373 Q_ASSERT(i >= 0 && i < criticalValues.size());
374 epsilon = criticalValues[i];
380 epsilon = intervalSearch<reach::Pointer> (0.0,upper_bound, approximation, &
Algorithm::decideCurve, result);
383 Q_ASSERT((
bool)result);
385 criticalValues.clear();
388 setStatus(result ? YES:NO);
390 emit optimisationResult(epsilon);
Represents a polygon line segment from node i to j.
frechet::reach::Graph::ptr GraphPtr
the result of the decision algorithm is a reachability Graph containing a feasible path
double round_up(double x, int ulps=1)
rounding function with 'units in the last place' Roughly speaking, a ulp is the smallest representabl...
virtual void collectCriticalValues_d()=0
compute critical values for diagonals and reflex vertices
global definitions for all algorithms.
std::vector< double > CriticalValueList
a list of critical values
virtual void combineCriticalValues() override
reduce thread-local lists to a global list, then sort it
virtual void collectCriticalValues_d() override
compute critical values for diagonals and reflex vertices
virtual void collectCriticalValues_b(const Curve &P, const Curve &Q) override
compute critical values of type (b)
virtual void combineCriticalValues() override
hook for post-processing of critical values
void removeDuplicates(CriticalValueList &vector)
remove duplicates from a sorted list of critical values
boundary interval in the reachability structure. Represents an interval on the boundary of the FreeSp...
virtual void collectCriticalValues_c(const Curve &P, const Curve &Q) override
compute critical values of type (c)
time_point printDebugTimer(std::string label)
clock benchmark and print elapsed time
GraphPtr decidePolygon(FreeSpace::ptr fs, reach::FSPath::ptr path, double epsilon, bool update_status)
execute the decision variant for simple polygons (Buchin et al.'s algorithm)
static const CriticalValueList & combine(CriticalValueList &a, const CriticalValueList &b)
reduce two thread-local lists of critical values; the lists are simply appended
void collectCriticalValues_a()
compute critical values of type (a)
long double accurate_float
QPointF Point
a point in the plane; with double floating point precision. This type is heavily used throughout all ...
boost::shared_ptr< FSPath > ptr
smart pointer to an FSPath object
void collectCriticalValues_c(const QLineF &pseg, const Curve &Q)
compute critical values of type (c)
QPolygonF Curve
a polygonal curve in the plane; with double floating point precision. This type is heavily used throu...
virtual void collectCriticalValues_c(const Curve &P, const Curve &Q) override
compute critical values of type (c)
void collectCriticalValues_b(const Point &p, const Curve &Q)
compute critical values of type (b)
reach::Pointer decideCurve(FreeSpace::ptr fs, reach::FSPath::ptr path, double ignored, bool update_status)
execute the decision variant for curves. (Alt and Godau's algorithm)
double optimiseCurve(double approximation=0.0)
execute the optimisation variant for curves. (Alt and Godau's algorithm)
The FreeSpace class models the Free-Space Diagram calculated from two curves.
void collectCriticalValues(bool a, bool b, bool c, bool d)
compute a set of critical values for the optimisation variant
virtual void collectCriticalValues_d() override
compute critical values for diagonals and reflex vertices
virtual CriticalValueList & currentCriticalValueList()
thread-local copy of critical values
double optimisePolygon(reach::FSPath::ptr path, double approximation=0.0)
execute the optimisaion variant for simple polygons. (Buchin et al.'s algorithm) The result value is ...
std::vector< int > Polygon
Polygon a sub-set of vertex indexes.
virtual CriticalValueList & currentCriticalValueList()
get the set of current critical values
virtual void collectCriticalValues_b(const Curve &P, const Curve &Q) override
compute critical values of type (b)
double max_euclidean_distance(const Curve &P, const Curve &Q)
compute the maximum distance between two polygons This value serves as an upper bound for the Frechet...
virtual void collectCriticalValue(const accurate_float &x)
store a critical value. Duplicates are accepted but removed later.