public bool IsCollide(RigidCircle circle)
            {
                var firstCollision  = CollisionDetector.GetCollisionInfo(Sector, circle);
                var secondCollision = CollisionDetector.GetCollisionInfo(Triangle, circle);

                return(firstCollision != null || secondCollision != null);
            }
Example #2
0
        private static CollisionInfo GetCollisionInfo(RigidCircle circle, RigidCircleQuarter circleQuarter)
        {
            var info = GetCollisionInfo(circle, circleQuarter.WholeCircle);

            if (info == null)
            {
                return(null);
            }
            var vector     = info.Start - circleQuarter.Center;
            var vertical   = Vector.ScalarProduct(vector, circleQuarter.Direction);
            var horizontal = Vector.ScalarProduct(vector, circleQuarter.DirectionNormal);

            switch (circleQuarter.QuarterIndex)
            {
            case 1 when vertical >= 0 && horizontal >= 0: return(info);

            case 2 when vertical >= 0 && horizontal <= 0: return(info);

            case 3 when vertical <= 0 && horizontal <= 0: return(info);

            case 4 when vertical <= 0 && horizontal >= 0: return(info);

            default: return(null);
            }
        }
        public void TestTwoCirclesAreInTouchOnEdge()
        {
            var first    = new RigidCircle(new Vector(40, 0), 10, true, true);
            var expected = new CollisionInfo(0, new Vector(1, 0), new Vector(30, 0));

            Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(first, MainCircle));
        }
Example #4
0
        private static CollisionInfo GetCollisionInfo(RigidCircle first, RigidCircle second)
        {
            var vFromFirstToSecond = second.Center - first.Center;
            var vLengthSqrt        = Vector.ScalarProduct(vFromFirstToSecond, vFromFirstToSecond);
            var sumRadii           = first.Radius + second.Radius;

            if (sumRadii * sumRadii < vLengthSqrt)
            {
                return(null);
            }
            if (Math.Abs(vLengthSqrt) > 0.01)
            {
                return(new CollisionInfo(
                           sumRadii - vFromFirstToSecond.Length,
                           -vFromFirstToSecond.Normalize(),
                           first.Center + vFromFirstToSecond.Normalize() * first.Radius));
            }

            var maxRadius = Math.Max(first.Radius, second.Radius);

            return(new CollisionInfo(
                       maxRadius,
                       new Vector(0, -1),
                       first.Center + new Vector(0, 1) * maxRadius));
        }
        public void TestTwoCirclesHaveTheSameCenters()
        {
            var first    = new RigidCircle(Vector.ZeroVector, 10, true, true);
            var expected = new CollisionInfo(MainCircle.Radius, new Vector(0, -1), new Vector(0, 30));

            Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(first, MainCircle));
        }
        public void TestOneCircleIsInAnother()
        {
            var first    = new RigidCircle(new Vector(15, 0), 10, true, true);
            var expected = new CollisionInfo(25, new Vector(1, 0), new Vector(5, 0));

            Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(first, MainCircle));
        }
Example #7
0
        public void TestCircleAndAABBAreInTouch()
        {
            var circle   = new RigidCircle(new Vector(0, -5), 20, true, true);
            var expected = new CollisionInfo(15, new Vector(0, -1), Vector.ZeroVector);

            Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(circle, MainAABB));
        }
Example #8
0
        private static float[] GetPenetrationTimeWithMovingCircle(
            Vector objectPosition, Vector objectVelocity, RigidCircle circle, Vector circleVelocity)
        {
            var dX  = objectPosition.X - circle.Center.X;
            var dY  = objectPosition.Y - circle.Center.Y;
            var dVx = objectVelocity.X - circleVelocity.X;
            var dVy = objectVelocity.Y - circleVelocity.Y;
            // t^2 * (dVx^2 + dVy^2) + 2t(dX * dVx + dY * dVy) + (dX^2 + dY^2 - R^2) = 0

            var a = dVx * dVx + dVy * dVy;
            var b = dX * dVx + dY * dVy;
            var D = 4 * (b * b - a * (dX * dX + dY * dY - circle.Radius * circle.Radius));

            if (D < 0)
            {
                return(null);
            }

            var delA  = 1 / (2 * a);
            var sqrtD = (float)Math.Sqrt(D);

            return(new[]
            {
                (-2 * b - sqrtD) * delA,
                (-2 * b + sqrtD) * delA
            });
        }
Example #9
0
        public void TestCircleAndAABBAreInTouchOnEdge()
        {
            var circle   = new RigidCircle(new Vector(5, -10), 10, true, true);
            var expected = new CollisionInfo(0, new Vector(0, -1), new Vector(5, 0));

            Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(circle, MainAABB));
        }
Example #10
0
        public static Vector IsInView(RigidCircle circle, VisibilityRegion region)
        {
            CollisionInfo info;
            var           size = region.VisibilityRegionPoints.Count;
            var           visibilityPolygonPoints = region.VisibilityRegionPoints;
            var           lightSourcePosition     = region.LightSourcePosition;

            for (var i = 0; i < size - 1; i++)
            {
                info = CollisionDetector.GetCollisionInfo(
                    circle,
                    lightSourcePosition,
                    visibilityPolygonPoints[i].Position,
                    visibilityPolygonPoints[i + 1].Position);
                if (info != null)
                {
                    return(info.Start);
                }
            }

            info = CollisionDetector.GetCollisionInfo(
                circle,
                lightSourcePosition,
                visibilityPolygonPoints[visibilityPolygonPoints.Count - 1].Position,
                visibilityPolygonPoints[0].Position);

            return(info?.Start);
        }
        public void TestTwoCirclesAreInTouchCircleCenterIsInMainCircle()
        {
            var circle   = new RigidCircle(new Vector(20, 0), 15, true, true);
            var expected = new CollisionInfo(25, new Vector(1, 0), new Vector(5, 0));

            Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(circle, MainCircle));
        }
Example #12
0
        private void AddWalls(List <RigidShape> staticShapes, Size levelSizeInTiles)
        {
            var circle = new RigidCircle(Vector.ZeroVector, 32, true, true);

            for (var j = 1; j < levelSizeInTiles.Width - 1; ++j)
            {
                for (var i = 1; i < levelSizeInTiles.Height - 1; ++i)
                {
                    circle.MoveTo(new Vector(j, i) * 32);
                    var canWalk = true;
                    foreach (var staticShape in staticShapes)
                    {
                        if (CollisionDetector.GetCollisionInfo(circle, staticShape) == null)
                        {
                            continue;
                        }
                        canWalk = false;
                        break;
                    }

                    if (!canWalk)
                    {
                        walls.Add(new Point(j, i));
                    }
                }
            }
        }
        private static void DrawCircle(RigidCircle shape, Vector cameraPosition, Pen strokePen, Graphics g)
        {
            var inCameraPosition = shape.Center.ConvertFromWorldToCamera(cameraPosition);

            g.DrawEllipse(strokePen,
                          inCameraPosition.X - shape.Radius, inCameraPosition.Y - shape.Radius,
                          shape.Diameter, shape.Diameter);
        }
Example #14
0
        public CustomCursor(Vector position)
        {
            var bmpCursor = LevelManager.GetTileMap("crosshair.png");
            var sprite    = new Sprite(bmpCursor, 3, 0, 9, new Size(64, 64));

            shape           = new RigidCircle(position, 3, false, true);
            SpriteContainer = new SpriteContainer(sprite, position, 0);
        }
Example #15
0
        public static CollisionInfo GetCollisionInfo(RigidCircle circle, Vector a, Vector b, Vector c)
        {
            var q = GetClosestPoint(circle.Center, a, b, c);
            var v = q - circle.Center;

            return(Vector.ScalarProduct(v, v) <= circle.Radius * circle.Radius
                ? new CollisionInfo(v.Length, v, q)
                : null);
        }
Example #16
0
        private static CollisionInfo GetCollisionInfo(RigidAABB rectangle, RigidCircle circle)
        {
            var closestPoint = GetClosestPoint(circle.Center, rectangle);
            var v            = closestPoint - circle.Center;

            return(Vector.ScalarProduct(v, v) <= circle.Radius * circle.Radius
                ? new CollisionInfo(circle.Radius - v.Length, -v.Normalize(), closestPoint)
                : null);
        }
Example #17
0
        private static CollisionInfo GetCollisionInfo(RigidCircle circle, RigidTriangle triangle)
        {
            var a = triangle.Points[0]; var b = triangle.Points[1]; var c = triangle.Points[2];
            var q = GetClosestPoint(circle.Center, a, b, c);
            var v = q - circle.Center;

            return(Vector.ScalarProduct(v, v) <= circle.Radius * circle.Radius
                ? new CollisionInfo(v.Length, v, q)
                : null);
        }
Example #18
0
 public Bot(
     int health, int armor, SpriteContainer legsContainer, SpriteContainer torsoContainer,
     Vector sight, RigidCircle collisionShape, Weapon weapon, string deadBodyPath, List <Vector> patrolPoints)
     : base(health, armor, collisionShape, legsContainer, torsoContainer, deadBodyPath)
 {
     currentWeapon            = weapon;
     this.sight               = sight;
     collisionAvoidanceFactor = collisionShape.Diameter * 2;
     this.patrolPoints        = patrolPoints;
     patrolPointIndex         = 0;
     currentPathPointIndex    = 0;
 }
Example #19
0
 protected LivingEntity(
     int health, int armor, RigidCircle collisionShape, SpriteContainer legsContainer,
     SpriteContainer torsoContainer, string deadBodyPath)
 {
     Health         = health;
     Armor          = armor;
     CollisionShape = collisionShape;
     TorsoContainer = torsoContainer;
     LegsContainer  = legsContainer;
     Velocity       = Vector.ZeroVector;
     DeadBodyPath   = deadBodyPath;
 }
Example #20
0
 public Player(int health, int armor, RigidCircle collisionShape,
               SpriteContainer legsContainer, SpriteContainer torsoContainer,
               List <Weapon> startWeapons, Dictionary <Type, Sprite> weaponSprites,
               MeleeWeaponSprite meleeWeaponSprite, MeleeWeapon meleeWeapon, string deadBodyPath)
     : base(health, armor, collisionShape, legsContainer, torsoContainer, deadBodyPath)
 {
     MeleeWeapon            = meleeWeapon;
     this.meleeWeaponSprite = meleeWeaponSprite;
     weapons            = startWeapons;
     this.weaponSprites = weaponSprites;
     currentWeaponIndex = 0;
     ticksFromLastDash  = TicksBetweenDashes + 1;
     dashCount          = 2;
 }
Example #21
0
        private void TryAvoidCircle(RigidCircle circle)
        {
            var vectorToShape = circle.Center - Position;
            var sc            = Vector.ScalarProduct(vectorToShape, sight);

            if (sc < 0)
            {
                return;
            }

            var p          = sight * sc;
            var projection = p - vectorToShape;

            if (Vector.ScalarProduct(projection, projection) < circle.Radius * circle.Radius &&
                Vector.ScalarProduct(p, p) < collisionAvoidanceFactor * collisionAvoidanceFactor)
            {
                var sightNormal = sight.GetNormal();
                var u           = Vector.ScalarProduct(vectorToShape, sightNormal);
                RotateOnDegree(u < 0);
            }
        }
Example #22
0
        public static float[] AreCollideWithDynamic(Bullet bullet, RigidCircle circle, Vector circleVelocity)
        {
            var time = GetPenetrationTimeWithMovingCircle(bullet.Position, bullet.Velocity, circle, circleVelocity);

            if (time == null)
            {
                return(null);
            }
            var t1 = time[0];
            var t2 = time[1];

            // TODO there could be great optimization but it's really case specific
            if (t1 > 1)
            {
                return(null);
            }

            var ist1 = t1 > 0;
            var ist2 = t2 > 0 && t2 < 1;

            if (ist1 && ist2)
            {
                return new[] { t1, t2 }
            }
            ;
            if (ist1)
            {
                return new[] { t1 }
            }
            ;
            if (ist2)
            {
                return new[] { t2 }
            }
            ;
            return(null);
        }
 private void TestNotInTouch(RigidCircle circle, RigidCircleQuarter quarterMainDirection, RigidCircleQuarter quarterSecondDirection)
 {
     Assert.IsNull(CollisionDetector.GetCollisionInfo(circle, quarterMainDirection));
     Assert.IsNull(CollisionDetector.GetCollisionInfo(circle, quarterSecondDirection));
 }
 private void TestInTouch(RigidCircle circle, RigidCircleQuarter quarterMainDirection, RigidCircleQuarter quarterSecondDirection, CollisionInfo expected)
 {
     Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(circle, quarterMainDirection));
     Assert.AreEqual(expected, CollisionDetector.GetCollisionInfo(circle, quarterSecondDirection));
 }
 private static void DrawCircle(RigidCircle shape, Pen strokePen, Graphics g)
 {
     g.DrawEllipse(strokePen,
                   shape.Center.X - shape.Radius, shape.Center.Y - shape.Radius,
                   shape.Diameter, shape.Diameter);
 }
Example #26
0
        public void TestCircleAndAABBAreNotInTouch()
        {
            var circle = new RigidCircle(new Vector(10, -10), 5, true, true);

            Assert.IsNull(CollisionDetector.GetCollisionInfo(circle, MainAABB));
        }
        public void TestTwoCirclesAreNotInTouch()
        {
            var first = new RigidCircle(new Vector(50, 0), 10, true, true);

            Assert.IsNull(CollisionDetector.GetCollisionInfo(first, MainCircle));
        }
Example #28
0
 private static float[] AreCollide(Vector objectPosition, Vector objectVelocity, RigidCircle circle)
 {
     return(GetPenetrationTimeWithMovingCircle(objectPosition, objectVelocity, circle, Vector.ZeroVector));
 }