39
39
// Class backpath
40
40
////////////////////////////////////////////////////////////////
41
41
42
- #define PRECISION 0.00001
42
+ // #define PRECISION 0.00001
43
43
44
44
45
45
//creation of a backPath
@@ -146,6 +146,7 @@ void DGtal::FrechetShortcut<TIterator,TInteger>::Backpath::updateOcculters()
146
146
double angle_min=0;
147
147
double angle_max=M_PI_4;
148
148
bool occ = false;
149
+ bool ok = true;
149
150
150
151
IntegerComputer<TInteger> ic;
151
152
@@ -157,16 +158,14 @@ void DGtal::FrechetShortcut<TIterator,TInteger>::Backpath::updateOcculters()
157
158
}
158
159
else
159
160
{
160
- typename occulter_list::iterator iter, next ;
161
- bool ok = true;
161
+ typename occulter_list::iterator iter=myOcculters.begin() ;
162
+
162
163
iter = myOcculters.begin();
163
- while(iter!= myOcculters.end () && ok)
164
+ for(typename occulter_list::size_type i=0; i < myOcculters.size () && ok ; ++i )
164
165
{
165
166
pi = Point(*(iter->first));
166
167
v = p-pi;
167
168
168
- next = iter;
169
- next++;
170
169
// pi is after p for all directions -> p is not an occulter
171
170
if(ic.dotProduct(v,u1) < 0 && ic.dotProduct(v,u2) <0)
172
171
{
@@ -178,7 +177,7 @@ void DGtal::FrechetShortcut<TIterator,TInteger>::Backpath::updateOcculters()
178
177
// anymore, p is a new occulter.
179
178
if(ic.dotProduct(v,u1) > 0 && ic.dotProduct(v,u2) > 0)
180
179
{
181
- myOcculters.erase(iter);
180
+ iter = myOcculters.erase(iter);
182
181
occ = true;
183
182
angle_min = 0;
184
183
angle_max = M_PI_4;
@@ -198,12 +197,13 @@ void DGtal::FrechetShortcut<TIterator,TInteger>::Backpath::updateOcculters()
198
197
angle_max = alpha;
199
198
// pi's angle_min is updated
200
199
iter->second.angle_min = alpha;
200
+ iter++;
201
201
}
202
202
else
203
203
if(alpha > iter->second.angle_max)
204
204
{
205
205
//pi is not an occulter anymore
206
- myOcculters.erase(iter);
206
+ iter = myOcculters.erase(iter);
207
207
occ=true;
208
208
angle_min = 0;
209
209
angle_max = M_PI_4;
@@ -225,21 +225,23 @@ void DGtal::FrechetShortcut<TIterator,TInteger>::Backpath::updateOcculters()
225
225
angle_max = M_PI_4;
226
226
// pi's angle_max is updated
227
227
iter->second.angle_max = alpha;
228
+ iter++;
228
229
}
229
230
else
230
231
if(alpha < iter->second.angle_min)
231
232
{
232
233
//pi is not an occulter anymore
233
- myOcculters.erase(iter);
234
+ iter = myOcculters.erase(iter);
234
235
occ=true;
235
236
angle_min = 0;
236
237
angle_max = M_PI_4;
237
238
}
239
+ else
240
+ iter++;
238
241
// if(alpha > iter->second.angle_max), pi does not
239
242
// change, p may be an occulter -> do nothing
240
243
241
244
}
242
- iter = next;
243
245
}
244
246
}
245
247
@@ -369,7 +371,7 @@ DGtal::FrechetShortcut<TIterator,TInteger>::Cone::Cone()
369
371
{
370
372
myInf = true;
371
373
myMin = 0;
372
- myMax = 0 ;
374
+ myMax = 2*M_PI ;
373
375
}
374
376
375
377
@@ -441,7 +443,8 @@ bool DGtal::FrechetShortcut<TIterator,TInteger>::Cone::isEmpty() const
441
443
if(myInf)
442
444
return false;
443
445
else
444
- if(myMin==myMax)
446
+ // Fix 05/2024 to enable error = 0: a cone may be defined by two values myMin=myMax --> check for empty cone by setting myMin=myMax= -1 instead
447
+ if(myMin==-1) // and then myMax = -1 too: way to represent the empty intersection of two cones.
445
448
return true;
446
449
else
447
450
return false;
@@ -509,7 +512,7 @@ typename DGtal::FrechetShortcut<TIterator,TInteger>::Cone DGtal::FrechetShortcut
509
512
// first possibility: the cones are disjoint
510
513
if(!Tools::isBetween(myMin, c.myMin, c.myMax, 2*M_PI) && !Tools::isBetween(myMax, c.myMin,
511
514
c.myMax, 2*M_PI))
512
- res = Cone(0,0);
515
+ res = Cone(-1,-1); // empty cone: both angles are set to -1
513
516
else
514
517
// or the new cone includes the old one, nothing changes, the cone remains the same.
515
518
res = *this;
@@ -523,6 +526,7 @@ typename DGtal::FrechetShortcut<TIterator,TInteger>::Cone DGtal::FrechetShortcut
523
526
res = Cone(c.myMin, myMax);
524
527
else
525
528
res = Cone(myMin,c.myMax);
529
+
526
530
527
531
return res;
528
532
}
@@ -568,6 +572,7 @@ template <typename TIterator, typename TInteger>
568
572
inline
569
573
DGtal::FrechetShortcut<TIterator,TInteger>::FrechetShortcut(double error)
570
574
{
575
+
571
576
myError = error;
572
577
myCone = Cone();
573
578
@@ -688,14 +693,18 @@ DGtal::FrechetShortcut<TIterator,TInteger>::computeNewCone()
688
693
Point firstP = Point(*myBegin);
689
694
Point newP = Point(*(myEnd+1));
690
695
691
-
692
696
Cone newCone=myCone;
697
+
698
+ if(firstP == newP)
699
+ return newCone;
693
700
694
701
// compute the tangent points defined by the first point and the
695
702
// circle C(newP,error)
703
+
704
+
696
705
bool intersect = Tools::circleTangentPoints(firstP[0],firstP[1], newP[0], newP[1], myError/(sqrt(2.0F)), &x0, &y0,
697
706
&x1, &y1);
698
-
707
+
699
708
if(intersect)
700
709
{
701
710
// define a cone according to the new tangent points
@@ -704,20 +713,16 @@ DGtal::FrechetShortcut<TIterator,TInteger>::computeNewCone()
704
713
if(fabs(x0-x1) < PRECISION && fabs(y0-y1) < PRECISION)
705
714
{
706
715
double angle = Tools::computeAngle(firstP[0],firstP[1],newP[0],newP[1]);
707
- assert(angle != -1);
708
- double angle0 = angle - M_PI_2;
709
- if(angle0<0)
710
- angle0 = angle0+2*M_PI;
711
- double angle1 = angle + M_PI_2;
712
- if(angle1>2*M_PI)
713
- angle1 = angle1-2*M_PI;
714
- c = Cone(angle0,angle1);
716
+
717
+ // the cone is reduced to a line
718
+ c = Cone(angle,angle);
715
719
}
716
720
else
717
721
c = Cone(firstP[0],firstP[1],x0,y0,x1,y1);
718
-
722
+
719
723
newCone.intersectCones(c);
720
724
}
725
+
721
726
722
727
return newCone;
723
728
@@ -873,7 +878,7 @@ inline
873
878
void DGtal::FrechetShortcut<TIterator,TInteger>::resetCone()
874
879
{
875
880
myCone.myMin = 0;
876
- myCone.myMax = 0;
881
+ myCone.myMax = 2*M_PI; // default cone is the whole space
877
882
myCone.myInf = true;
878
883
}
879
884
0 commit comments