// jsClipper uses X/Y instead of x/y... function toClipperCoordinates(polygon){ var clone = []; for(var i=0; i 0){ rotated.children = []; for(var j=0; j 0){ var placed = []; var placements = []; fitness += 1; // add 1 for each new bin opened (lower fitness is better) for(i=0; i 2 && area > 0.1*self.config.clipperScale*self.config.clipperScale){ clipper.AddPath(clone, ClipperLib.PolyType.ptSubject, true); } } } if(!clipper.Execute(ClipperLib.ClipType.ctUnion, combinedNfp, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero)){ continue; } // difference with bin polygon var finalNfp = new ClipperLib.Paths(); clipper = new ClipperLib.Clipper(); clipper.AddPaths(combinedNfp, ClipperLib.PolyType.ptClip, true); clipper.AddPaths(clipperBinNfp, ClipperLib.PolyType.ptSubject, true); if(!clipper.Execute(ClipperLib.ClipType.ctDifference, finalNfp, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero)){ continue; } finalNfp = ClipperLib.Clipper.CleanPolygons(finalNfp, 0.0001*self.config.clipperScale); for(j=0; j= 0){ paths.splice(index,1); } } if(placements && placements.length > 0){ allplacements.push(placements); } else{ break; // something went wrong } } // there were parts that couldn't be placed fitness += 2*paths.length; return {placements: allplacements, fitness: fitness, paths: paths, area: binarea }; }; } (typeof window !== 'undefined' ? window : self).PlacementWorker = PlacementWorker; // clipperjs uses alerts for warnings function alert(message) { console.log('alert: ', message); }