Menu

#176 Calling GetBounds method causes infinite loop

*
open
nobody
1
2017-11-23
2017-11-22
No

Running simple code snippet:

Clipper clipper;

Path rectangle;
rectangle << Point64(0, 0) << Point64(100, 0)
          << Point64(100, 100) << Point64(0, 100);
clipper.AddPath(rectangle, ptSubject);
Rect64 bounds = clipper.GetBounds();

causes infinite loop in here:

// clipper.cpp, GetBounds() ...
      do {
        if (v2.pt.x < result.left) result.left = v2.pt.x;
        if (v2.pt.x > result.right) result.right = v2.pt.x;
        if (v2.pt.y < result.top) result.top = v2.pt.y;
        if (v2.pt.y > result.bottom) result.bottom = v2.pt.y;
      } while (&v2 != &v);

I've tried running Execute() method before GetBounds(), but this hasn't fixed the problem either.

Discussion

  • Angus Johnson

    Angus Johnson - 2017-11-22

    Thanks, and yes, it's missing an important step.
    Here's what the function should look like (though admittedly I haven't tested it yet) ...

      Rect64 Clipper::GetBounds()
      {
        MinimaList::iterator lm_iter = minima_list_.begin();
        if (lm_iter == minima_list_.end()) return Rect64(0, 0, 0, 0);
    
        Rect64 result = Rect64(INT64_MAX, INT64_MAX, INT64_MIN, INT64_MIN);
        while (lm_iter != minima_list_.end()) {
          Vertex  &v = *(*lm_iter)->vertex, v2 = v;
          do {
            if (v2.pt.x < result.left) result.left = v2.pt.x;
            if (v2.pt.x > result.right) result.right = v2.pt.x;
            if (v2.pt.y < result.top) result.top = v2.pt.y;
            if (v.pt.y > result.bottom) result.bottom = v.pt.y;
            v2 = *v2.next;
          } while (&v2 != &v);
          ++lm_iter;
        }
        return result;
      }
    
     
  • Andrii Doroshenko

    I've tested your changes now. This yields the same infinite loop. But if I change the condition:

    while (&v2 != &v);
    

    to this:

    while (v2.pt != v.pt);
    

    seems to solve the problem and yields correct Rect64.

    Oops, sent previous message as anonymous...

     

    Last edit: Andrii Doroshenko 2017-11-23
  • Angus Johnson

    Angus Johnson - 2017-11-23

    OK, sorry about that.
    This time I've had a proper look and tested too ...

      Rect64 Clipper::GetBounds()
      {
        if (vertex_list_.size() == 0) return Rect64(0, 0, 0, 0);
        Rect64 result = Rect64(INT64_MAX, INT64_MAX, INT64_MIN, INT64_MIN);
        VerticesList::const_iterator it = vertex_list_.cbegin();
        while (it != vertex_list_.cend()) {
          Vertex  *v = *it, *v2 = v;
          do {
            if (v2->pt.x < result.left) result.left = v2->pt.x;
            if (v2->pt.x > result.right) result.right = v2->pt.x;
            if (v2->pt.y < result.top) result.top = v2->pt.y;
            if (v2->pt.y > result.bottom) result.bottom = v2->pt.y;
            v2 = v2->next;
          } while (v2 != v);
          ++it;
        }
        return result;
      }
    
     

    Last edit: Angus Johnson 2017-11-23
  • Andrii Doroshenko

    Yeah, works like a charm, thanks!

     

Anonymous
Anonymous

Add attachments
Cancel





MongoDB Logo MongoDB