Beispiel #1
0
        public void SplitHorizontally(string ptsStr, int y, string topPtsExpected, string bottomPtsExpected)
        {
            var poly = _ParsePattern(ptsStr);

            var split  = poly.SplitHorizontally(FixedPoint.FromInt(y), ScratchPoints1, ScratchPoints2, ScratchPoints3);
            var top    = split[0];
            var bottom = split[1];

            var pts = new List <string>();

            foreach (var pt in top.Vertices)
            {
                pts.Add("(" + pt.X + "," + pt.Y + ")");
            }
            var topPts = string.Join(";", pts);

            pts.Clear();
            foreach (var pt in bottom.Vertices)
            {
                pts.Add("(" + pt.X + "," + pt.Y + ")");
            }
            var bottomPts = string.Join(";", pts);

            Assert.Equal(topPtsExpected, topPts);
            Assert.Equal(bottomPtsExpected, bottomPts);
        }
Beispiel #2
0
        public void CanIntersect(string ptsStr, int?x, int?y, bool expected)
        {
            if (x.HasValue && y.HasValue)
            {
                throw new Exception();
            }
            if (!x.HasValue && !y.HasValue)
            {
                throw new Exception();
            }

            var poly = _ParsePattern(ptsStr);

            bool val;

            if (x.HasValue)
            {
                val = poly.CanDivideAlongVertical(FixedPoint.FromInt(x.Value));
            }
            else
            {
                val = poly.CanDivideAlongHorizontal(FixedPoint.FromInt(y.Value));
            }

            Assert.Equal(expected, val);
        }
Beispiel #3
0
        public void SplitVertically(string ptsStr, int x, string leftPtsExpected, string rightPtsExpected)
        {
            var poly = _ParsePattern(ptsStr);

            var split = poly.SplitVertically(FixedPoint.FromInt(x), ScratchPoints1, ScratchPoints2, ScratchPoints3);
            var left  = split[0];
            var right = split[1];

            var pts = new List <string>();

            foreach (var pt in left.Vertices)
            {
                pts.Add("(" + pt.X + "," + pt.Y + ")");
            }
            var leftPts = string.Join(";", pts);

            pts.Clear();
            foreach (var pt in right.Vertices)
            {
                pts.Add("(" + pt.X + "," + pt.Y + ")");
            }
            var rightPts = string.Join(";", pts);

            Assert.Equal(leftPtsExpected, leftPts);
            Assert.Equal(rightPtsExpected, rightPts);
        }
        [InlineData(1, 4, 2, 3, 1, "NEVER")]                        // overlapping
        public void LineSegementCollision1D(int start1, int stop1, int start2, int stop2, int motion2, string expected)
        {
            var ls1 = new LineSegment1D(FixedPoint.FromInt(start1), FixedPoint.FromInt(stop1));
            var ls2 = new LineSegment1D(FixedPoint.FromInt(start2), FixedPoint.FromInt(stop2));

            var m    = FixedPoint.FromInt(motion2);
            var time = CollisionDetector.DetermineCollisionTime(ls1, ls2, m);

            var res = time == null ? "NEVER" : time.Value.ToString();

            Assert.Equal(expected, res);
        }
        public void TestOverlap(int a1, int a2, int b1, int b2, int expected)
        {
            var l1 = new LineSegment1D(FixedPoint.FromInt(a1), FixedPoint.FromInt(a2));
            var l2 = new LineSegment1D(FixedPoint.FromInt(b1), FixedPoint.FromInt(b2));

            var overlap1    = l1.MeasureOverlap(l2);
            var overlapInt1 = (int)overlap1;

            Assert.Equal(expected, overlapInt1);

            var overlap2    = l2.MeasureOverlap(l1);
            var overlapInt2 = (int)overlap2;

            Assert.Equal(expected, overlapInt2);
        }
Beispiel #6
0
        private static void DoBounce(
            IHitMapManager hitMapManager,
            int roomHeightSubPixels,
            Point collisionPtCartesian,

            CollisionListener self,
            ConvexPolygon selfPoly,
            PositionComponent selfLoc,
            VelocityComponent selfVelocity,

            CollisionListener other,
            ConvexPolygon otherPoly
            )
        {
            // nothing to do
            if (selfVelocity.X_SubPixels == 0 && selfVelocity.Y_SubPixels == 0)
            {
                return;
            }

            var    edgeCartesian = ClosestTo(collisionPtCartesian, otherPoly);
            Vector normOfWallScreen;

            if (edgeCartesian == null)
            {
                // vertex on vertex collision
                var otherVertex = ClosestVertexTo(collisionPtCartesian, otherPoly);
                var betweenVerticesCartesian = new LineSegment2D(collisionPtCartesian, otherVertex);

                var betweenVerticesScreen = TranslateToScreen(roomHeightSubPixels, betweenVerticesCartesian);
                var wallSlopeScreen       = betweenVerticesScreen.Normal();
                normOfWallScreen = wallSlopeScreen.Normal();
            }
            else
            {
                var edgeScreen = TranslateToScreen(roomHeightSubPixels, edgeCartesian.Value);
                normOfWallScreen = edgeScreen.Normal();
            }

            // based on: https://gamedev.stackexchange.com/a/23676/155
            var curSpeed = new Vector(selfVelocity.X_SubPixels, selfVelocity.Y_SubPixels);
            var newSpeed = curSpeed - 2 * curSpeed.Dot(normOfWallScreen) * normOfWallScreen;

            newSpeed = newSpeed.Normalize() * FixedPoint.FromInt(self.DesiredSpeed_HACK);

            selfVelocity.X_SubPixels = (int)newSpeed.DeltaX;
            selfVelocity.Y_SubPixels = (int)newSpeed.DeltaY;
        }
        public void DetermineCollisionPointInMotion(
            string p1, int x1, int y1,
            int m1x, int m1y,
            string p2, int x2, int y2,
            int m2x, int m2y,
            int time,
            string expected
            )
        {
            var poly1      = ForName(p1);
            var poly1Trans = poly1.Translate(x1, y1);
            var poly2      = ForName(p2);
            var poly2Trans = poly2.Translate(x2, y2);

            var t  = FixedPoint.FromInt(time);
            var v1 = new Vector(m1x, m1y);
            var v2 = new Vector(m2x, m2y);

            var detector = new CollisionDetector(64, 100);

            var collision = detector.DetermineCollisionPointInMotion(poly1Trans, v1, poly2Trans, v2, t);

            Assert.Equal(expected, collision.ToString());
        }
        public void VectorOperations()
        {
            // equality
            {
                var a = new Vector(FixedPoint.One, FixedPoint.FromInt(3));
                var b = new Vector(FixedPoint.One, FixedPoint.FromInt(3));
                var c = new Vector(FixedPoint.FromInt(2), FixedPoint.FromInt(2));

                Assert.True(a == b);
                Assert.True(a != c);
            }

            // add
            {
                var a = new Vector(FixedPoint.One, FixedPoint.FromInt(3));
                var b = new Vector(FixedPoint.FromInt(4), FixedPoint.FromInt(-10));

                var c = a + b;

                Assert.Equal("DeltaX=5, DeltaY=-(7)", c.ToString());
            }

            // subtract
            {
                var a = new Vector(FixedPoint.One, FixedPoint.FromInt(3));
                var b = new Vector(FixedPoint.FromInt(4), FixedPoint.FromInt(-10));

                var c = a - b;

                Assert.Equal("DeltaX=-(3), DeltaY=13", c.ToString());
            }

            // magnitude
            {
                var a = new Vector(FixedPoint.FromInt(15), FixedPoint.FromInt(-14));
                Assert.True(a.TryMagnitude(out var mag));
                Assert.Equal("20 + 543,460/1,048,576", mag.ToString());
            }

            // normal
            {
                var tolerance = FixedPoint.One / 10_000;

                var a = new Vector(FixedPoint.FromInt(-3), FixedPoint.FromInt(23));
                Assert.True(a.TryMagnitude(out var mPre));
                var n = a.Normalize();
                Assert.True(n.TryMagnitude(out var mPost));
                var b = n * mPre;

                var diff = (mPost - FixedPoint.One).Abs();
                Assert.True(diff < tolerance);

                var delta = a - b;
                Assert.True(delta.TryMagnitude(out diff));

                Assert.True(diff < tolerance);
            }

            // parallel
            {
                var a = new Vector(FixedPoint.FromInt(2), FixedPoint.FromInt(4));
                var b = a * FixedPoint.FromInt(5);
                var c = a * FixedPoint.FromInt(-1);

                Assert.True(a.IsParallel(b));
                Assert.True(b.IsParallel(a));
                Assert.True(a.IsParallel(c));

                var d = new Vector(FixedPoint.FromInt(-2), FixedPoint.FromInt(4));

                Assert.False(a.IsParallel(d));
                Assert.False(d.IsParallel(a));
            }

            // dot
            {
                var a = new Vector(FixedPoint.FromInt(4), FixedPoint.FromInt(-99));
                var b = new Vector(FixedPoint.FromInt(17), FixedPoint.FromInt(63));

                var d = a.Dot(b);
                Assert.Equal("-(6,169)", d.ToString());
            }
        }
        public void FullScene()
        {
            var step = FixedPoint.FromInt(1) / 1_000;

            var square1   = ForName("square");
            var bigSquare = ForName("bigsquare");
            var triangle  = ForName("triangle");
            var square2   = ForName("square");
            var octagon   = ForName("smalloctagon");

            var shapes = new List <ConvexPolygon>();

            shapes.Add(square1.Translate(1, 4));
            shapes.Add(bigSquare.Translate(5, 7));
            shapes.Add(triangle.Translate(5, 2));
            shapes.Add(square2.Translate(10, 2));
            shapes.Add(octagon.Translate(9, 5));

            var motion = new List <Vector>();

            motion.Add(new Vector(2, 1));
            motion.Add(new Vector(1, -1));
            motion.Add(new Vector(0, 2));
            motion.Add(new Vector(-1, 1));
            motion.Add(new Vector(-3, 0));

            var square1_BigSquare = new List <Collision>();
            var square1_Triangle  = new List <Collision>();
            var square1_Square2   = new List <Collision>();
            var square1_Octagon   = new List <Collision>();

            var bigSquare_Triangle = new List <Collision>();
            var bigSquare_Square2  = new List <Collision>();
            var bigSquare_Octagon  = new List <Collision>();

            var triangle_Square2 = new List <Collision>();
            var triangle_Octagon = new List <Collision>();

            var square2_Octagon = new List <Collision>();

            var detector = new CollisionDetector(64, 100);

            using (var collisions = detector.FindCollisions(shapes.Count, shapes.ToArray(), motion.ToArray(), step))
            {
                // mux these into separate collections
                foreach (var c in collisions)
                {
                    if (c.FirstPolygonIndex == 0)
                    {
                        if (c.SecondPolygonIndex == 1)
                        {
                            square1_BigSquare.Add(c);
                            continue;
                        }

                        if (c.SecondPolygonIndex == 2)
                        {
                            square1_Triangle.Add(c);
                            continue;
                        }

                        if (c.SecondPolygonIndex == 3)
                        {
                            square1_Square2.Add(c);
                            continue;
                        }

                        if (c.SecondPolygonIndex == 4)
                        {
                            square1_Octagon.Add(c);
                            continue;
                        }

                        throw new Exception("Wut");
                    }

                    if (c.FirstPolygonIndex == 1)
                    {
                        if (c.SecondPolygonIndex == 2)
                        {
                            bigSquare_Triangle.Add(c);
                            continue;
                        }

                        if (c.SecondPolygonIndex == 3)
                        {
                            bigSquare_Square2.Add(c);
                            continue;
                        }

                        if (c.SecondPolygonIndex == 4)
                        {
                            bigSquare_Octagon.Add(c);
                            continue;
                        }

                        throw new Exception("Wut");
                    }

                    if (c.FirstPolygonIndex == 2)
                    {
                        if (c.SecondPolygonIndex == 3)
                        {
                            triangle_Square2.Add(c);
                            continue;
                        }

                        if (c.SecondPolygonIndex == 4)
                        {
                            triangle_Octagon.Add(c);
                            continue;
                        }

                        throw new Exception("Wut");
                    }

                    if (c.FirstPolygonIndex == 3)
                    {
                        if (c.SecondPolygonIndex == 4)
                        {
                            square2_Octagon.Add(c);
                            continue;
                        }

                        throw new Exception("Wut");
                    }

                    throw new Exception("Huh");
                }
            }

            Assert.Equal(0, square1_BigSquare.Count);
            Assert.Equal(1, square1_Triangle.Count);
            Assert.Equal("X=5 + 349,522/1,048,576, Y=5 + 699,049/1,048,576", square1_Triangle[0].CollisionAt.ToString());
            Assert.Equal("1 + 699,049/1,048,576", square1_Triangle[0].AtTime.ToString());
            Assert.Equal(0, square1_Square2.Count);
            Assert.Equal(1, square1_Octagon.Count);
            Assert.Equal("X=4 + 838,862/1,048,576, Y=6 + 209,715/1,048,576", square1_Octagon[0].CollisionAt.ToString());
            Assert.Equal("1 + 419,429/1,048,576", square1_Octagon[0].AtTime.ToString());

            Assert.Equal(1, bigSquare_Triangle.Count);
            Assert.Equal("X=6 + 524,287/1,048,576, Y=5 + 524,289/1,048,576", bigSquare_Triangle[0].CollisionAt.ToString());
            Assert.Equal("1 + 524,287/1,048,576", bigSquare_Triangle[0].AtTime.ToString());
            Assert.Equal(1, bigSquare_Square2.Count);
            Assert.Equal("X=8 + 524,288/1,048,576, Y=5", bigSquare_Square2[0].CollisionAt.ToString());
            Assert.Equal("1 + 1,048,575/1,048,576", bigSquare_Square2[0].AtTime.ToString());
            Assert.Equal(1, bigSquare_Octagon.Count);
            Assert.Equal("X=7 + 524,289/1,048,576, Y=6 + 786,433/1,048,576", bigSquare_Octagon[0].CollisionAt.ToString());
            Assert.Equal("524,287/1,048,576", bigSquare_Octagon[0].AtTime.ToString());


            Assert.Equal(0, triangle_Square2.Count);
            Assert.Equal(1, triangle_Octagon.Count);
            Assert.Equal("X=6 + 209,717/1,048,576, Y=5 + 209,714/1,048,576", triangle_Octagon[0].CollisionAt.ToString());
            Assert.Equal("1 + 209,714/1,048,576", triangle_Octagon[0].AtTime.ToString());

            Assert.Equal(0, square2_Octagon.Count);
        }
        public void FixedPointOperations()
        {
            // addition
            {
                var one     = FixedPoint.One;
                var two     = FixedPoint.FromInt(2);
                var oneHalf = one / two;

                var three = one + two;
                Assert.Equal(FixedPoint.FromInt(3), three);

                var oneAndAHalf = one + oneHalf;
                Assert.Equal("1 + 524,288/1,048,576", oneAndAHalf.ToString());

                var twoAndAHalf = two + oneHalf;
                Assert.Equal("2 + 524,288/1,048,576", twoAndAHalf.ToString());

                var threeAndAHalf = three + oneHalf;
                Assert.Equal("3 + 524,288/1,048,576", threeAndAHalf.ToString());
            }

            // subtraction
            {
                var one     = FixedPoint.One;
                var two     = FixedPoint.FromInt(2);
                var oneHalf = one / two;

                var negativeOne = one - two;
                Assert.Equal(FixedPoint.FromInt(-1), negativeOne);

                var aHalf = one - oneHalf;
                Assert.Equal("524,288/1,048,576", aHalf.ToString());

                var oneAndAHalf = two - oneHalf;
                Assert.Equal("1 + 524,288/1,048,576", oneAndAHalf.ToString());

                var negativeOneHalf = FixedPoint.Zero - oneHalf;
                Assert.Equal("-(524,288/1,048,576)", negativeOneHalf.ToString());
            }

            // division
            {
                var one = FixedPoint.One;
                Assert.Equal("1", one.ToString());

                var oneHalf1 = one / 2;
                var oneHalf2 = one / FixedPoint.FromInt(2);
                var oneHalf3 = 1 / FixedPoint.FromInt(2);
                Assert.Equal(oneHalf1, oneHalf2);
                Assert.Equal(oneHalf1, oneHalf3);
                Assert.Equal("524,288/1,048,576", oneHalf1.ToString());

                var nineteenDivideBySeven = FixedPoint.FromInt(19) / FixedPoint.FromInt(7);
                Assert.Equal("2 + 748,982/1,048,576", nineteenDivideBySeven.ToString());
                var sevenDividedByNineteen = FixedPoint.FromInt(7) / FixedPoint.FromInt(19);
                Assert.Equal("386,317/1,048,576", sevenDividedByNineteen.ToString());
            }

            // sqrt
            {
                var zero = FixedPoint.Zero;
                Assert.Equal("0", zero.Sqrt().ToString());
                var one = FixedPoint.One;
                Assert.Equal("1", one.Sqrt().ToString());

                var two   = FixedPoint.FromInt(2);
                var sqrt2 = two.Sqrt();
                Assert.Equal("1 + 434,176/1,048,576", sqrt2.ToString());

                var big     = FixedPoint.FromInt(1_444_579);
                var sqrtBig = big.Sqrt();
                Assert.Equal("1,201 + 950,272/1,048,576", sqrtBig.ToString());
            }
        }