public static double[] GreySL(Projector projector, Camera camera, PointF[] corners, Bitmap nolight, Color fullColor, bool vertical, int offset) { uint[] horizontal = new uint[corners.Length]; int max = (int)Math.Floor(Math.Log((vertical ? projector.bitmap.Width : projector.bitmap.Height), 2)) + 1; int subdivisions = 1; var nol = Classifier(nolight); for (var step = 0; step < max - 4; step++) { projector.DrawBackground(Color.Black); camera.TakePicture(2).Dispose(); projector.DrawGrey(step, vertical, offset, fullColor); var light = camera.TakePicture(2); var classifier = nol(light, step); int idx = 0; Bitmap withCorners = null; foreach (var point in corners) { var hit = classifier(point); var h = horizontal[idx]; h = h << 1; h = h | (hit ? (uint)1 : (uint)0); horizontal[idx] = h; idx++; if (DebugWindow != null) { withCorners = light; QuickDraw.Start(withCorners) .Color(hit ? Color.Gray : Color.White) .DrawPoint(point.X, point.Y, 5) .Finish(); } } if (DebugWindow != null) DebugWindow.DrawBitmap(withCorners); light.Dispose(); subdivisions++; } var result = horizontal .Select(h => { uint num = h; uint mask; for (mask = num >> 1; mask != 0; mask = mask >> 1) { num = num ^ mask; } return num; }) .Select(row => (1 - (double)row / Math.Pow(2, max - 4)) * (vertical ? projector.bitmap.Width : projector.bitmap.Height)).ToArray(); return result; }