//sort grid squares by x coordinate
        int IComparable.CompareTo(object obj)
        {
            collision_grid_square sq = (collision_grid_square)obj;

            if (this.ix > sq.ix)
            {
                return(1);
            }
            if (this.ix < sq.ix)
            {
                return(-1);
            }
            return(0);
        }
        public collision_grid(Environment e, int _coarseness)
        {
            double mapx = 0.0, mapy = 0.0;

            foreach (Wall w in e.walls)
            {
                if (w.line.p1.x > mapx)
                {
                    mapx = w.line.p1.x;
                }
                if (w.line.p2.x > mapx)
                {
                    mapx = w.line.p2.x;
                }
                if (w.line.p1.y > mapy)
                {
                    mapy = w.line.p1.y;
                }
                if (w.line.p2.y > mapy)
                {
                    mapy = w.line.p2.y;
                }
            }
            //add some slack..
            mapx += 50;
            mapy += 50;

            coarseness = _coarseness;

            //mapx = 618 * 4;
            //mapy = 885 * 4;
            //coarseness = 20*4;

            //Console.WriteLine(mapx.ToString()+ " " + mapy.ToString() + " " + coarseness.ToString());

            gridx = (double)mapx / (double)coarseness;
            gridy = (double)mapy / (double)coarseness;

            grid = new collision_grid_square[coarseness, coarseness];
            for (int x = 0; x < coarseness; x++)
            {
                for (int y = 0; y < coarseness; y++)
                {
                    grid[x, y] = new collision_grid_square(x, y, x * gridx, y * gridy);
                }
            }

            //Console.WriteLine("Grid square x_size = " + gridx.ToString());
            //Console.WriteLine("Grid square y_size = " + gridy.ToString());
        }
        public collision_grid(Environment e, int _coarseness)
        {
            double mapx = 0.0, mapy = 0.0;

            foreach (Wall w in e.walls)
            {
                if (w.line.p1.x > mapx)
                    mapx = w.line.p1.x;
                if (w.line.p2.x > mapx)
                    mapx = w.line.p2.x;
                if (w.line.p1.y > mapy)
                    mapy = w.line.p1.y;
                if (w.line.p2.y > mapy)
                    mapy = w.line.p2.y;
            }
            //add some slack..
            mapx += 50;
            mapy += 50;

            coarseness = _coarseness;

            //mapx = 618 * 4;
            //mapy = 885 * 4;
            //coarseness = 20*4;

            //Console.WriteLine(mapx.ToString()+ " " + mapy.ToString() + " " + coarseness.ToString());

            gridx = (double)mapx / (double)coarseness;
            gridy = (double)mapy / (double)coarseness;

            grid = new collision_grid_square[coarseness, coarseness];
            for (int x = 0; x < coarseness; x++)
                for (int y = 0; y < coarseness; y++)
                    grid[x, y] = new collision_grid_square(x, y, x * gridx, y * gridy);

            //Console.WriteLine("Grid square x_size = " + gridx.ToString());
            //Console.WriteLine("Grid square y_size = " + gridy.ToString());
        }
        //ray-casting for detecting collisions with walls using the grid stucture
        public List <collision_grid_square> cast_ray(double sx, double sy, double ex, double ey)
        {
            List <collision_grid_square> intersect = new List <collision_grid_square>();

            double bsx = sx;
            double bsy = sy;
            double bex = ex;
            double bey = ey;

            double maxx = gridx * (coarseness) - 0.001;
            double maxy = gridy * (coarseness) - 0.001;

            double tslope = (ey - sy) / (ex - sx);

            //clip ray within grid...
            if (ex < 0.0)
            {
                ey = sy + tslope * (0 - sx);
                ex = 0.0;
            }
            if (ex > maxx)
            {
                ey = sy + tslope * (maxx - sx);
                ex = maxx;
            }
            if (ey < 0.0)
            {
                ex = sx + (1.0 / tslope) * (0 - sy);
                ey = 0.0;
            }
            if (ey > maxy)
            {
                ex = sx + (1.0 / tslope) * (maxy - sy);
                ey = maxy;
            }

            //calculate special vertical and horizontal cases...
            double x0 = sx / gridx;
            double x1 = ex / gridx;
            double y0 = sy / gridy;
            double y1 = ey / gridy;

            //horizontal line, easy to calculate
            if (y0 == y1)
            {
                bool reverse = false;

                int sxi = (int)x0;
                int exi = (int)x1;
                int yi  = (int)y0;

                if (exi < sxi)
                {
                    int temp = exi;
                    exi     = sxi;
                    sxi     = temp;
                    reverse = true;
                }

                for (int xi = sxi; xi <= exi; xi++)
                {
                    intersect.Add(grid[xi, yi]);
                }

                if (reverse)
                {
                    intersect.Reverse();
                }

                return(intersect);
            }

            //vertical line, easy to calculate
            if (x0 == x1)
            {
                bool reverse = false;
                int  syi     = (int)y0;
                int  eyi     = (int)y1;
                int  xi      = (int)x0;

                if (eyi < syi)
                {
                    int temp = eyi;
                    eyi     = syi;
                    syi     = temp;
                    reverse = true;
                }

                for (int yi = syi; yi <= eyi; yi++)
                {
                    intersect.Add(grid[xi, yi]);
                }

                if (reverse)
                {
                    intersect.Reverse();
                }

                return(intersect);
            }
            //we've handled the special vertical and horizontal cases...

            bool rev = false;

            //make sure we are going left-to-right
            //if not, swap the points
            if (sx > ex)
            {
                double temp = sx;
                sx  = ex;
                ex  = temp;
                rev = true;

                temp = ey;
                ey   = sy;
                sy   = temp;
            }

            //does our line slope up or down?
            bool up = true;

            if (sy > ey)
            {
                up = false;
            }

            collision_grid_square to_add = null;

            //  try
            //  {
            //add the current grid square
            to_add = grid[(int)(sx / gridx), (int)(sy / gridy)];
            // }
            //catch (Exception e)
            //{
            //    Console.WriteLine(bsx.ToString() + " " + bsy.ToString() + " " + bex.ToString() + " " + bey.ToString());
            //    Console.WriteLine(sx.ToString() + " " + sy.ToString() + " " + ex.ToString() + " " + ey.ToString());
            //    Console.WriteLine(e.Source);
            //    Console.WriteLine(e.Message);
            //    Console.WriteLine(e.StackTrace);

            //    Console.WriteLine("own sqaure...");
            //    throw (e);
            //}
            to_add.ix = sx;
            intersect.Add(to_add);

            double slope    = Math.Abs((ey - sy) / (ex - sx));
            double invslope = 1.0 / slope;

            //vertical intersections
            //we must find the first intersection now

            double py   = Math.Floor(sy / gridy) * gridy;
            double incy = gridy;

            if (up)
            {
                py += gridy + 0.001;
            }
            else
            {
                py  -= 0.001;
                incy = -incy;
            }
            double px   = sx + Math.Abs((py - sy)) / slope;
            double incx = invslope * gridy;

            while (true)
            {
                if (px > ex)
                {
                    break;
                }

                if (up)
                {
                    if (py > ey)
                    {
                        break;
                    }
                }
                else
                {
                    if (py < ey)
                    {
                        break;
                    }
                }

                try
                {
                    to_add = grid[(int)(px / gridx), (int)(py / gridy)];
                }
                catch (Exception e)
                {
                    Console.WriteLine(bsx.ToString() + " " + bsy.ToString() + " " + bex.ToString() + " " + bey.ToString());
                    Console.WriteLine(sx.ToString() + " " + sy.ToString() + " " + ex.ToString() + " " + ey.ToString());

                    Console.WriteLine("Vertical..." + ((int)(px / gridx)).ToString() + " " + ((int)(py / gridy)).ToString());
                    Console.WriteLine(px.ToString() + " " + py.ToString() + " " + ex.ToString() + " " + ey.ToString());
                    Console.WriteLine(e.Source);
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.StackTrace);
                    //throw (e);
                }
                to_add.ix = px;
                intersect.Add(to_add);

                px += incx;
                py += incy;
            }

            //horizontal intersections...
            slope    = (ey - sy) / (ex - sx);
            invslope = 1.0 / slope;

            px = Math.Floor(sx / gridx) * gridx + gridx + 0.01;
            py = sy + (px - sx) * slope;

            incx = gridx;
            incy = gridx * slope;

            while (true)
            {
                if (px > ex)
                {
                    break;
                }

                if (up)
                {
                    if (py > ey)
                    {
                        break;
                    }
                }
                else
                {
                    if (py < ey)
                    {
                        break;
                    }
                }
                try
                {
                    to_add = grid[(int)(px / gridx), (int)(py / gridy)];
                }
                catch (Exception e)
                {
                    Console.WriteLine(bsx.ToString() + " " + bsy.ToString() + " " + bex.ToString() + " " + bey.ToString());
                    Console.WriteLine(sx.ToString() + " " + sy.ToString() + " " + ex.ToString() + " " + ey.ToString());

                    Console.WriteLine("Horizontal..." + ((int)(px / gridx)).ToString() + " " + ((int)(py / gridy)).ToString());
                    Console.WriteLine(px.ToString() + " " + py.ToString() + " " + ex.ToString() + " " + ey.ToString());
                    Console.WriteLine(e.Source);
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.StackTrace);
                    throw (e);
                }

                to_add.ix = px;
                if (!intersect.Contains(to_add))
                {
                    intersect.Add(to_add);
                }

                px += incx;
                py += incy;
            }
            //now we sort the grid squares so they are in
            //increasing x order
            intersect.Sort();

            //but if our line actually goes right to left,
            //we need to reverse the order
            if (rev)
            {
                intersect.Reverse();
            }

            return(intersect);
        }