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); }
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); }
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); }
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()); } }