public static bool CircleLineIntersection(Circle2D c, Line2D l)
        {
            var a1 = new Vector2D(c.Point.X - c.Radius, c.Point.Y - c.Radius);
            var a2 = new Vector2D(c.Point.X + c.Radius, c.Point.Y + c.Radius);

            if (BoundingBoxIntersection(a1, a2, l.A, l.B))
            {
                var slope = l.Slope;
                double inverseSlope;

                if (slope == null || (double) slope == 0)
                {
                    // the bounding box already determined that an intersection has been made.
                    return true;
                }

                // slightly more complicated... need to create a tangent line. and find the distance.
                inverseSlope = 1 / (double)slope;

                // y= mx+b
                // b = circle.y, x = circle .x
                Line2D l2 = new Line2D();
                l2.A  = new Vector2D(c.Point.X, c.Point.Y);
                l2.B.X = c.Point.X + c.Radius;
                l2.B.Y = c.Point.Y + inverseSlope * (c.Point.X + c.Radius);
                var p = LineLineIntersection(l, l2);

                if (p != null)
                {
                    var d = new Line2D(c.Point, p);
                    if (d.Length < c.Radius)
                        return true;
                    return false;
                }

                Line2D l3 = new Line2D();
                l2.A = new Vector2D(c.Point.X, c.Point.Y);
                l2.B.X = c.Point.X - c.Radius;
                l2.B.Y = c.Point.Y + inverseSlope * (c.Point.X - c.Radius);
                var q = LineLineIntersection(l, l2);

                if (q != null)
                {
                    var d = new Line2D(c.Point, q);
                    if (d.Length < c.Radius)
                        return true;
                    return false;
                }

            }

            return false;
        }
 public static bool CircleCircleIntersection(Circle2D a, Circle2D b)
 {
     var l = new Line2D(a.Point, b.Point);
     return l.Length < (a.Radius + b.Radius);
 }
 public static bool CircleContainsVertex(Circle2D a, Vector2D b)
 {
     var l = new Line2D(a.Point, b);
     return l.Length < a.Radius;
 }
 public static List<Vector2D> PolygonLineIntersection(Polygon2D polygon, Line2D intersectLine)
 {
     return
         polygon.Lines.Select(line => LineLineIntersection(line, intersectLine)).Where(point => point != null).
             ToList();
 }
        public static Vector2D LineLineIntersection(Line2D l1, Line2D l2)
        {
            if (BoundingBoxIntersection(l1.A,l1.B, l2.A,l2.B))
            {
                // if the slopes are not null
                if (l1.Slope != null && l2.Slope != null)
                {
                    // and the slopes are not equal
                    if (Math.Abs((double)l1.Slope - (double)l2.Slope) < double.Epsilon)
                    {
                        return null;
                    }
                    // if the points form a bounding box

                    // solve for m1x+b1 = m2x+b2
                    // m1x = m2x + b2 - b1
                    // m1x - m2x = b2 - b1
                    // (m1 - m2)x = b2-b1

                    // y = mx+b
                    // m1x+b1 = m2x+b2
                    // m1x = m2x+b2-b1
                    // m1x - m2x = b2-b1
                    // (m1-m2)x = b2-b1
                    // x = (b2-b1)/(m1-m2)
                    // x = (b2-b1)/((dy1/dx1)-(dy2-dx2))

                    double? x = (l2.YIntercept - l1.YIntercept) / ((double)l1.Slope - (double)l2.Slope);

                    double? y = l1.Slope * x + l1.YIntercept;

                    if (x != null) if (y != null) return new Vector2D((double)x, (double)y);
                }

                else if (l1.Slope == null && l2.Slope != null)
                {
                    double? y = l2.Slope * l1.A.X + l2.YIntercept;
                    if (y != null) return new Vector2D(l1.A.X, (double)y);
                }

                else if (l1.Slope != null && l2.Slope == null)
                {
                    double? y = l1.Slope * l2.A.X + l1.YIntercept;
                    if (y != null) return new Vector2D(l2.A.X, (double)y);
                }
            }

            return null;
        }
        private void DrawWall(Wall w)
        {
            var wTex = ContentManager.Instance[w.WallTexture.TextureTag];
              GL.BindTexture(TextureTarget.Texture2D, wTex.glID);

              double total = 0;
              foreach (var wx in w.Area.Lines) total += wx.Length;

              double runningTotal = 0;

              var wt = w.WallTexture;

              SetupTexture(wt);

              var c = w.Area.Center;

              GL.Begin(BeginMode.Quads);
              foreach (var wall in w.Area.Lines)
              {
            var l1 = new Line2D(c, wall.A);
            var l2 = new Line2D(c, wall.B);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);

            GL.TexCoord2((runningTotal / total), _gameInstance.CurrentLevel.BaseFloorHeight / wTex.Height);
            GL.Vertex3(wall.A.X, _gameInstance.CurrentLevel.BaseFloorHeight, wall.A.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);

            GL.TexCoord2(((wall.Length + runningTotal) / total), _gameInstance.CurrentLevel.BaseFloorHeight / wTex.Height);
            GL.Vertex3(wall.B.X, _gameInstance.CurrentLevel.BaseFloorHeight, wall.B.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);

            GL.TexCoord2(((wall.Length + runningTotal) / total), _gameInstance.CurrentLevel.BaseCeilingHeight / wTex.Height);
            GL.Vertex3(wall.B.X, _gameInstance.CurrentLevel.BaseCeilingHeight, wall.B.Y);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);

            GL.TexCoord2((runningTotal / total), _gameInstance.CurrentLevel.BaseCeilingHeight / wTex.Height);
            GL.Vertex3(wall.A.X, _gameInstance.CurrentLevel.BaseCeilingHeight, wall.A.Y);

            runningTotal += wall.Length;
              }
              GL.End();
        }
        private void DrawPlatform(Platform p)
        {
            var floorTex = ContentManager.Instance[p.FloorTexture.TextureTag];
              var ceilingTex = ContentManager.Instance[p.CeilingTexture.TextureTag];
              var wallTex = ContentManager.Instance[p.WallTexture.TextureTag];

              var area = p.Area.Triangulate();

              var center = p.Area.Center;

              SetupTexture(p.FloorTexture);

              GL.BindTexture(TextureTarget.Texture2D, floorTex.glID);
              GL.Begin(BeginMode.Triangles);

              foreach (var renderTriangle in area)
              {
            GL.Normal3(0, 1, 0);

            GL.TexCoord2(renderTriangle.Points[0].X / floorTex.Width, renderTriangle.Points[0].Y / floorTex.Height);
            GL.Vertex3(renderTriangle.Points[0].X, p.FloorHeight, renderTriangle.Points[0].Y);

            GL.TexCoord2(renderTriangle.Points[1].X / floorTex.Width, renderTriangle.Points[1].Y / floorTex.Height);
            GL.Vertex3(renderTriangle.Points[1].X, p.FloorHeight, renderTriangle.Points[1].Y);

            GL.TexCoord2(renderTriangle.Points[2].X / floorTex.Width, renderTriangle.Points[2].Y / floorTex.Height);
            GL.Vertex3(renderTriangle.Points[2].X, p.FloorHeight, renderTriangle.Points[2].Y);
              }
              GL.End();

              SetupTexture(p.CeilingTexture);

              GL.BindTexture(TextureTarget.Texture2D, ceilingTex.glID);
              GL.Begin(BeginMode.Triangles);
              foreach (var renderTriangle in area)
              {
            GL.Normal3(0, -1, 0);

            GL.TexCoord2(renderTriangle.Points[0].X / ceilingTex.Width, renderTriangle.Points[0].Y / ceilingTex.Height);
            GL.Vertex3(renderTriangle.Points[0].X, p.CeilingHeight, renderTriangle.Points[0].Y);

            GL.TexCoord2(renderTriangle.Points[2].X / ceilingTex.Width, renderTriangle.Points[2].Y / ceilingTex.Height);
            GL.Vertex3(renderTriangle.Points[2].X, p.CeilingHeight, renderTriangle.Points[2].Y);

            GL.TexCoord2(renderTriangle.Points[1].X / ceilingTex.Width, renderTriangle.Points[1].Y / ceilingTex.Height);
            GL.Vertex3(renderTriangle.Points[1].X, p.CeilingHeight, renderTriangle.Points[1].Y);

              }

              GL.End();

              SetupTexture(p.WallTexture);

              GL.BindTexture(TextureTarget.Texture2D, ContentManager.Instance[p.WallTexture.TextureTag].glID);
              GL.Begin(BeginMode.Quads);

              double total = 0;
              foreach (var wx in p.Area.Lines) total += wx.Length;

              double runningTotal = 0;

              foreach (var wall in p.Area.Lines)
              {
            var l1 = new Line2D(center, wall.A);
            var l2 = new Line2D(center, wall.B);
            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);

            GL.TexCoord2((runningTotal / total), p.FloorHeight / wallTex.Height);
            GL.Vertex3(wall.A.X, p.FloorHeight, wall.A.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);
            GL.TexCoord2((wall.Length + runningTotal) / total, p.FloorHeight / wallTex.Height);
            GL.Vertex3(wall.B.X, p.FloorHeight, wall.B.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);
            GL.TexCoord2((wall.Length + runningTotal) / total, p.CeilingHeight / wallTex.Height);
            GL.Vertex3(wall.B.X, p.CeilingHeight, wall.B.Y);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);
            GL.TexCoord2((runningTotal / total), p.CeilingHeight / wallTex.Height);
            GL.Vertex3(wall.A.X, p.CeilingHeight, wall.A.Y);

            runningTotal += wall.Length;

              }
              GL.End();
        }
        private void DrawCorridor(Corridor c)
        {
            var floorTex = ContentManager.Instance[c.FloorTexture.TextureTag];
              var ceilingTex = ContentManager.Instance[c.CeilingTexture.TextureTag];
              var cWallTex = ContentManager.Instance[c.CeilingWallTexture.TextureTag];
              var cFloorTex = ContentManager.Instance[c.FloorWallTexture.TextureTag];

              var area = c.Area.Triangulate();

              SetupTexture(c.FloorTexture);
              GL.BindTexture(TextureTarget.Texture2D, floorTex.glID);
              GL.Begin(BeginMode.Triangles);

              var center = c.Area.Center;

              foreach (var renderTriangle in area)
              {
            GL.Normal3(0, 1, 0);

            GL.TexCoord2(renderTriangle.Points[0].X / floorTex.Width, renderTriangle.Points[0].Y / floorTex.Height);
            GL.Vertex3(renderTriangle.Points[0].X, c.FloorHeight, renderTriangle.Points[0].Y);

            GL.TexCoord2(renderTriangle.Points[1].X / floorTex.Width, renderTriangle.Points[1].Y / floorTex.Height);
            GL.Vertex3(renderTriangle.Points[1].X, c.FloorHeight, renderTriangle.Points[1].Y);

            GL.TexCoord2(renderTriangle.Points[2].X / floorTex.Width, renderTriangle.Points[2].Y / floorTex.Height);
            GL.Vertex3(renderTriangle.Points[2].X, c.FloorHeight, renderTriangle.Points[2].Y);
              }
              GL.End();

              SetupTexture(c.CeilingTexture);
              GL.BindTexture(TextureTarget.Texture2D, ceilingTex.glID);
              GL.Begin(BeginMode.Triangles);

              foreach (var renderTriangle in area)
              {
            GL.Normal3(0, -1, 0);

            GL.TexCoord2(renderTriangle.Points[0].X / ceilingTex.Width, renderTriangle.Points[0].Y / ceilingTex.Height);
            GL.Vertex3(renderTriangle.Points[0].X, c.CeilingHeight, renderTriangle.Points[0].Y);

            GL.TexCoord2(renderTriangle.Points[2].X / ceilingTex.Width, renderTriangle.Points[2].Y / ceilingTex.Height);
            GL.Vertex3(renderTriangle.Points[2].X, c.CeilingHeight, renderTriangle.Points[2].Y);

            GL.TexCoord2(renderTriangle.Points[1].X / ceilingTex.Width, renderTriangle.Points[1].Y / ceilingTex.Height);
            GL.Vertex3(renderTriangle.Points[1].X, c.CeilingHeight, renderTriangle.Points[1].Y);

              }

              GL.End();

              SetupTexture(c.CeilingWallTexture);

              GL.BindTexture(TextureTarget.Texture2D, cWallTex.glID);

              GL.Begin(BeginMode.Quads);

              double total = 0;
              foreach (var wx in c.Area.Lines) total += wx.Length;

              double runningTotal = 0;

              foreach (var wall in c.Area.Lines)
              {
            var l1 = new Line2D(center, wall.A);
            var l2 = new Line2D(center, wall.B);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);

            GL.TexCoord2((runningTotal / total), _gameInstance.CurrentLevel.BaseFloorHeight / cWallTex.Height);
            GL.Vertex3(wall.A.X, _gameInstance.CurrentLevel.BaseFloorHeight, wall.A.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);
            GL.TexCoord2((wall.Length + runningTotal) / total, _gameInstance.CurrentLevel.BaseFloorHeight / cWallTex.Height);
            GL.Vertex3(wall.B.X, _gameInstance.CurrentLevel.BaseFloorHeight, wall.B.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);
            GL.TexCoord2((wall.Length + runningTotal) / total, c.FloorHeight / cWallTex.Height);
            GL.Vertex3(wall.B.X, c.FloorHeight, wall.B.Y);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);
            GL.TexCoord2(runningTotal / total, c.FloorHeight / cWallTex.Height);
            GL.Vertex3(wall.A.X, c.FloorHeight, wall.A.Y);
              }
              GL.End();

              SetupTexture(c.FloorWallTexture);

              GL.BindTexture(TextureTarget.Texture2D, cFloorTex.glID);

              GL.Begin(BeginMode.Quads);
              foreach (var wall in c.Area.Lines)
              {
            var l1 = new Line2D(center, wall.A);
            var l2 = new Line2D(center, wall.B);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);

            GL.TexCoord2((runningTotal) / total, c.CeilingHeight / cFloorTex.Height);
            GL.Vertex3(wall.A.X, c.CeilingHeight, wall.A.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);

            GL.TexCoord2((wall.Length + runningTotal) / total, c.CeilingHeight / cFloorTex.Height);
            GL.Vertex3(wall.B.X, c.CeilingHeight, wall.B.Y);

            GL.Normal3(l2.Normal.X, 0, l2.Normal.Y);

            GL.TexCoord2((wall.Length + runningTotal) / total, _gameInstance.CurrentLevel.BaseCeilingHeight / cFloorTex.Height);
            GL.Vertex3(wall.B.X, _gameInstance.CurrentLevel.BaseCeilingHeight, wall.B.Y);

            GL.Normal3(l1.Normal.X, 0, l1.Normal.Y);
            GL.TexCoord2((runningTotal) / total, _gameInstance.CurrentLevel.BaseCeilingHeight / cFloorTex.Height);
            GL.Vertex3(wall.A.X, _gameInstance.CurrentLevel.BaseCeilingHeight, wall.A.Y);

            runningTotal += wall.Length;

              }
              GL.End();
        }