public void TestPushBackBotRightToCenter() { //Preconfig Vector position1 = new Vector(0f, 50f); Vector target1 = new Vector(50f, 50f); int radius2 = 20; Vector center2 = new Vector(25, 55); Vector ballSpeed = new Vector(-5, -5); Vector hitPoint = new Vector(20, 50); Vector pushBackVec; Vector estimatedPushBackVec = new Vector(0, 1); estimatedPushBackVec.Normalize(); //Creation Line parent = new Line(); BoundingContainer bCont = new BoundingContainer(parent); BoundingLine bL1 = new BoundingLine(position1, target1); bCont.AddBoundingBox(bL1); parent.Location = (new Vector(0, 0)); //Operation pushBackVec = bL1.GetOutOfAreaPush(radius2 * 2, hitPoint, -ballSpeed, center2); pushBackVec.Normalize(); //Assertion Assert.AreEqual(estimatedPushBackVec, pushBackVec); }
public void TestReflection135Direction() { //Preconfig Vector position = new Vector(100f, 100f); Vector ballPos = new Vector(140f, 120f); int radius = 20; Vector ballSpeed = new Vector(-100, -100); Vector hitPoint = new Vector(120 + 14.1421f, 120 + 14.1421f); Vector expectedReflection = -ballSpeed; expectedReflection.Normalize(); Vector reflection; //Creation Bumper parent = new Bumper(); BoundingCircle bC2 = new BoundingCircle(radius, position); BoundingContainer bCont = new BoundingContainer(parent); bCont.AddBoundingBox(bC2); //Operation parent.Location = (new Vector(0, 0)); reflection = bC2.Reflect(ballSpeed, hitPoint, ballPos); reflection.Normalize(); //Assertion Assert.AreEqual(expectedReflection.X, reflection.X, 0.001f); Assert.AreEqual(expectedReflection.Y, reflection.Y, 0.001f); }
public void addReferenceTwiceTest() { //Preconfig int radius1 = 20; Vector center1 = new Vector(0f, 0f); //Creation Bumper parent = new Bumper(); BoundingContainer bCont = new BoundingContainer(parent); BoundingCircle bC1 = new BoundingCircle(radius1, center1); bCont.AddBoundingBox(bC1); BoundingField bf = new BoundingField(0, 0); //Operation bf.addReference(bC1); bf.addReference(bC1); int hit = 0; //Assertion foreach (IBoundingBox b in bf.getReferences()) { if (b.Equals(bC1)) { hit++; } } if (hit == 1) { Assert.AreEqual(1, hit); } }
public void TestIntersectIntersectBallSpeedZero() { //Preconfig int radius1 = 20; Vector center1 = new Vector(0f, 0f); int radius2 = 20; Vector center2 = new Vector(-19, 0f); Vector ballSpeed = new Vector(0, 0); Vector hitPoint; bool isIntersec = false; //Creation Bumper parent = new Bumper(); Ball ball = new Ball(); BoundingContainer bCont = new BoundingContainer(parent); BoundingContainer bCont2 = new BoundingContainer(ball); BoundingCircle bC1 = new BoundingCircle(radius1, center1); BoundingCircle bC2 = new BoundingCircle(radius2, center2); bCont.AddBoundingBox(bC1); bCont2.AddBoundingBox(bC2); ball.Velocity = ballSpeed; parent.Location = (new Vector(0, 0)); parent.Width = 2 * radius1; parent.Height = 2 * radius1; //Operation isIntersec = bC1.Intersect(bC2, out hitPoint, ballSpeed); //Assertion Assert.IsTrue(isIntersec); }
public void TestBoundingLineReflect180Bot() { //Preconfig Vector position1 = new Vector(0f, 50f); Vector target1 = new Vector(50f, 50f); Vector ballSpeed = new Vector(0, -10); Vector ballPos = new Vector(20f, 100f); Vector hitPoint = new Vector(20, 50); Vector expectedReflection = -ballSpeed; expectedReflection.Normalize(); Vector reflection; //Creation Line parent = new Line(); BoundingContainer bCont = new BoundingContainer(parent); BoundingLine bL1 = new BoundingLine(position1, target1); bCont.AddBoundingBox(bL1); parent.Location = (new Vector(0, 0)); //Operation reflection = bL1.Reflect(ballSpeed, hitPoint, ballPos); reflection.Normalize(); //Assertion Assert.AreEqual(expectedReflection, reflection); }
public void TestBoundingCirclePushBackLeft() { //Preconfig int radius = 20; Vector position = new Vector(100f, 100f); Vector ballPos = new Vector(90, 120); Vector hitPoint = new Vector(100, 120); Vector ballSpeed = hitPoint - ballPos; Vector expectedPushBack = (radius * 2 / 1.9f) * ((hitPoint - (position + new Vector(radius, radius)))).AsNormalized(); Vector pushBackVec; //Creation Bumper parent = new Bumper(); BoundingCircle bC2 = new BoundingCircle(radius, position); BoundingContainer bCont = new BoundingContainer(parent); bCont.AddBoundingBox(bC2); //Operation parent.Location = (new Vector(0, 0)); pushBackVec = bC2.GetOutOfAreaPush(radius * 2, hitPoint, ballSpeed, ballPos); //Assertion Assert.AreEqual(expectedPushBack, pushBackVec); }
public void TestIntersect1pxOverlapBot() { //Preconfig Vector position1 = new Vector(0f, 50f); Vector target1 = new Vector(50f, 50f); int radius2 = 20; Vector center2 = new Vector(20, 49); Vector ballSpeed = new Vector(0, -5); Vector hitPoint; bool isIntersec = false; //Creation Line parent = new Line(); Ball ball = new Ball(); BoundingContainer bCont = new BoundingContainer(parent); BoundingContainer bCont2 = new BoundingContainer(ball); BoundingLine bL1 = new BoundingLine(position1, target1); BoundingCircle bC2 = new BoundingCircle(radius2, center2); bCont.AddBoundingBox(bL1); bCont2.AddBoundingBox(bC2); ball.Velocity = ballSpeed; parent.Location = (new Vector(0, 0)); //Operation isIntersec = bC2.Intersect(bL1, out hitPoint); //Assertion Assert.IsTrue(isIntersec); Assert.AreEqual(new Vector(40,50), hitPoint); }
public void TakeOverBoundingContainerWithLineSmallDiagonal() { //preconfig int cols = 10; int rows = 10; int width = 100; int height = 100; int expectedFieldHeight = height / rows; int expectedFieldWidth = width / cols; Vector position1 = new Vector(0, 0); Vector target1 = new Vector(50, 50); //creation BoundingRaster br = new BoundingRaster(cols, rows, width, height); Line parent1 = new Line(); BoundingLine bL1 = new BoundingLine(position1, target1); BoundingContainer bCont1 = new BoundingContainer(parent1); bCont1.AddBoundingBox(bL1); parent1.Location = (new Vector(0, 0)); //operation br.TakeOverBoundingContainer(bCont1); //assertion for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { if ((x == y) && x >= 0 && x <= 5) { bool found = false; foreach (IBoundingBox b in br.GetBoundingField(x, y).getReferences()) { Assert.AreEqual(bL1, b); found = true; } if (!found) { Assert.Fail(); } } else { foreach (IBoundingBox b in br.GetBoundingField(x, y).getReferences()) { if (bL1.Equals(b)) { Assert.Fail(); } } } } } }
public void TakeOverBoundingContainerWithCircleBigCenter() { //preconfig int cols = 10; int rows = 10; int width = 100; int height = 100; int expectedFieldHeight = height / rows; int expectedFieldWidth = width / cols; int radius1 = 50; Vector position1 = new Vector(0, 0); //creation BoundingRaster br = new BoundingRaster(cols, rows, width, height); Bumper parent1 = new Bumper(); BoundingCircle bC1 = new BoundingCircle(radius1, position1); BoundingContainer bCont1 = new BoundingContainer(parent1); bCont1.AddBoundingBox(bC1); parent1.Location = (new Vector(0, 0)); //operation br.TakeOverBoundingContainer(bCont1); //assertion for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { if (x <= 9 && x >= 0 && y <= 9 && y >= 0) { bool found = false; foreach (IBoundingBox b in br.GetBoundingField(x, y).getReferences()) { Assert.AreEqual(bC1, b); found = true; } if (!found) { Assert.Fail(); } } else { foreach (IBoundingBox b in br.GetBoundingField(x, y).getReferences()) { if (bC1.Equals(b)) { Assert.Fail(); } } } } } }
public void TestIntersectIntersectleft1pxOverlap() { //Preconfig Vector target1 = new Vector(40, 50); Vector position1 = new Vector(0f, 50f); int radius2 = 20; Vector center2 = new Vector(-39, 30); Vector ballSpeed = new Vector(0, 5); Vector hitPoint; bool isIntersec = false; //Creation Line parent = new Line(); Ball ball = new Ball(); BoundingContainer bCont = new BoundingContainer(parent); BoundingContainer bCont2 = new BoundingContainer(ball); BoundingLine bL1 = new BoundingLine(position1, target1); BoundingCircle bC2 = new BoundingCircle(radius2, center2); bCont.AddBoundingBox(bL1); bCont2.AddBoundingBox(bC2); ball.Velocity = ballSpeed; ball.Location = (new Vector(0, 0)); ball.Width = 20; ball.Height = 20; parent.Location = (new Vector(0, 0)); parent.Width = 40; parent.Height = 0; //Operation isIntersec = bL1.Intersect(bC2, out hitPoint); //Assertion Assert.IsTrue(isIntersec); Assert.AreEqual(0, hitPoint.X, 2); Assert.AreEqual(50f, hitPoint.Y, 2); }
private void init() { Transform = Matrix.Identity; pureIntersection = false; BoundingContainer = new BoundingContainer(this); Init(); RebuildMatrix(); }
public void TakeOverBoundingContainerWithLineTotalOutside() { //preconfig int cols = 10; int rows = 10; int width = 100; int height = 100; int expectedFieldHeight = height / rows; int expectedFieldWidth = width / cols; Vector position1 = new Vector(-20, -20); Vector target1 = new Vector(-50, -50); //creation BoundingRaster br = new BoundingRaster(cols, rows, width, height); Line parent1 = new Line(); BoundingLine bL1 = new BoundingLine(position1, target1); BoundingContainer bCont1 = new BoundingContainer(parent1); bCont1.AddBoundingBox(bL1); parent1.Location = (new Vector(0, 0)); //operation br.TakeOverBoundingContainer(bCont1); //assertion for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { foreach (IBoundingBox b in br.GetBoundingField(x, y).getReferences()) { if (bL1.Equals(b)) { Assert.Fail(); } } } } }
/// <summary> /// assigne this bounding box to a container /// </summary> /// <param name="bc">The container which this bounding box shall be assigned to</param> public void AssignToContainer(BoundingContainer bc) { this.BoundingContainer = bc; }
public void TestIntersectNoIntersectTouch() { //Preconfig int radius1 = 20; Vector center1 = new Vector(0f, 0f); int radius2 = 20; Vector center2 = new Vector(40f, 0f); Vector ballSpeed = new Vector(-5, 0); Vector hitPoint; bool isIntersec = false; //Creation Bumper parent = new Bumper(); Ball ball = new Ball(); BoundingContainer bCont = new BoundingContainer(parent); BoundingContainer bCont2 = new BoundingContainer(ball); BoundingCircle bC1 = new BoundingCircle(radius1, center1); BoundingCircle bC2 = new BoundingCircle(radius2, center2); bCont.AddBoundingBox(bC1); bCont2.AddBoundingBox(bC2); ball.Velocity = ballSpeed; //Operation isIntersec = bC1.Intersect(bC2, out hitPoint); //Assertion Assert.IsFalse(isIntersec); }
/// <summary> /// Goes though the bounding container and takes over his bounding boxes. /// Animated Objects do not need to be taken over /// </summary> /// <param name="bC">Container that holds bounding boxes to add</param> public void TakeOverBoundingContainer(BoundingContainer bC) { Vector worldTrans = bC.ParentElement.Location; int x; int y; foreach (IBoundingBox b in bC.BoundingBoxes) { if (b.GetType() == typeof(BoundingCircle) || b.GetType() == typeof(BoundingCircleZentripush)) { //Strategy: Make a box around the circle BoundingCircle bCir = (BoundingCircle)b; //position of the circle self (which field) x = ((int)((bCir.Position.X + worldTrans.X) / FieldWidth)); //TODO check if this is rounded down y = ((int)((bCir.Position.Y + worldTrans.Y) / FieldHeight)); //amount of fields x and y (rounded up) //2*cicFieldsX + (1 where the ceneter is) will make the width of the square which includes the circle) //2*cicFieldsY + (1 where the ceneter is) will make the height of the square which includes the circle) int circFieldsX = (int)Math.Ceiling((double)(bCir.radius * 1f / FieldWidth)); int circFieldsy = (int)Math.Ceiling((double)(bCir.radius * 1f / FieldHeight)); if ((bCir.Position.X + worldTrans.X) < 0) { x = (x - 1); if (circFieldsX + x > 0) { circFieldsX++; } } if ((bCir.Position.Y + worldTrans.Y) < 0) { y = (y - 1); if (circFieldsy + y > 0) { circFieldsy++; } } //go from the left to the right of the square for (int h = x - circFieldsX; h <= x + circFieldsX; h++) { if (h < 0 || h >= this.Cols) { //if h is out of raster skip this continue; } for (int ver = y - circFieldsy; ver <= y + circFieldsy; ver++) { if (ver < 0 || ver >= this.Rows) { //if ver is out of raster skip this continue; } //this is a field which should hold a reference to the boundingCircle this.fields[h, ver].addReference(bCir); //duplicate entries will be neglected } } } else //if(b.GetType() == typeof(BoundingCircle)) { //line BoundingLine bL = (BoundingLine)b; double posX = bL.Position.X + worldTrans.X; double posY = bL.Position.Y + worldTrans.Y; //position of the line base (which field) x = (int)(posX / FieldWidth); y = (int)(posY / FieldHeight); //add the start if (IsWithinBounds(x, y)) this.fields[x, y].addReference(bL); //duplicate entries will be neglected //define unitvector from position to target Vector unitV = bL.target - bL.Position; unitV.Normalize(); if (unitV.X > 0) { takeOverBoundingLineLeftToRight(unitV, posX, posY,ref x,ref y, bL, worldTrans); } else { takeOverBoundingLineRightToLeft(unitV, posX, posY,ref x,ref y, bL, worldTrans); } //at this point all x fields have been added but there might be some y fields who get touched but are not referenced yet. //that are all fields that are above the last x cross (like directly under the target) int endField = (int)((bL.target.Y + worldTrans.Y) / FieldHeight); if (unitV.Y > 0) //heading down { for (int i = y + 1; i <= endField; i++) { if (IsWithinBounds(x, i)) this.fields[x, i].addReference(bL); } } else //heading up { for (int i = y - 1; i >= endField - 1; i--) { if (IsWithinBounds(x, i)) this.fields[x, i].addReference(bL); } } } //if(b.GetType() == typeof(BoundingCircle)) } //foreach (IBoundingBox b in bC.boundingBoxes) }
/// <summary> /// Checks if two bounding container intersect each other. /// </summary> /// <param name="bC"></param> /// <returns></returns> public bool Intersects(BoundingContainer bC) { Vector dummy = new Vector(); foreach (var b1 in BoundingBoxes) { foreach (var b2 in bC.BoundingBoxes) { if (b2.Intersect(b1, out dummy)) return true; } } return false; }
public void TestIntersectIntersectNone() { //Preconfig Vector target1 = new Vector(20, 50); Vector position1 = new Vector(0f, 50f); int radius2 = 20; Vector center2 = new Vector(10, 0f); Vector ballSpeed = new Vector(0, 5); Vector hitPoint; bool isIntersec = false; //Creation Line parent = new Line(); Ball ball = new Ball(); BoundingContainer bCont = new BoundingContainer(parent); BoundingContainer bCont2 = new BoundingContainer(ball); BoundingLine bL1 = new BoundingLine(position1, target1); BoundingCircle bC2 = new BoundingCircle(radius2, center2); bCont.AddBoundingBox(bL1); bCont2.AddBoundingBox(bC2); ball.Velocity = ballSpeed; parent.Location = new Vector(0, 0); parent.Width = 20; parent.Height = 0; //Operation isIntersec = bC2.Intersect(bL1, out hitPoint); //Assertion Assert.IsFalse(isIntersec); }