public void NotEqualWithinEpsilonTest()
        {
            Polygon a = Polygon.AsRectangle(new Vector(1000, 1000));
            Polygon b = Polygon.AsRectangle(new Vector(2000, 3000));

            Assert.IsFalse(ClipperUtility.EqualWithinEpsilon(a, b));
        }
        private void BuildDistortion(GraphicsPath source)
        {
            _sourceBounds = source.GetBounds();

            _distortionPath = new GraphicsPath(source.FillMode);

            _lowerLeft  = new PointF(_sourceBounds.Left, _sourceBounds.Bottom);
            _lowerRight = new PointF(_sourceBounds.Right, _sourceBounds.Bottom);
            _upperLeft  = new PointF(_sourceBounds.Left, _sourceBounds.Top);
            _upperRight = new PointF(_sourceBounds.Right, _sourceBounds.Top);

            _distortionPath.AddLine(_lowerLeft, _upperLeft);

            _distortionPath.AddBezier(_upperLeft,
                                      new PointF(_sourceBounds.Left, _sourceBounds.Top + ((_sourceBounds.Height * (float)Intensity)) * -1),
                                      new PointF(_sourceBounds.Right, _sourceBounds.Top + ((_sourceBounds.Height * (float)Intensity)) * -1),
                                      _upperRight);

            _distortionPath.AddLine(_upperRight, _lowerRight);

            _distortionPath.AddBezier(_lowerRight,
                                      new PointF(_sourceBounds.Right, _sourceBounds.Bottom + (_sourceBounds.Height * (float)Intensity)),
                                      new PointF(_sourceBounds.Left, _sourceBounds.Bottom + (_sourceBounds.Height * (float)Intensity)),
                                      _lowerLeft);

            _distortionPath.Flatten();
            _distortionPoints = ClipperUtility.ConvertToClipperPolygons(_distortionPath);
            _distortionBounds = _distortionPath.GetBounds();
        }
        public void EqualWithinEpsilonTest()
        {
            Polygon a = Polygon.AsRectangle(new Vector(1000, 1000));
            Polygon b = Polygon.AsRectangle(new Vector(1000.000001, 1000.000001));

            Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(a, b));
        }
        public void ContainsFullyTest()
        {
            Polygon a = Polygon.AsRectangle(new Vector(10, 10));
            Polygon b = Polygon.AsRectangle(new Vector(1, 1), new Vector(1, 1));

            Assert.IsTrue(ClipperUtility.ContainsWithinEpsilon(a, b));
            Assert.AreEqual(1, ClipperUtility.ContainsRelative(a, b), .001);
        }
        public void GetAreaTest()
        {
            Polygon polygon      = Polygon.AsRectangle(new Vector(10, 100));
            double  expectedArea = 10 * 100;
            double  resultArea   = ClipperUtility.GetArea(polygon);

            Assert.AreEqual(expectedArea, resultArea, .001);
        }
        public void EqualWithinHighEpsilonTest()
        {
            Polygon a = Polygon.AsRectangle(new Vector(10, 10));
            Polygon b = Polygon.AsRectangle(new Vector(10, 10), new Vector(1, 1));

            Assert.IsFalse(ClipperUtility.EqualWithinEpsilon(a, b));
            Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(a, b, epsilon: 15 * Vector.Scale * 15 * Vector.Scale));
        }
        public void PolygonAsCircleAreaTest()
        {
            Polygon circle       = Polygon.AsCircle(4, new Vector(5, 5), 360);
            double  area         = ClipperUtility.GetArea(circle);
            double  expectedArea = Math.PI * 4 * 4; // PI * r * r

            Assert.AreEqual(expectedArea, area, .01);
        }
        public void PolygonRotation90Degrees()
        {
            Polygon expectedPolygon = Polygon.AsRectangle(new Vector(2, 2), new Vector(-1, -1));
            Polygon actualPolygon   = expectedPolygon.DeepClone();

            actualPolygon.RotateCounter(90 * Math.PI / 180);

            CollectionAssert.AreNotEqual(expectedPolygon.Points, actualPolygon.Points);
            Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(expectedPolygon, actualPolygon));
        }
Beispiel #9
0
        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 PolygonVectorAddition()
        {
            Polygon polygon = Polygon.AsRectangle(new Vector(3, 4));
            Vector  offset  = new Vector(1, 1);

            polygon += offset;

            List <IntPoint> expectedCoordinates = new List <IntPoint>(
                new IntPoint[] { new Vector(1, 1), new Vector(4, 1), new Vector(4, 5), new Vector(1, 5) });

            Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(polygon, expectedCoordinates));
        }
        public void OffsetPolygonByHalfTest()
        {
            Polygon input          = Polygon.AsRectangle(new Vector(10, 10));
            Polygon expectedOutput = Polygon.AsRectangle(new Vector(5, 5), new Vector(2.5, 2.5));

            PolygonList output = ClipperUtility.OffsetPolygon(input, -2.5f);

            Assert.AreEqual(1, output.Count);

            Polygon actualOutput = output[0];

            Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(expectedOutput, actualOutput));
        }
        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 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));
        }
        private void GetBoundedPoints(out PointF upperBoundPoint, out PointF lowerBoundPoint, PointF source)
        {
            if (_boundCache.ContainsKey(source.X))
            {
                upperBoundPoint = _boundCache[source.X][0];
                lowerBoundPoint = _boundCache[source.X][1];
                return;
            }

            var Path   = new GraphicsPath();
            var UpperX = source.X * (_sourceBounds.Width / (_upperRight.X - _upperLeft.X));
            var LowerX = source.X * (_sourceBounds.Width / (_lowerRight.X - _lowerLeft.X));

            Path.AddPolygon(new PointF[] {
                new PointF(_distortionBounds.Left, _distortionBounds.Bottom),
                new PointF(_distortionBounds.Left, _distortionBounds.Top),
                new PointF(UpperX, _distortionBounds.Top),
                new PointF(LowerX, _distortionBounds.Bottom),
            });
            Path.CloseFigure();
            var ClippingPath = ClipperUtility.ConvertToClipperPolygons(Path);

            Path.Dispose();

            var ClippedPath = ClipperUtility.Clip(ClippingPath, _distortionPoints);

            if (Math.Abs(source.X - _sourceBounds.Left) < .1 || Math.Abs(source.X - _sourceBounds.Right) < .1)
            {
                upperBoundPoint = new PointF(_sourceBounds.Left, _sourceBounds.Top);
                lowerBoundPoint = new PointF(_sourceBounds.Left, _sourceBounds.Bottom);
            }
            else
            {
                var Points       = ClippedPath.PathPoints;
                var QuickBounded = Points.Where(p => Math.Abs(p.X - LowerX) < .01);
                if (QuickBounded.Any())
                {
                    upperBoundPoint = Points.Where(p => Math.Abs(p.X - LowerX) < .01).OrderBy(p => p.Y).First();
                    lowerBoundPoint = Points.Where(p => Math.Abs(p.X - LowerX) < .01).OrderByDescending(p => p.Y).First();
                    _boundCache.Add(source.X, new PointF[] { upperBoundPoint, lowerBoundPoint });
                }
                else
                {
                    var RightMostPoints = Points.OrderByDescending(p => p.X).Take(2).ToList();
                    upperBoundPoint = RightMostPoints.OrderBy(p => p.Y).First();
                    lowerBoundPoint = RightMostPoints.OrderByDescending(p => p.Y).First();
                }
                ClippedPath.Dispose();
            }
        }
Beispiel #15
0
        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);
        }
        public static void Run()
        {
            Logger.SetLevel(Logger.Level.Debug);

            string[] allInfoLines = File.ReadAllLines(Config.CsvStudyInfoFilePath);

            var infoSelections = (from line in allInfoLines.Skip(1)
                                  let data = line.Split(';')
                                             select new
            {
                PartId = data[0],
                StartOffset = Helper.ConvertToLong(data[2]),
                StudyType = data[1]
            }).Distinct();

            string[] allLines = File.ReadAllLines(Config.CsvFilePath);

            // select
            var selections = (from line in allLines.Skip(1)
                              let data = line.Split(';')
                                         select new
            {
                PartId = data[1],
                Game = data[5],
                StudyType = data[2]
            }).Distinct();

            // for each selection
            if (selections.Count() != 32)
            {
                Logger.Warn("Expecting 32 different conditions for participants");
            }


            foreach (var selection in selections)
            {
                var query = from line in allLines.Skip(1)
                            let data = line.Split(';')
                                       where data[5] == selection.Game && data[1] == selection.PartId && data[2] == selection.StudyType
                                       &&
                                       infoSelections
                                       .First(infoSelection => infoSelection.PartId == selection.PartId &&
                                              infoSelection.StudyType == selection.StudyType).StartOffset < Helper.ConvertToLong(data[9])
                                       select new
                {
                    PartId    = Helper.ConvertToInteger(data[1]),
                    Timestamp = Helper.ConvertToLong(data[9]),
                    Game      = data[5],
                    StudyType = data[2],
                    Rotation  = Helper.ConvertToDouble(data[8]),
                    PositionX = Helper.ConvertToDouble(data[11]),
                    PositionY = Helper.ConvertToDouble(data[12])
                };

                //var minOffsetTime =
                //    infoSelections.First(select => select.PartId == selection.PartId && select.StudyType == selection.StudyType).StartOffset;

                // BASIC STEPS FOR FIRST 100 ENTRIES
                //i = 0;
                //foreach (var row in query)
                //{
                //    Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}");
                //    i++;
                //    if (i > 100) break;
                //}

                // USED AREA
                var radius         = .3f;
                var circleSubsteps = 32;
                var usedPlayArea   = new PolygonList();
                foreach (var row in query)
                {
                    //if (row.Timestamp < minOffsetTime) continue;

                    var position = new Vector(row.PositionX, row.PositionY);
                    position.RotateCounter(-row.Rotation / 180 * Math.PI);
                    var positionPolygon = Polygon.AsCircle(radius, position, circleSubsteps);
                    usedPlayArea = ClipperUtility.Union(usedPlayArea, positionPolygon);
                }

                var usedArea = ClipperUtility.GetArea(usedPlayArea);
                Logger.Debug($"{selection.PartId};{selection.Game};{selection.StudyType};{usedArea}");

                // DURATION, MIN/MAX TIME
                //var min = double.MaxValue;
                //var max = double.MinValue;
                //foreach (var row in query)
                //{
                //    if (row.Timestamp < minOffsetTime) continue;

                //    if (row.Timestamp < min) min = row.Timestamp;
                //    if (max < row.Timestamp) max = row.Timestamp;
                //}

                //Logger.Debug($"{selection.PartId};{selection.StudyType};{min};{max};0;{max-min}");
            }



            //i = 0;
            //foreach (var row in query)
            //{
            //    Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}");
            //    i++;
            //    if (i > 100) break;
            //}



            Console.ReadKey();
        }