private static Vector2D UnProject(Vector2D point, Vector2D windowSize, Vector2D camOrigin, Vector2D camSize)
        {
            var xScale = point.X / windowSize.X;
            var yScale = point.Y / windowSize.Y;

            return new Vector2D(
                (xScale * camSize.X) + camOrigin.X,
                (yScale * camSize.Y) + camOrigin.Y);
        }
        public SpawnPoint(Vector2D position, double height, double initialAngle)
            : base()
        {
            Position = position;
            Z = height;
            InitialAngle = initialAngle;

            _isVisible = true;

            _textureHandle = "SpawnPoint";
        }
        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 BoundingBoxIntersection(Vector2D A1, Vector2D A2, Vector2D B1, Vector2D B2)
        {
            double x1min = Math.Min(A1.X, A2.X);
            double x1max = Math.Max(A1.X, A2.X);
            double y1min = Math.Min(A1.Y, A2.Y);
            double y1max = Math.Max(A1.Y, A2.Y);

            double x2min = Math.Min(B1.X, B2.X);
            double x2max = Math.Max(B1.X, B2.X);
            double y2min = Math.Min(B1.Y, B2.Y);
            double y2max = Math.Max(B1.Y, B2.Y);

            bool x1Overlapx2 = (Between(x2min, x2max, x1min) || Between(x2min, x2max, x1max));
            bool y1Overlapy2 = (Between(y2min, y2max, y1min) || Between(y2min, y2max, y1max));
            bool x2Overlapx1 = (Between(x1min, x1max, x2min) || Between(x1min, x1max, x2max));
            bool y2Overlapy1 = (Between(y1min, y1max, y2min) || Between(y1min, y1max, y2max));

            return (x1Overlapx2 || x2Overlapx1) && (y1Overlapy2 || y2Overlapy1);
        }
 public Circle2D(Vector2D point, double radius)
 {
     Point = point;
     Radius = radius;
 }
 public Circle2D()
 {
     Point = new Vector2D();
     Radius = 0;
 }
 public double Dot(Vector2D b)
 {
     var a = this;
     return (a.X * b.X + a.Y * b.Y);
 }
 public double Distance(Vector2D b)
 {
     Vector2D a = this;
     return Math.Sqrt((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y));
 }
 public double Cross(Vector2D b)
 {
     var a = this;
     return (a.X * b.Y) - (a.Y * b.X);
 }
 public Line2D(Vector2D a, Vector2D b)
 {
     A = a;
     B = b;
 }
 public static bool PointInTriangle(Vector2D p, Vector2D a, Vector2D b, Vector2D c)
 {
     return PointsOnSameSide(p, a, b, c) && PointsOnSameSide(p, b, a, c) && PointsOnSameSide(p, c, a, b);
 }
 private static Vector2D VSub(Vector2D a, Vector2D b)
 {
     return new Vector2D(a.X - b.X, a.Y - b.Y);
 }
 public static bool CircleContainsVertex(Circle2D a, Vector2D b)
 {
     var l = new Line2D(a.Point, b);
     return l.Length < a.Radius;
 }
 private static Vector2D VAdd(Vector2D a, Vector2D b)
 {
     return new Vector2D(a.X + b.X, a.Y + b.Y);
 }
 private static bool PointsOnSameSide(Vector2D p1, Vector2D p2, Vector2D a, Vector2D b)
 {
     double cp1 = CrossProduct(VSub(b, a), VSub(p1, a));
     double cp2 = CrossProduct(VSub(b, a), VSub(p2, a));
     return (cp1 * cp2) >= 0; // they have the same sign if on the same side of the line
 }
 private static double CrossProduct(Vector2D p1, Vector2D p2)
 {
     return (p1.X * p2.Y) - (p1.Y * p2.X);
 }
 public SpawnPoint CreateSpawnPoint(Vector2D position, double height, double initialAngle)
 {
     return new SpawnPoint(position,height, initialAngle);
 }
 public ActionMovePlayer(Player p, Vector2D velocity, bool isJumping)
 {
     PlayerID = p.UniqueId;
     Velocity = velocity;
     IsJumping = isJumping;
 }
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            var nmx = Mouse.X;
            var nmy = Mouse.Y;

            var dmx = (double)nmx - 320;
            var dmy = (double)nmy - 240;

            _gi.Players[0].Angle += dmx / 10;
            _gi.Players[0].LookAngle -= dmy / 15;

            var p = PointToScreen(new System.Drawing.Point(320, 240));
            SetCursorPos(p.X, p.Y);

            var velocityVector = new Vector2D();

            //
            bool moving = false;
            if ((GetAsyncKeyState(Keys.W) & 0x8000) != 0)
            {
                moving = true;
                velocityVector.X += Math.Cos(_gi.Players[0].Angle * Math.PI / 180);
                velocityVector.Y += Math.Sin(_gi.Players[0].Angle * Math.PI / 180);

            }

            if ((GetAsyncKeyState(Keys.S) & 0x8000) != 0)
            {
                moving = true;
                velocityVector.X += Math.Cos((_gi.Players[0].Angle + 180) * Math.PI / 180);
                velocityVector.Y += Math.Sin((_gi.Players[0].Angle + 180) * Math.PI / 180);

            }

            if ((GetAsyncKeyState(Keys.A) & 0x8000) != 0)
            {
                moving = true;
                velocityVector.X += Math.Cos((_gi.Players[0].Angle - 90) * Math.PI / 180);
                velocityVector.Y += Math.Sin((_gi.Players[0].Angle - 90) * Math.PI / 180);

            }

            if ((GetAsyncKeyState(Keys.D) & 0x8000) != 0)
            {
                moving = true;
                velocityVector.X += Math.Cos((_gi.Players[0].Angle + 90) * Math.PI / 180);
                velocityVector.Y += Math.Sin((_gi.Players[0].Angle + 90) * Math.PI / 180);

            }

            bool isjumping = false;
            if ((GetAsyncKeyState(Keys.Space) & 0x8000) != 0)
            {
                moving = true;
               isjumping = true;
            }

            if ((GetAsyncKeyState(Keys.Escape) & 0x8000) != 0)
                this.Exit();

            var moveAction = new Unicorn21.GameObjects.GameActions.ActionMovePlayer(_gi.Players[0], velocityVector, isjumping);

            if(moving)
                _gi.AddAction(moveAction);
            _gi.DoGame(e.Time);

            base.OnUpdateFrame(e);
        }
        // this is sloppy as f**k... but should work... rewrite later
        public static bool IsPointInPolygon(Polygon2D polygon, Vector2D point)
        {
            //double minX = polygon.Points[0].X;
            //double minY = polygon.Points[0].Y;
            //double maxX = polygon.Points[0].X;
            //double maxY = polygon.Points[0].Y;

            //for (int i = 1; i < polygon.Points.Count; i++)
            //{
            //    if (polygon.Points[i].X < minX)
            //        minX = polygon.Points[i].X;
            //    if (polygon.Points[i].Y < minY)
            //        minY = polygon.Points[i].Y;
            //    if (polygon.Points[i].X > maxX)
            //        maxX = polygon.Points[i].X;
            //    if (polygon.Points[i].Y > maxY)
            //        maxY = polygon.Points[i].Y;
            //}

            //var r = new Random();
            //var p = new Vector2D();
            //while (true)
            //{
            //    var rx = r.NextDouble() * double.MaxValue;
            //    var ry = r.NextDouble() * double.MaxValue;

            //    if ((minX <= rx && rx <= maxX) || (minY <= ry && ry <= maxY)) continue;
            //    p.X = rx;
            //    p.Y = ry;
            //    break;
            //}
            //var q = PolygonLineIntersection(polygon, new Line2D(p, point));
            //return q.Count % 2 != 0;

            List<Polygon2D> tris = polygon.Triangulate();

            foreach (Polygon2D polygon2D in tris)
            {
                if (PointInTriangle(point, polygon2D.Points[0], polygon2D.Points[1], polygon2D.Points[2]))
                    return true;
            }
            return false;
        }