public Allocation PlaceSingle(PlayerAllocationRequest request) { double minMustHaveOverlap = double.MaxValue; double minNiceHaveOverlap = double.MaxValue; int minIndex = -1; for (int i = 0; i < _numPlacements; i++) { var offset = _possibleOffsets[i]; var rotation = _possibleRotations[i]; var mustHaveArea = request.MustHave.DeepClone(); mustHaveArea.Rotate(rotation); mustHaveArea += offset; var niceHaveArea = request.NiceHave.DeepClone(); niceHaveArea.Rotate(rotation); niceHaveArea += offset; var mustHaveOverlap = .0; var niceHaveOverlap = .0; foreach (var allocation in _playerData.GetAllocations()) { if (allocation == null) { continue; } var playerMustHaveOverlap = ClipperUtility.GetArea(ClipperUtility.Intersection(allocation.GlobalMustHave, mustHaveArea)); var playerNiceHaveOverlap = ClipperUtility.GetArea(ClipperUtility.Intersection(allocation.GlobalNiceHave, niceHaveArea)); //Logger.Debug($"Overlap {request.PlayerId} with {playerId}: {playerMustHaveOverlap}"); mustHaveOverlap += playerMustHaveOverlap; niceHaveOverlap += playerNiceHaveOverlap; } if (mustHaveOverlap < minMustHaveOverlap || Math.Abs(mustHaveOverlap - minMustHaveOverlap) < .001 && niceHaveOverlap < minNiceHaveOverlap) { minMustHaveOverlap = mustHaveOverlap; minNiceHaveOverlap = niceHaveOverlap; minIndex = i; } } if (minIndex < 0) { return(null); } var newAllocation = new Allocation(request.MustHave, request.NiceHave, _possibleOffsets[minIndex], _possibleRotations[minIndex]); return(newAllocation); }
public void LineIntersectionTest() { Polygon line = Polygon.AsLine(Vector.Zero, Vector.One); Polygon rectangle = Polygon.AsRectangle(Vector.One); PolygonList output = ClipperUtility.Intersection(line, rectangle); Assert.AreEqual(1, output.Count); Polygon actualOutput = output[0]; Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(line, actualOutput, epsilon: 15 * Vector.Scale * 15 * Vector.Scale)); }
public void SimpleOverlapTest() { Polygon a = Polygon.AsRectangle(new Vector(2, 2)); Polygon b = Polygon.AsRectangle(new Vector(2, 2), new Vector(1, 1)); Polygon expectedPolygon = Polygon.AsRectangle(new Vector(1, 1), new Vector(1, 1)); PolygonList resultIntersection = ClipperUtility.Intersection(a, b); Assert.AreEqual(1, resultIntersection.Count); Polygon resultPolygon = resultIntersection[0]; Assert.IsTrue(ClipperUtility.HaveIntersection(a, b)); Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(expectedPolygon, resultPolygon)); }
public Dictionary <int, Polygon> GetAreasForPositions(Dictionary <int, Vector> idToPosition) { Dictionary <Vector, MIVector> vectorToMiVectorMapping = new Dictionary <Vector, MIVector>(); idToPosition.ForEachValue(vector => vectorToMiVectorMapping[vector] = new MIVector(vector.X, vector.Z)); // add fake generators vectorToMiVectorMapping.Add(new Vector(0, 10), new MIVector(0, 10)); vectorToMiVectorMapping.Add(new Vector(10, 0), new MIVector(10, 0)); vectorToMiVectorMapping.Add(new Vector(0, -10), new MIVector(0, -10)); vectorToMiVectorMapping.Add(new Vector(-10, 0), new MIVector(-10, 0)); Dictionary <MIVector, VoronoiCell> positionsToVoronoi = GetAreasForPositions(vectorToMiVectorMapping.Values.ToList()); Dictionary <int, Polygon> idsToVoronoi = new Dictionary <int, Polygon>(); foreach (KeyValuePair <int, Vector> pair in idToPosition) { if (!positionsToVoronoi.ContainsKey(vectorToMiVectorMapping[pair.Value])) { continue; } PolygonList intersection = ClipperUtility.Intersection( _wrapperPolygon, new PolygonList(positionsToVoronoi[vectorToMiVectorMapping[pair.Value]] .CellVertices .Select((p) => { List <Vector> list = p.Select(mi => new Vector(mi.X, mi.Z)).ToList(); Polygon poly = new Polygon(list); poly.MakeContour(); return(poly); }) .ToList()) ); if (intersection.Count > 0) { idsToVoronoi[pair.Key] = intersection.First(); } } return(idsToVoronoi); }