public Bitmap Scan(Bitmap baseImage, Rayable drawnObject, Vector3 pov, float lengthCutoff = 50)
        {
            Bitmap image = new Bitmap(baseImage);

            for (int iy = 1; iy < resolution_Y; iy++)
            {
                for (int ix = 1; ix < resolution_X; ix++)
                {
                    RayResult result = Ray(RayDirection(ix, iy), drawnObject, pov, 0.005f, lengthCutoff, 50);
                    //int color = (int)((1 - (result.Closest /0.05f)) * 255);
                    //int color = (int)((1 - (result.RayLength / 20)) * 255);
                    //int color = (int)(( (result.RayLength/lengthCutoff)) * 255);
                    int color = (int)((1 - (result.Steps / 50f)) * 255);
                    if (color > 255 || result.RayLength > lengthCutoff)
                    {
                        color = 0;
                    }
                    if (color < 0)
                    {
                        color = 0;
                    }
                    //if(color>100)
                    {
                        Color color1 = Color.FromArgb(color, color, color);
                        //image.SetPixel(resolution_X-ix, resolution_Y-iy, color1);
                        image.SetPixel(ix, resolution_Y - iy, color1);
                        //DrawPixel(baseImage, color1, ix, resolution_Y - iy);
                    }
                }
            }
            return(image);
        }
        public float RayMarchScan(Vector3 Point, Rayable item)
        {
            Vector3 point = new Vector3(Point.x, Point.y, Point.z);

            if (true)
            {
                //if (point.x < 4f && point.x > -5f)
                {
                    //point.x = MathModulo(point.x+1f, 2f)-1f;
                }
                //if (point.y < 3f && point.y > -3f)
                {
                    //point.y = MathModulo(point.y, 2f);
                    //point.y = Math.Abs(point.y);
                }
                if (point.y < 2)
                {
                    //point.y = 2-point.y;
                }
                if (point.x + 5 < 0)
                {
                    //point.x = -point.x-10;
                }
                point.z = 1.5f - Math.Abs(point.z - 1.5f);

                point.x = 1.5f - Math.Abs(point.x - 1.5f);

                point = Mirror(point - new Vector3(0, 0, 0), 1) + new Vector3(0, 0, 0);
                point = Mirror(point - new Vector3(0, 0, 0), -1) + new Vector3(0, 0, 0);

                //point.z = 3.5f - Math.Abs(point.z - 3.5f);

                //point.x = 3.5f - Math.Abs(point.x - 3.5f);

                //if (point.y > 2){ point.y -= 2f;point.x -= 1f;}
                //point.y = Math.Abs(point.y);
                //point.z = Math.Abs(10 - point.z);
                //point.z = MathModulo(point.z, 1);
            }
            return(item.NearestPoint(point));
        }
        public RayResult Ray(Vector3 rayPoint, Rayable drawable, Vector3 pov, float precisionCutoff = 0.1f, float lengthCutoff = 20, int maxSteps = 20)
        {
            float   rayLength    = 0;
            int     steps        = 0;
            Vector3 rayPointNorm = rayPoint.Normalize;
            Vector3 rayPointNow  = pov * 1;
            float   closest      = RayMarchScan(rayPointNow, drawable);
            bool    enough       = false;

            while (!enough)
            {
                steps++;
                closest      = RayMarchScan(rayPointNow, drawable);
                rayLength   += closest;
                rayPointNow += rayPointNorm * closest;
                //if (closestNow < closest)

                //closest = closestNow;


                if (
                    (closest < precisionCutoff)

                    || (steps >= maxSteps)
                    )
                {
                    //DrawPixel(rayDirection * 2, 1 - closeness * 7);
                    //steps = 0;
                    enough = true;
                }
                if (rayLength > lengthCutoff)
                {
                    enough = true;                            //steps = maxSteps;
                }
            }
            return(new RayResult(steps, closest, rayLength));
        }