typemytype / booleanOperations

Boolean operations on paths
MIT License
38 stars 18 forks source link

fails dramatically #48

Closed typemytype closed 5 years ago

typemytype commented 5 years ago
<?xml version="1.0" encoding="UTF-8"?>
<glyph name="A" format="2">
  <advance width="500"/>
  <outline>
    <contour>
      <point x="100" y="700" type="line"/>
      <point x="500" y="700" type="line"/>
      <point x="100" y="900" type="line"/>
      <point x="500" y="500" type="line"/>
    </contour>
  </outline>
</glyph>

the contour is gone after a boolean operation

typemytype commented 5 years ago

the area is zero here in this case...

anthrotype commented 5 years ago

ouch

anthrotype commented 5 years ago

@typemytype I forgot why did we do that?

typemytype commented 5 years ago

real zero area paths cause errors later on, did test yet with such a path.

anthrotype commented 5 years ago

by real zero area paths, perhaps you mean a closed path with all the points on top of each other?

justvanrossum commented 5 years ago

by real zero area paths, perhaps you mean a closed path with all the points on top of each other?

I think rather situations like:

pen.moveTo((100, 100))
pen.lineTo((300, 300))
pen.closePath()
typemytype commented 5 years ago

real zero area paths are paths with no visible fill, could be all points on top, could be like Justs example.

the case above should return something ;) and definitely not ignore the contour

typemytype commented 5 years ago

some cases and a narrowed down fix below, used in the PR

<?xml version="1.0" encoding="UTF-8"?>
<glyph name="A" format="2">
  <advance width="500"/>
  <outline>
    <contour>
      <point x="100" y="700" type="line"/>
      <point x="500" y="700" type="line"/>
      <point x="100" y="920" type="line"/>
      <point x="500" y="500" type="line"/>
    </contour>
    <contour>
      <point x="299" y="1003" type="move"/>
      <point x="591" y="1030" type="line"/>
    </contour>
    <contour>
      <point x="460" y="943" type="line"/>
      <point x="605" y="958" type="line"/>
    </contour>
    <contour>
      <point x="103.0" y="1018" type="line"/>
      <point x="103.0" y="1018" type="line"/>
    </contour>
    <contour>
      <point x="103.0" y="1018" type="line"/>
      <point x="103.0" y="1018" type="line"/>
      <point x="103.0" y="1018" type="line"/>
      <point x="103.0" y="1018" type="line"/>
      <point x="103.0" y="1018" type="line"/>
    </contour>
  </outline>
</glyph>

import pyclipper

glyph = CurrentGlyph()

subjectContours = []
for contour in glyph:
    subjectContours.append([(p.x, p.y) for p in contour.points])
    r = pyclipper.Area(subjectContours[-1])
    print(r)

pc = pyclipper.Pyclipper()
for subjectContour in subjectContours:
    try:
        pc.AddPath(subjectContour, pyclipper.PT_SUBJECT)
    except pyclipper.ClipperException:
        pass

r = pc.Execute(pyclipper.CT_UNION, pyclipper.PFT_NONZERO, pyclipper.PFT_NONZERO)

print(r)
anthrotype commented 5 years ago

Fixed by #51