1

I am using the c# version of Clipper. I would like to clip a closed subj path with a closed clip path, but have the result be multiple open lines. For example, slicing say a star shape into two parts with a long rectangle, but what is left of the two sides of the subj shape is two open lines.

In this clipping question, Angus said that the lines to be clipped must be open in order for the results to be open. Is there a way to do the clipping operation with two closed paths? As a workaround, I was thinking I could do a simple difference of the two closed paths and then traverse the result. Each time I find a vertex not contained in the subj path, then start a new path with the next vert. When I get to the end, join the first path to the end of the last path found. Is there another way?

Community
  • 1
  • 1
  • 1
    I don't think you're talking about the same "Clipper" as the tag you've applied to your question is for. It's for an old dBase-like program from the 1980's, if I remember right. – RenniePet Dec 16 '14 at 20:14
  • 1
    Clipper wasn't a "program" per se. It was a database language based on xBase and was compatible with dBase databases. You could use Clipper to create applications and executables. – Icemanind Dec 16 '14 at 21:22

2 Answers2

1

Paths in the Clipper library may be open or closed. You simply indicate whether the supplied paths are open or closed through the Closed parameter in the Clipper object's AddPath method. If all the paths are closed then you can be assured that all the paths in the clipping solution will be closed too.

      Path s = new Path();
      s.Add(new IntPoint(10, 40));
      s.Add(new IntPoint(40, 40));
      s.Add(new IntPoint(50, 10));
      s.Add(new IntPoint(60, 40));
      s.Add(new IntPoint(90, 40));
      s.Add(new IntPoint(65, 60));
      s.Add(new IntPoint(75, 90));
      s.Add(new IntPoint(50, 70));
      s.Add(new IntPoint(25, 90));
      s.Add(new IntPoint(35, 60));

      Path c = new Path();
      c.Add(new IntPoint(49, 0));
      c.Add(new IntPoint(51, 0));
      c.Add(new IntPoint(51, 100));
      c.Add(new IntPoint(49, 100));

      Paths solution = new Paths();
      Clipper cpr = new Clipper();
      cpr.AddPath(s, PolyType.ptSubject, true);
      cpr.AddPath(c, PolyType.ptClip, true);
      cpr.Execute(ClipType.ctDifference, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);                   
Angus Johnson
  • 4,565
  • 2
  • 26
  • 28
  • Thanks for your response Angus! I am afraid I may not have phrased my question very well, though. – RoaringTide Dec 17 '14 at 02:22
  • As an example, I would like to have a subj rect from 10,10 to 40,40 and a clip rect of 20,0 to 25,50. After the execute, I would like a solution with 2 open paths (25,10), (40,10), (40,40), (25,40) and (20,40), (20,10), (10,10), (20,10). In other words, the clip rect trims the subj and the open paths are what is left of the subj. I tried specifying the subj as open, but then it loses the last segment before the first point of the subj. – RoaringTide Dec 17 '14 at 02:40
  • If you start with closed paths (as in your subject and clip rectangles above) then you won't/can't get open paths from the solution. You'll have to open the paths in the solution yourself. – Angus Johnson Dec 17 '14 at 02:47
  • Thanks Angus - I will give it a try. BTW - Clipper is awesome! – RoaringTide Dec 17 '14 at 03:12
  • Do I understand correctly, that it is not possible using Clipper to achieve a solution as outlined in RoaringTides's example above? Clipping two overlapping closed rectangles can not produce an open path solution? "You'll have to open the paths in the solution yourself", Is this done using additional Clipper functions, or completely in C# using some kind of graphicspath/region clip method? – George Aslanis Aug 02 '16 at 18:17
1

A better workaround is to convert them into open paths and appending the first vertex. You can then handle them as open paths while they still signify the same polyline. This way you don't have the overhead of traversing the polygons again.

Tim Kuipers
  • 1,705
  • 2
  • 16
  • 26