public static IntPoint CenterOfMass(this Polygon polygon) { #if true IntPoint center = new IntPoint(); for (int positionIndex = 0; positionIndex < polygon.Count; positionIndex++) { center += polygon[positionIndex]; } center /= polygon.Count; return(center); #else double x = 0, y = 0; IntPoint prevPosition = polygon[polygon.Count - 1]; for (int positionIndex = 0; positionIndex < polygon.Count; positionIndex++) { IntPoint currentPosition = polygon[positionIndex]; double crossProduct = (prevPosition.X * currentPosition.Y) - (prevPosition.Y * currentPosition.X); x += (double)(prevPosition.X + currentPosition.X) * crossProduct; y += (double)(prevPosition.Y + currentPosition.Y) * crossProduct; prevPosition = currentPosition; } double area = Clipper.Area(polygon); x = x / 6 / area; y = y / 6 / area; return(new IntPoint(x, y)); #endif }
public Floor Build(InDoorGeneratorSettings settings) { var intFootPrint = settings.ObjectPool.NewList <IntPoint>(settings.Footprint.Count); for (int i = 0; i < settings.Footprint.Count; i++) { var point = settings.Footprint[i]; intFootPrint.Add(new IntPoint(point.X * Scale, point.Y * Scale)); } // return null if footprint area is too small if (Clipper.Area(intFootPrint) < MinArea) { return(null); } var floor = new Floor(settings.ObjectPool); var walls = CreateWalls(settings); InsertEntrances(settings, floor, walls); List <List <IntPoint> > transitPolygons; var connectedWalls = CreateConnectedAndTransit(settings, walls, out transitPolygons); var transitArea = CreateTransitArea(settings, floor, walls, transitPolygons); CreateApartments(settings, floor, intFootPrint, transitArea, connectedWalls); return(floor); }
bool IsSmallerThanMinimumArea(List <IntPoint> polygon) { var area = Parameters.minimumPolygonArea * (PlacementUtility.UpScaleFactor * PlacementUtility.UpScaleFactor); return(Math.Abs(Clipper.Area(polygon)) < area); }
private void UpdatePlayerOverlap() { if (CurrentOnsetDrawing == _collidedBeatIndex || CurrentOnset >= Onsets.Count) { ParentStage.Overlap = 0; return; } var c = new Clipper(); c.AddPaths(_onsetDrawing.GetPolygonBounds(CurrentOnsetDrawing), PolyType.ptSubject, true); if (CurrentOnsetDrawing < _onsetDrawing.DrawingCount - 1) { c.AddPaths(_onsetDrawing.GetPolygonBounds(CurrentOnsetDrawing + 1), PolyType.ptSubject, true); } c.AddPath(Player.GetBounds(), PolyType.ptClip, true); var soln = new List <List <IntPoint> >(); c.Execute(ClipType.ctIntersection, soln); //ParentStage.Overlap = soln.Count > 0 ? (int)((Clipper.Area(soln[0]) / Clipper.Area(Player.GetBounds())) * 100) : 0; ParentStage.Overlap = 0; foreach (var a in soln) { ParentStage.Overlap += (int)((Clipper.Area(a) / Clipper.Area(Player.GetBounds())) * (100.0f)); } if (ParentStage.Overlap > 80) { ParentStage.Multiplier = -1; Player.Hits++; _collidedBeatIndex = CurrentOnsetDrawing; //_polygons[_collidedBeatIndex].SetColour(_colours.EvenCollisionColour, _colours.EvenCollisionOutlineColour, _colours.OddCollisionColour, _colours.OddCollisionOutlienColour); CenterPolygon.SetColour(_colours.EvenCollisionColour, _colours.EvenCollisionOutlineColour, _colours.OddCollisionColour, _colours.OddCollisionOutlienColour); } }
public static bool AlmostRectangle(Ngon target, double percent_diff = 0.05) { IntRect bounds = GetBounds(target); double area = Math.Abs(Clipper.Area(target)); return(1.0 - area / bounds.Area() < percent_diff); }
public static void Prune(this PolyNode polyTree, double actorRadius, double areaPruneThreshold = kMinAreaPrune) { var cleaned = Clipper.CleanPolygon(polyTree.Contour, actorRadius / 5 + 2); if (cleaned.Count > 0) { polyTree.Contour.Clear(); polyTree.Contour.AddRange(cleaned); } for (var i = polyTree.Childs.Count - 1; i >= 0; i--) { var child = polyTree.Childs[i]; var childArea = Math.Abs(Clipper.Area(child.Contour)); if (childArea < areaPruneThreshold) { // Console.WriteLine("Prune: " + Clipper.Area(child.Contour) + " " + child.Contour.Count); polyTree.Childs.RemoveAt(i); continue; } var kMinimumChildRelativeArea = 1 / 1000.0; // prev 1 / 1000, 1 / 1000000 child.Prune(actorRadius, Math.Max(kMinAreaPrune, childArea * kMinimumChildRelativeArea)); } }
protected override bool Condition(Func <double> random, Myre.Collections.INamedDataCollection metadata, IReadOnlyList <Vector2> footprint, IReadOnlyList <Vector2> basis) { var area = Area.SelectFloatValue(random, metadata); const int SCALE = 1000; var measuredArea = Math.Abs(Clipper.Area(footprint.Select(a => new IntPoint((int)(a.X * SCALE), (int)(a.Y * SCALE))).ToList())) / (SCALE * SCALE); return(measuredArea > area); }
public Shape(List <Vector2> points) { m_vectorPoints = points; if (Clipper.Area(ToInt(points)) < 0) { points.Reverse(); } this.points = new List <List <IntPoint> >(1); this.points.Add(ToInt(points)); }
public float Area() { float area = 0; foreach (var poly in Clipper.PolyTreeToPaths(polyTree)) { area += (float)Clipper.Area(poly); } return(area); }
private double PathsArea(CPaths P) { double area = 0.0; foreach (CPath path in P) { area += Clipper.Area(path); } return(area); }
public double FitnessFunctionG() { // return 3; double fitnessFunctionVar = 0; int precision = 100; Clipper cc = new ClipperLib.Clipper(); Paths solution = new Paths(); Paths subjects = new Paths(); Paths clips = new Paths(); foreach (Room room in collection) { subjects.Add(new Path(room.GetClipperLibPath(precision))); } IntPoint boundaryA = new IntPoint( (int)((boundary.GetBoundingBox(false).Center.X - boundary.GetBoundingBox(false).Diagonal.X / 2) * precision) , (int)((boundary.GetBoundingBox(false).Center.Y - boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision)); IntPoint boundaryB = new IntPoint( (int)((boundary.GetBoundingBox(false).Center.X - boundary.GetBoundingBox(false).Diagonal.X / 2) * precision) , (int)((boundary.GetBoundingBox(false).Center.Y + boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision)); IntPoint boundaryC = new IntPoint( (int)((boundary.GetBoundingBox(false).Center.X + boundary.GetBoundingBox(false).Diagonal.X / 2) * precision) , (int)((boundary.GetBoundingBox(false).Center.Y + boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision)); IntPoint boundaryD = new IntPoint( (int)((boundary.GetBoundingBox(false).Center.X + boundary.GetBoundingBox(false).Diagonal.X / 2) * precision) , (int)((boundary.GetBoundingBox(false).Center.Y - boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision)); clips.Add(new Path(new List <IntPoint>() { boundaryA, boundaryB, boundaryC, boundaryD })); cc.AddPaths(subjects, PolyType.ptSubject, true); cc.AddPaths(clips, PolyType.ptClip, true); cc.Execute(ClipType.ctIntersection, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); foreach (Path path in solution) { fitnessFunctionVar += Clipper.Area(path); } return(fitnessFunctionVar); }
double Intersection(List <IntPoint> polygon, Municipality municipality) { Clipper c = new Clipper(); c.AddPolygon(polygon, PolyType.ptSubject); c.AddPolygon(municipality.polygon, PolyType.ptClip); List <List <IntPoint> > solution = new List <List <IntPoint> >(); c.Execute(ClipType.ctIntersection, solution); return(solution.Sum(s => Clipper.Area(s))); }
private List <Vector2[]> IntListsToVector2(Paths paths) { List <Vector2[]> verticesList = new List <Vector2[]>(paths.Count); for (int i = 0; i < paths.Count; i++) { if (Mathf.Abs((float)Clipper.Area(paths[i])) > ignoreArea) { verticesList.Add(IntListToVector2(paths[i])); } } return(verticesList); }
// todo clearly define what equal means: cm difference in height+width maximal public static bool EqualWithinEpsilon(Polygon a, Polygon b, double epsilon = (.01 * Vector.Scale * .01 * Vector.Scale)) { PolygonList intersections = Intersection(a, b); if (intersections.Count != 1) { return(false); } double intersectionArea = Clipper.Area(intersections[0]); return((Math.Abs(intersectionArea - Clipper.Area(a)) < epsilon) && (Math.Abs(intersectionArea - Clipper.Area(b)) < epsilon)); }
public double GetIntersectionArea() { var resultPolygons = new List <List <IntPoint> >(); TheClipper.Execute(ClipType.ctIntersection, resultPolygons, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); double area = 0; resultPolygons.ForEach(poly => area += Clipper.Area(poly)); //Теперь у нас есть площадь, рассчитанная для сетки, увеличенной в CUPUU в квадрате раз //Разделим ее на это число - получим настоящую площадь double originalArea = area / (ClipperUnitsPerUnityUnit * ClipperUnitsPerUnityUnit); return(originalArea); }
protected override void OnUpdate() { var polygons = PolygonsFromRoadOutline(Parameters.extensionDistance); var clipper = new Clipper(); foreach (var polygon in polygons) { if (!Clipper.Orientation(polygon)) { polygon.Reverse(); } if (Clipper.Area(polygon) > 0) { clipper.AddPath(polygon, PolyType.ptSubject, true); } } var solution = new List <List <IntPoint> >(); clipper.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); solution.RemoveAll(IsSmallerThanMinimumArea); if (solution.Count == 0 && polygons.Count != 0) { throw new Exception($"Unable to create a polygon from " + $"{Parameters.roadNetworkDescription.name}"); } foreach (var polygon in solution) { var pathEntity = EntityManager.CreateEntity(m_SamplesArchetype); var orientation = Clipper.Orientation(polygon) ? PolygonOrientation.Outside : PolygonOrientation.Inside; var pathSamplesBuffer = EntityManager.GetBuffer <PointSampleGlobal>(pathEntity).Reinterpret <RigidTransform>(); var placementPathSamples = PlacementUtility.IntPointsToRigidTransforms(polygon, true, Allocator.TempJob); pathSamplesBuffer.AddRange(placementPathSamples); placementPathSamples.Dispose(); EntityManager.SetComponentData(pathEntity, new PolygonOrientationComponent { Orientation = orientation }); } }
/// <summary> /// Return 1 if ccw -1 if cw /// </summary> /// <param name="polygon"></param> /// <returns></returns> public static int GetWindingDirection(this Polygon polygon) { var clipper = Clipper.Area(polygon); if (clipper > 0) { return(1); } else if (clipper < 0 - 1) { return(-1); } return(0); }
private MeshRegion CreateMeshRegions(Path clipRect, MeshCanvas.Region region, RenderMode renderMode, ref Rectangle2d rect, bool useContours = false) { using (var polygon = new Polygon(256, _objectPool)) { var simplifiedPath = ClipByRectangle(clipRect, region.Shape); var contours = new List <List <Point> >(useContours ? simplifiedPath.Count : 0); foreach (var path in simplifiedPath) { var area = Clipper.Area(path); // skip small polygons to prevent triangulation issues if (Math.Abs(area / DoubleScale) < 0.001) { continue; } var vertices = GetVertices(path, renderMode, ref rect); // sign of area defines polygon orientation polygon.AddContour(vertices, area < 0); if (useContours) { contours.Add(vertices); } } contours.ForEach(c => c.Reverse()); var mesh = polygon.Points.Any() ? GetMesh(polygon, renderMode) : null; return(new MeshRegion { GradientKey = region.GradientKey, ElevationNoiseFreq = region.ElevationNoiseFreq, ColorNoiseFreq = region.ColorNoiseFreq, ModifyMeshAction = region.ModifyMeshAction, Mesh = mesh, Contours = contours }); } }
//将自相交多边形转化为简单多边形 public static NestPath cleanNestPath(NestPath srcPath) { /** * Convert NestPath 2 Clipper */ Path path = CommonUtil.NestPath2Path(srcPath); Paths simple = Clipper.SimplifyPolygon(path, PolyFillType.pftEvenOdd); if (simple.Count == 0) { return(null); } Path biggest = simple[0]; double biggestArea = Math.Abs(Clipper.Area(biggest)); for (int i = 0; i < simple.Count; i++) { double area = Math.Abs(Clipper.Area(simple[i])); if (area > biggestArea) { biggest = simple[i]; biggestArea = area; } } //Path clean = biggest.Cleaned(Config.CURVE_TOLERANCE * Config.CLIIPER_SCALE); Path clean = Clipper.CleanPolygon(biggest, Config.CURVE_TOLERANCE * Config.CLIIPER_SCALE); if (clean.Count == 0) { return(null); } /** * Convert Clipper 2 NestPath */ NestPath cleanPath = CommonUtil.Path2NestPath(clean); cleanPath.bid = srcPath.bid; cleanPath.setRotation(srcPath.rotation); return(cleanPath); }
public double ComputeArea() { if (SubPolygons.Count == 0) { return(Polygon.GetArea()); } Clipper c = new Clipper(); Path polyPath = new Path(); foreach (Point2 point in Polygon.Points) { polyPath.Add(new IntPoint(point.X, point.Y)); } c.AddPath(polyPath, PolyType.ptSubject, true); foreach (Polygon poly in SubPolygons) { polyPath = new Path(); foreach (Point2 point in poly.Points) { polyPath.Add(new IntPoint(point.X, point.Y)); } c.AddPath(polyPath, PolyType.ptSubject, true); } Paths solution = new Paths(); c.Execute(ClipType.ctXor, solution, PolyFillType.pftEvenOdd); double clipperArea = 0.0; foreach (Path p in solution) { clipperArea += Clipper.Area(p); } return(clipperArea); }
private double calcCoverage(List <IntPoint> subject, List <IntPoint> clipping) { var clipper = new Clipper(); clipper.StrictlySimple = true; var solution = new List <List <IntPoint> >(); clipper.AddPath(subject, PolyType.ptSubject, true); clipper.AddPath(clipping, PolyType.ptClip, true); if (clipper.Execute(ClipType.ctIntersection, solution) == false || solution.Count != 1) { return(0); } var areaIntersection = Clipper.Area(solution[0]); var areaSubject = Clipper.Area(subject); return(areaIntersection / areaSubject); }
private static void CreateApartments(InDoorGeneratorSettings settings, Floor floor, List <IntPoint> footprint, List <List <IntPoint> > transitArea, List <Wall> connected) { var extrudedPolygons = new List <List <IntPoint> >(4); settings.Clipper.AddPaths(transitArea, PolyType.ptClip, true); settings.Clipper.AddPath(footprint, PolyType.ptSubject, true); settings.Clipper.Execute(ClipType.ctDifference, extrudedPolygons); settings.Clipper.Clear(); //SVGBuilder.SaveToFile(extrudedPolygons, "regions_ex.svg", 0.01, 100); foreach (var extrudedPolygon in extrudedPolygons) { // Clipper may produce small polygons on building offsets if (Clipper.Area(extrudedPolygon) / DoubleScale < settings.MinimalArea) { continue; } var firstOuterWallIndex = InvalidIndex; var firstTransitWallIndex = InvalidIndex; var outerWallCount = 0; double outerWallLength = 0; var extrudedWalls = new List <Wall>(); var lastItemIndex = extrudedPolygon.Count - 1; var mergePoint = Vector2d.Empty; double skippedDistance = 0; for (var i = 0; i <= lastItemIndex; i++) { var start = extrudedPolygon[i]; var end = extrudedPolygon[i == lastItemIndex ? 0 : i + 1]; var isOuterWall = ClipperUtils.CalcMinDistance(start, footprint) < IntPrecisionError && ClipperUtils.CalcMinDistance(end, footprint) < IntPrecisionError; var p1 = new Vector2d(start.X / Scale, start.Y / Scale); var p2 = new Vector2d(end.X / Scale, end.Y / Scale); // NOTE this allows to skip artifacts of clipper offset library // which I don't know to avoid by clipper API. var distance = p1.DistanceTo(p2); if (distance < settings.HalfTransitAreaWidth && skippedDistance < settings.TransitAreaWidth) { skippedDistance += distance; if (mergePoint != Vector2d.Empty) { continue; } mergePoint = p1; continue; } if (mergePoint != Vector2d.Empty) { p1 = mergePoint; mergePoint = Vector2d.Empty; skippedDistance = 0; } if (isOuterWall) { outerWallCount++; outerWallLength += ClipperUtils.Distance(start, end) / Scale; if (firstOuterWallIndex == InvalidIndex) { firstOuterWallIndex = extrudedWalls.Count; } } if (!isOuterWall && firstTransitWallIndex == InvalidIndex) { firstTransitWallIndex = extrudedWalls.Count; } extrudedWalls.Add(new Wall(p1, p2, isOuterWall)); } firstOuterWallIndex = firstOuterWallIndex != 0 ? firstOuterWallIndex : firstTransitWallIndex + extrudedWalls.Count - outerWallCount; var context = new FloorContext(outerWallCount, extrudedWalls.Count - outerWallCount, firstOuterWallIndex, firstTransitWallIndex); CreateAparments(settings, floor, context, extrudedWalls, connected, outerWallLength); } }
/** * 根据板件列表与旋转角列表,通过nfp,计算板件在底板上的位置,并返回这个种群的fitness * @param paths * @return */ public Result placePaths(List <NestPath> paths) { List <NestPath> rotated = new List <NestPath>(); for (int i = 0; i < paths.Count; i++) { NestPath r = GeometryUtil.rotatePolygon2Polygon(paths[i], paths[i].getRotation()); r.setRotation(paths[i].getRotation()); r.setSource(paths[i].getSource()); r.setId(paths[i].getId()); rotated.Add(r); } paths = rotated; List <List <Vector> > allplacements = new List <List <Vector> >(); double fitness = 0; double binarea = Math.Abs(GeometryUtil.polygonArea(this.binPolygon)); String key = null; List <NestPath> nfp = null; while (paths.Count > 0) { List <NestPath> placed = new List <NestPath>(); List <Vector> placements = new List <Vector>(); fitness += 1; double minwidth = Double.MaxValue; for (int i = 0; i < paths.Count; i++) { NestPath path = paths[i]; //inner NFP key = new JavaScriptSerializer().Serialize(new NfpKey(-1, path.getId(), true, 0, path.getRotation())); //key = gson.toJson(new NfpKey(-1, path.getId(), true, 0, path.getRotation())); if (!nfpCache.ContainsKey(key)) { continue; } List <NestPath> binNfp = nfpCache[key]; // ensure exists bool error = false; for (int j = 0; j < placed.Count; j++) { key = new JavaScriptSerializer().Serialize(new NfpKey(placed[j].getId(), path.getId(), false, placed[j].getRotation(), path.getRotation())); // key = gson.toJson(new NfpKey(placed[j].getId(), path.getId(), false, placed[j].getRotation(), path.getRotation())); if (nfpCache.ContainsKey(key)) { nfp = nfpCache[key]; } else { error = true; break; } } if (error) { continue; } Vector position = null; if (placed.Count == 0) { // first placement , put it on the lefth for (int j = 0; j < binNfp.Count; j++) { for (int k = 0; k < binNfp[j].size(); k++) { if (position == null || binNfp[j].get(k).x - path.get(0).x < position.x) { position = new Vector( binNfp[j].get(k).x - path.get(0).x, binNfp[j].get(k).y - path.get(0).y, path.getId(), path.getRotation() ); } } } placements.Add(position); placed.Add(path); continue; } Paths clipperBinNfp = new Paths(); for (int j = 0; j < binNfp.Count; j++) { NestPath binNfpj = binNfp[j]; clipperBinNfp.Add(scaleUp2ClipperCoordinates(binNfpj)); } Clipper clipper = new Clipper(); Paths combinedNfp = new Paths(); for (int j = 0; j < placed.Count; j++) { key = new JavaScriptSerializer().Serialize(new NfpKey(placed[j].getId(), path.getId(), false, placed[j].getRotation(), path.getRotation())); //key = gson.toJson(new NfpKey(placed[j].getId(), path.getId(), false, placed[j].getRotation(), path.getRotation())); nfp = nfpCache[key]; if (nfp == null) { continue; } for (int k = 0; k < nfp.Count; k++) { Path clone = PlacementWorker.scaleUp2ClipperCoordinates(nfp[k]); for (int m = 0; m < clone.Count; m++) { long clx = (long)clone[m].X; long cly = (long)clone[m].Y; IntPoint intPoint = clone[m]; intPoint.X = (clx + (long)(placements[j].x * Config.CLIIPER_SCALE)); intPoint.Y = (cly + (long)(placements[j].y * Config.CLIIPER_SCALE)); clone[m] = intPoint; } //clone = clone.Cleaned(0.0001 * Config.CLIIPER_SCALE); clone = Clipper.CleanPolygon(clone, 0.0001 * Config.CLIIPER_SCALE); double areaPoly = Math.Abs(Clipper.Area(clone)); if (clone.Count > 2 && areaPoly > 0.1 * Config.CLIIPER_SCALE * Config.CLIIPER_SCALE) { clipper.AddPath(clone, PolyType.ptSubject, true); } } } if (!clipper.Execute(ClipType.ctUnion, combinedNfp, PolyFillType.pftNonZero, PolyFillType.pftNonZero)) { continue; } //difference with bin polygon Paths finalNfp = new Paths(); clipper = new Clipper(); clipper.AddPaths(combinedNfp, PolyType.ptClip, true); clipper.AddPaths(clipperBinNfp, PolyType.ptSubject, true); if (!clipper.Execute(ClipType.ctDifference, finalNfp, PolyFillType.pftNonZero, PolyFillType.pftNonZero)) { continue; } // finalNfp = finalNfp.Cleaned(0.0001 * Config.CLIIPER_SCALE); finalNfp = Clipper.CleanPolygons(finalNfp, 0.0001 * Config.CLIIPER_SCALE); for (int j = 0; j < finalNfp.Count(); j++) { //double areaPoly = Math.Abs(finalNfp[j].Area); double areaPoly = Math.Abs(Clipper.Area(finalNfp[j])); if (finalNfp[j].Count < 3 || areaPoly < 0.1 * Config.CLIIPER_SCALE * Config.CLIIPER_SCALE) { finalNfp.RemoveAt(j); j--; } } if (finalNfp == null || finalNfp.Count == 0) { continue; } List <NestPath> f = new List <NestPath>(); for (int j = 0; j < finalNfp.Count; j++) { f.Add(toNestCoordinates(finalNfp[j])); } List <NestPath> finalNfpf = f; double minarea = Double.MinValue; double minX = Double.MaxValue; NestPath nf = null; double area = Double.MinValue; Vector shifvector = null; for (int j = 0; j < finalNfpf.Count; j++) { nf = finalNfpf[j]; if (Math.Abs(GeometryUtil.polygonArea(nf)) < 2) { continue; } for (int k = 0; k < nf.size(); k++) { NestPath allpoints = new NestPath(); for (int m = 0; m < placed.Count; m++) { for (int n = 0; n < placed[m].size(); n++) { allpoints.add(new Segment(placed[m].get(n).x + placements[m].x, placed[m].get(n).y + placements[m].y)); } } shifvector = new Vector(nf.get(k).x - path.get(0).x, nf.get(k).y - path.get(0).y, path.getId(), path.getRotation(), combinedNfp); for (int m = 0; m < path.size(); m++) { allpoints.add(new Segment(path.get(m).x + shifvector.x, path.get(m).y + shifvector.y)); } Bound rectBounds = GeometryUtil.getPolygonBounds(allpoints); area = rectBounds.getWidth() * 2 + rectBounds.getHeight(); if (minarea == Double.MinValue || area < minarea || (GeometryUtil.almostEqual(minarea, area) && (minX == Double.MinValue || shifvector.x < minX))) { minarea = area; minwidth = rectBounds.getWidth(); position = shifvector; minX = shifvector.x; } } } if (position != null) { placed.Add(path); placements.Add(position); } } if (minwidth != Double.MinValue) { fitness += minwidth / binarea; } for (int i = 0; i < placed.Count; i++) { int index = paths.IndexOf(placed[i]); if (index >= 0) { paths.RemoveAt(index); } } if (placements != null && placements.Count > 0) { allplacements.Add(placements); } else { break; // something went wrong } } // there were paths that couldn't be placed fitness += 2 * paths.Count; return(new Result(allplacements, fitness, paths, binarea)); }
public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica) { if (parametricObject == null || !parametricObject.isActive) { return(null); } if (P_PrototypePlan == null || P_Prototype == null) { return(null); } preGenerate(); // PLAN planSrc_p = P_Plan.DependsOn; // getUpstreamSourceParameter(P_Plan); planSrc_po = (planSrc_p != null) ? planSrc_p.parametricObject : null; P_Plan.polyTree = null; AXShape.thickenAndOffset(ref P_Plan, planSrc_p); planPaths = P_Plan.getPaths(); if (planPaths == null || planPaths.Count == 0) { return(null); } prototypePlanSrc_p = P_PrototypePlan.DependsOn; prototypePlanSrc_po = (prototypePlanSrc_p != null) ? prototypePlanSrc_p.parametricObject : null; prototypeSrc_p = P_Prototype.DependsOn; prototypePlanSrc_po = (prototypeSrc_p != null) ? prototypeSrc_p.parametricObject : null; if (prototypePlanSrc_p == null || prototypePlanSrc_po == null || prototypeSrc_po == null) { return(null); } AXParameter srcSrc_p = prototypePlanSrc_p.DependsOn; if (srcSrc_p == null) { return(null); } // AX_MESHES List <AXMesh> ax_meshes = new List <AXMesh>(); GameObject go = null; if (makeGameObjects && !parametricObject.combineMeshes) { go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject); } Perlin perlin = new Perlin(); perlin.OctaveCount = 1; perlin.Frequency = .05f; GameObject replicant = null; foreach (Path plan in planPaths) { // 1. cache source object //prototypeSrc_po.cacheParameterValues(); Paths tmpPaths = new Paths(); tmpPaths.Add(plan); IntPoint planCenter = AXGeometryTools.Utilities.getCenter(tmpPaths); Vector3 centerPt = AXGeometryTools.Utilities.IntPt2Vec3(planCenter); //Debug.Log("Center: " + centerPt); srcSrc_p.paths = tmpPaths; float area = ((float)Clipper.Area(plan)) / 1000000000; //Debug.Log(area); float perlinVal = (float)perlin.GetValue(centerPt); float h = 3 + 100 * (float)Math.Exp(-(.1f * area)) + 5 * perlinVal; // (float) perlin.GetValue(2,3,4); AXParameter sHeight = prototypeSrc_po.getParameter("Height"); sHeight.initiateRipple_setFloatValueFromGUIChange(h); prototypeSrc_po.generator.pollControlValuesFromParmeters(); prototypeSrc_po.isAltered = true; replicant = prototypeSrc_po.generateOutputNow(makeGameObjects, parametricObject, true); if (replicant != null) { replicant.transform.parent = go.transform; } AXParameter output_p = prototypeSrc_po.getParameter("Output Mesh"); foreach (AXMesh amesh in output_p.meshes) { ax_meshes.Add(amesh.Clone(amesh.transMatrix)); } } // FINISH AX_MESHES parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica); if (makeGameObjects) { return(go); } return(null); }
//--------------------------------------------------------------------------- private void DrawBitmap(bool justClip = false) { Cursor.Current = Cursors.WaitCursor; try { if (!justClip) { //GenerateRandomPolygon(10); //GenerateTestPolygon(4); } using (Graphics newgraphic = Graphics.FromImage(mybitmap)) using (GraphicsPath path = new GraphicsPath()) { newgraphic.SmoothingMode = SmoothingMode.AntiAlias; newgraphic.Clear(Color.White); if (rbNonZero.Checked) { path.FillMode = FillMode.Winding; } //draw subjects ... foreach (Polygon pg in subjects) { PointF[] pts = PolygonToPointFArray(pg, scale); path.AddPolygon(pts); pts = null; } using (Pen myPen = new Pen(Color.FromArgb(196, 0xC3, 0xC9, 0xCF), (float)0.6)) using (SolidBrush myBrush = new SolidBrush(Color.FromArgb(127, 0xDD, 0xDD, 0xF0))) { newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); path.Reset(); //draw clips ... if (rbNonZero.Checked) { path.FillMode = FillMode.Winding; } foreach (Polygon pg in clips) { PointF[] pts = PolygonToPointFArray(pg, scale); path.AddPolygon(pts); pts = null; } myPen.Color = Color.FromArgb(196, 0xF9, 0xBE, 0xA6); myBrush.Color = Color.FromArgb(127, 0xFF, 0xE0, 0xE0); newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); //do the clipping ... if ((clips.Count > 0 || subjects.Count > 0) && !rbNone.Checked) { Polygons solution2 = new Polygons(); Clipper c = new Clipper(); c.AddPaths(subjects, PolyType.ptSubject, true); c.AddPaths(clips, PolyType.ptClip, true); solution.Clear(); //my codes ... bool succeeded = c.Execute(GetClipType(), solution, GetPolyFillType(), GetPolyFillType()); PrintVertice(solution); //if (rbIntersect.Checked) // Console.WriteLine("****END OF INTERSECT****"); //if (rbUnion.Checked) // Console.WriteLine("****END OF UNION****"); //if (rbDifference.Checked) // Console.WriteLine("****END OF DIFFERENCE****"); //else // Console.WriteLine("****END OF XOR****"); Tuple <List <List <IntPoint> >, List <List <IntPoint> >, List <List <IntPoint> > > testTuple; testTuple = PushPolygonToArray(subjects, clips); //my codes ... if (succeeded) { //SaveToFile("solution", solution); myBrush.Color = Color.Black; path.Reset(); //It really shouldn't matter what FillMode is used for solution //polygons because none of the solution polygons overlap. //However, FillMode.Winding will show any orientation errors where //holes will be stroked (outlined) correctly but filled incorrectly ... path.FillMode = FillMode.Winding; //or for something fancy ... if (nudOffset.Value != 0) { ClipperOffset co = new ClipperOffset(); co.AddPaths(solution, JoinType.jtRound, EndType.etClosedPolygon); co.Execute(ref solution2, (double)nudOffset.Value * scale); } else { solution2 = new Polygons(solution); } foreach (Polygon pg in solution2) { PointF[] pts = PolygonToPointFArray(pg, scale); if (pts.Count() > 2) { path.AddPolygon(pts); } pts = null; } myBrush.Color = Color.FromArgb(127, 0x66, 0xEF, 0x7F); myPen.Color = Color.FromArgb(255, 0, 0x33, 0); myPen.Width = 1.0f; newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); //now do some fancy testing ... using (Font f = new Font("Arial", 8)) using (SolidBrush b = new SolidBrush(Color.Navy)) { double subj_area = 0, clip_area = 0, int_area = 0, union_area = 0; c.Clear(); c.AddPaths(subjects, PolyType.ptSubject, true); c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { subj_area += Clipper.Area(pg); } c.Clear(); c.AddPaths(clips, PolyType.ptClip, true); c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { clip_area += Clipper.Area(pg); } c.AddPaths(subjects, PolyType.ptSubject, true); c.Execute(ClipType.ctIntersection, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { int_area += Clipper.Area(pg); } c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { union_area += Clipper.Area(pg); } using (StringFormat lftStringFormat = new StringFormat()) using (StringFormat rtStringFormat = new StringFormat()) { lftStringFormat.Alignment = StringAlignment.Near; lftStringFormat.LineAlignment = StringAlignment.Near; rtStringFormat.Alignment = StringAlignment.Far; rtStringFormat.LineAlignment = StringAlignment.Near; Rectangle rec = new Rectangle(pictureBox1.ClientSize.Width - 108, pictureBox1.ClientSize.Height - 116, 104, 106); newgraphic.FillRectangle(new SolidBrush(Color.FromArgb(196, Color.WhiteSmoke)), rec); newgraphic.DrawRectangle(myPen, rec); rec.Inflate(new Size(-2, 0)); newgraphic.DrawString("Areas", f, b, rec, rtStringFormat); rec.Offset(new Point(0, 14)); newgraphic.DrawString("subj: ", f, b, rec, lftStringFormat); newgraphic.DrawString((subj_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new Point(0, 12)); newgraphic.DrawString("clip: ", f, b, rec, lftStringFormat); newgraphic.DrawString((clip_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new Point(0, 12)); newgraphic.DrawString("intersect: ", f, b, rec, lftStringFormat); newgraphic.DrawString((int_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new Point(0, 12)); newgraphic.DrawString("---------", f, b, rec, rtStringFormat); rec.Offset(new Point(0, 10)); newgraphic.DrawString("s + c - i: ", f, b, rec, lftStringFormat); newgraphic.DrawString(((subj_area + clip_area - int_area) / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new Point(0, 10)); newgraphic.DrawString("---------", f, b, rec, rtStringFormat); rec.Offset(new Point(0, 10)); newgraphic.DrawString("union: ", f, b, rec, lftStringFormat); newgraphic.DrawString((union_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new Point(0, 10)); newgraphic.DrawString("---------", f, b, rec, rtStringFormat); } } } //end if succeeded } //end if something to clip pictureBox1.Image = mybitmap; } } } finally { Cursor.Current = Cursors.Default; } }
public static double Area(this Polygon polygon) { return(Clipper.Area(polygon)); }
void DrawingPanel_Paint(object sender, GUI.PaintEventArgs e) { GUI.Cursor.Current = GUI.Cursors.WaitCursor; Graphics graphics = e.Graphics; SmoothingMode fillSmoothingMode = graphics is SoftwareGraphics ? SmoothingMode.AntiAlias : SmoothingMode.None; SmoothingMode strokeSmoothingMode = SmoothingMode.AntiAlias; graphics.SmoothingMode = fillSmoothingMode; graphics.Clear(Color.White); GraphicsPath path = new GraphicsPath(); if (rbNonZero.IsChecked) { path.FillMode = FillMode.Winding; } //draw subjects ... foreach (Polygon pg in subjects) { Point[] pts = PolygonToPointArray(pg, scale); path.AddPolygon(pts); pts = null; } Pen myPen = new Pen( //Color.FromArgb(196, 0xC3, 0xC9, 0xCF), Color.FromArgb(128, 0, 0, 255), 0.6); SolidColorBrush myBrush = new SolidColorBrush( //Color.FromArgb(127, 0xDD, 0xDD, 0xF0)); //Color.FromArgb(255, 210, 210, 255)); Color.FromArgb(127, Color.LightBlue)); graphics.SmoothingMode = fillSmoothingMode; graphics.FillPath(myBrush, path); graphics.SmoothingMode = strokeSmoothingMode; graphics.DrawPath(myPen, path); path.Reset(); //draw clips ... if (rbNonZero.IsChecked) { path.FillMode = FillMode.Winding; } foreach (Polygon pg in clips) { Point[] pts = PolygonToPointArray(pg, scale); path.AddPolygon(pts); pts = null; } myPen.Color = Color.FromArgb(128, Color.Red); //0xF9, 0xBE, 0xA6); myBrush.Color = //Color.FromArgb(127, 0xFF, 0xE0, 0xE0); Color.FromArgb(50, 255, 0, 0); graphics.SmoothingMode = fillSmoothingMode; graphics.FillPath(myBrush, path); graphics.SmoothingMode = strokeSmoothingMode; graphics.DrawPath(myPen, path); //do the clipping ... if ((clips.Count > 0 || subjects.Count > 0) && !rbNone.IsChecked) { Polygons solution2 = new Polygons(); Clipper c = new Clipper(0); c.AddPaths(subjects, PolyType.ptSubject, true); c.AddPaths(clips, PolyType.ptClip, true); solution.Clear(); bool succeeded = c.Execute(GetClipType(), solution, GetPolyFillType(), GetPolyFillType()); if (succeeded) { myBrush.Color = Color.Black; path.Reset(); //It really shouldn't matter what FillMode is used for solution //polygons because none of the solution polygons overlap. //However, FillMode.Winding will show any orientation errors where //holes will be stroked (outlined) correctly but filled incorrectly ... path.FillMode = FillMode.Winding; //or for something fancy ... if (nudOffset.Value != 0) { //old solution2 = Clipper.OffsetPolygons(solution, (double)nudOffset.Value * scale, JoinType.jtMiter); ClipperOffset co = new ClipperOffset(2, 0.25); co.AddPaths(solution, JoinType.jtMiter, EndType.etClosedPolygon); co.Execute(ref solution2, (double)nudOffset.Value * scale); } else { solution2 = new Polygons(solution); } foreach (Polygon pg in solution2) { Point[] pts = PolygonToPointArray(pg, scale); if (pts.Length//Count() > 2) { path.AddPolygon(pts); } pts = null; } //myBrush.Color = Color.FromArgb(127, 0x66, 0xEF, 0x7F); myBrush.Color = Color.FromArgb(100, 0, 255, 0); myPen.Color = Color.FromArgb(255, 0, 0x33, 0); myPen.Width = 1; graphics.SmoothingMode = fillSmoothingMode; graphics.FillPath(myBrush, path); graphics.SmoothingMode = strokeSmoothingMode; graphics.DrawPath(myPen, path); //now do some fancy testing ... Font f = new Font("Arial", 8); Brush b = Brushes.Navy; double subj_area = 0, clip_area = 0, int_area = 0, union_area = 0; c.Clear(); c.AddPaths(subjects, PolyType.ptSubject, true); c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { subj_area += Clipper.Area(pg); } c.Clear(); c.AddPaths(clips, PolyType.ptClip, true); c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { clip_area += Clipper.Area(pg); } c.AddPaths(subjects, PolyType.ptSubject, true); c.Execute(ClipType.ctIntersection, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { int_area += Clipper.Area(pg); } c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType()); foreach (Polygon pg in solution2) { union_area += Clipper.Area(pg); } StringFormat lftStringFormat = new StringFormat(); lftStringFormat.Alignment = StringAlignment.Near; lftStringFormat.LineAlignment = StringAlignment.Near; StringFormat rtStringFormat = new StringFormat(); rtStringFormat.Alignment = StringAlignment.Far; rtStringFormat.LineAlignment = StringAlignment.Near; RectI rec = new RectI(WorkArea.Width - 114, WorkArea.Height - 116, 104, 106); graphics.FillRectangle(new SolidColorBrush(Color.FromArgb(196, Color.WhiteSmoke)), rec); graphics.DrawRectangle(myPen, rec); rec.Inflate(new SizeI(-2, 0)); // because of Alt.Sketch smaller top offset rec += new PointI(0, 1); rec -= new SizeI(0, 1); graphics.DrawString("Areas", f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 14)); graphics.DrawString("subj: ", f, b, rec, lftStringFormat); graphics.DrawString((subj_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 12)); graphics.DrawString("clip: ", f, b, rec, lftStringFormat); graphics.DrawString((clip_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 12)); graphics.DrawString("intersect: ", f, b, rec, lftStringFormat); graphics.DrawString((int_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 12)); graphics.DrawString("---------", f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 10)); graphics.DrawString("s + c - i: ", f, b, rec, lftStringFormat); graphics.DrawString(((subj_area + clip_area - int_area) / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 10)); graphics.DrawString("---------", f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 10)); graphics.DrawString("union: ", f, b, rec, lftStringFormat); graphics.DrawString((union_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat); rec.Offset(new PointI(0, 10)); graphics.DrawString("---------", f, b, rec, rtStringFormat); } //end if succeeded } //end if something to clip //TEMP pictureBox1.Image = mybitmap; graphics.Dispose(); GUI.Cursor.Current = GUI.Cursors.Default; }
internal float Area() { return((float)Clipper.Area(GetPoints())); }
public string MinimalDXFSave(string outputfile, double offset = 3.0, double holediameter = 3.2) { if (Directory.Exists(outputfile)) { outputfile = Path.Combine(outputfile, "SickOfBeige"); } PolyLine Biggest = null; double BiggestArea = 0; List <PointD> Holes = new List <PointD>(); var holeradius = holediameter / 2.0; double Circumference = 2 * Math.PI * holeradius; foreach (var a in PLSs.Where(x => x.Layer == BoardLayer.Outline)) { foreach (var b in a.OutlineShapes) { var A = b.toPolygon(); double LRatio = (b.OutlineLength() / Circumference); double Lperc = Math.Abs(LRatio - 1); if (Lperc < 0.1) { if (b.Vertices.Count > 5) { var C = b.GetCentroid(); bool round = true; foreach (var v in b.Vertices) { var L = (C - v).Length(); if (Math.Abs(L - holeradius) > 0.2) { // not very round! round = false; } } if (round) { Console.WriteLine("Hole detected in outline:{0} {1} {2} {3} {4} {5}", a.Layer, a.Side, C, LRatio, Lperc, b.Vertices.Count); Holes.Add(C); } } // might be hole! } var Area = Clipper.Area(A); if (Area > BiggestArea) { Biggest = b; BiggestArea = Area; } } } Polygons Offsetted = new Polygons(); List <String> Lines = new List <string>(); Lines.Add("0"); Lines.Add("SECTION"); Lines.Add("2 "); Lines.Add("ENTITIES"); if (Biggest != null) { Polygons clips = new Polygons(); clips.Add(Biggest.toPolygon()); Offsetted = Clipper.OffsetPolygons(clips, offset * 100000.0f, JoinType.jtRound); foreach (var poly in Offsetted) { PolyLine P = new PolyLine(PolyLine.PolyIDs.Temp); P.fromPolygon(poly); for (int i = 0; i < P.Vertices.Count; i++) { var V1 = P.Vertices[i]; var V2 = P.Vertices[(i + 1) % P.Vertices.Count]; Lines.Add("0"); Lines.Add("LINE"); Lines.Add("8"); Lines.Add("Outline"); Lines.Add("10"); Lines.Add(V1.X.ToString().Replace(',', '.')); Lines.Add("20"); Lines.Add(V1.Y.ToString().Replace(',', '.')); Lines.Add("11"); Lines.Add(V2.X.ToString().Replace(',', '.')); Lines.Add("21"); Lines.Add(V2.Y.ToString().Replace(',', '.')); } } } else { Errors.Add("No longest outline found - not generating offset curve"); } foreach (var a in Excellons) { foreach (var t in a.Tools) { var R = t.Value.Radius; if (Math.Abs(R * 2 - holediameter) < 0.05) { foreach (var h in t.Value.Drills) { Holes.Add(h); } } } } foreach (var a in Holes) { for (int i = 0; i < 40; i++) { double P = i * Math.PI * 2.0 / 40.0; double P2 = (i + 1) * Math.PI * 2.0 / 40.0; var C1 = Math.Cos(P) * holeradius; var C2 = Math.Cos(P2) * holeradius; var S1 = Math.Sin(P) * holeradius; var S2 = Math.Sin(P2) * holeradius; double x1 = a.X + C1; double y1 = a.Y + S1; double x2 = a.X + C2; double y2 = a.Y + S2; Lines.Add("0"); Lines.Add("LINE"); Lines.Add("8"); Lines.Add("Holes"); Lines.Add("10"); Lines.Add(x1.ToString().Replace(',', '.')); Lines.Add("20"); Lines.Add(y1.ToString().Replace(',', '.')); Lines.Add("11"); Lines.Add(x2.ToString().Replace(',', '.')); Lines.Add("21"); Lines.Add(y2.ToString().Replace(',', '.')); } } Lines.Add("0"); Lines.Add("ENDSEC"); Lines.Add("0"); Lines.Add("EOF"); File.WriteAllLines(outputfile + ".dxf", Lines); float scalefac = 10; Console.WriteLine("Report: {0} holes created in case ({1} spacers and {1} screws needed!)", Holes.Count, Holes.Count * 2); { var BB = new GerberLibrary.Bounds(); BB.AddPolygons(Offsetted); BB.AddPolyLine(Biggest); Bitmap B = new Bitmap((int)((BB.Width()) * scalefac) + 6, (int)((BB.Height()) * scalefac) + 6); Graphics G = Graphics.FromImage(B); G.Clear(Color.Transparent); G.Clear(Color.White); G.TranslateTransform(3, 3); G.ScaleTransform(scalefac, scalefac); G.TranslateTransform((float)-(BB.TopLeft.X), (float)-(BB.TopLeft.Y)); Pen pen = new Pen(Color.Black, 0.1f); Pen pen2 = new Pen(Color.FromArgb(160, 160, 160), 0.1f); pen2.DashPattern = new float[2] { 2, 2 }; GerberImageCreator.ApplyAASettings(G); RectangleF R = new RectangleF(0, 0, (float)holediameter, (float)holediameter); foreach (var a in Holes) { R.X = (float)a.X - (float)holeradius; R.Y = (float)a.Y - (float)holeradius; G.DrawEllipse(pen, R); } foreach (var poly in Offsetted) { PolyLine Pl = new PolyLine(PolyLine.PolyIDs.Temp); Pl.fromPolygon(poly); var Points = new List <PointF>(Pl.Vertices.Count); for (int i = 0; i < Pl.Vertices.Count; i++) { Points.Add(Pl.Vertices[i].ToF()); } Points.Add(Pl.Vertices[0].ToF()); G.DrawLines(pen, Points.ToArray()); } { PolyLine Pl = Biggest; var Points = new List <PointF>(Pl.Vertices.Count); for (int i = 0; i < Pl.Vertices.Count; i++) { Points.Add(Pl.Vertices[i].ToF()); } Points.Add(Pl.Vertices[0].ToF()); G.DrawLines(pen2, Points.ToArray()); } var ImagePNG = outputfile + ".png"; B.Save(ImagePNG); return(ImagePNG); } }
public static float pathArea(Path path) { return(Mathf.Abs(((float)Clipper.Area(path)) / Mathf.Pow(IntPointPrecision, 2))); }