/// <summary> /// Uses a FloodFill scanline algorithm to get a targets bounds /// </summary> public MotionHelper GetBoundsFromMotion(ref byte[,] motion, Point size, Point seed) { MotionHelper helper = new MotionHelper(motion, size.X, size.Y, seed.X, seed.Y); DoNextScanLine(seed.X, seed.Y, ref helper); // +2 and +1 are for creating an empty box around the whole shape, (1's never at the end /start of an array) helper.Shape = new byte[helper.MaxX - helper.MinX + 4, helper.MaxY - helper.MinY + 4]; for (int x = helper.MinX; x < helper.MaxX; x++) for (int y = helper.MinY; y < helper.MaxY; y++) if (helper.Motion[x, y] == 2) { helper.Shape[x - helper.MinX + 2, y - helper.MinY + 2] = 1; } return helper; }
/// <summary> /// Recursave function for scanlines /// </summary> public void DoNextScanLine(int x, int y, ref MotionHelper motion) { // 2 3 4 // 2 O O O // 3 O X O // 4 O O O if (x >= motion.Width || y >= motion.Height) return; if (motion.Motion[x, y] == 0) return; if (x > motion.MaxX) motion.MaxX = x; if (x < motion.MinX) motion.MinX = x; if (y > motion.MaxY) motion.MaxY = y; if (y < motion.MinY) motion.MinY = y; int y1; //draw current scanline from start position to the top y1 = y; while (y1 < motion.Height && motion.Motion[x, y1] == 1) { motion.Motion[x, y1] = 2; if (y1 > motion.MaxY) motion.MaxY = y1; y1++; } //draw current scanline from start position to the bottom y1 = y - 1; while (y1 >= 0 && motion.Motion[x, y1] == 1) { motion.Motion[x, y1] = 2; if (y1 < motion.MinY) motion.MinY = y1; y1--; } //test for new scanlines to the left y1 = y; while (y1 < motion.Height && (motion.Motion[x, y1] == 2)) { if (x > 0 && motion.Motion[x -1, y1] == 1) { DoNextScanLine(x - 1, y1, ref motion); } y1++; } y1 = y - 1; while (y1 >= 0 && (motion.Motion[x, y1] == 2)) { if (x > 0 && motion.Motion[x - 1, y1] == 1) { DoNextScanLine(x - 1, y1, ref motion); } y1--; } //test for new scanlines to the right y1 = y; while (y1 < motion.Height && (motion.Motion[x, y1] == 2)) { if (x < motion.Width - 1 && motion.Motion[x + 1, y1] == 1) { DoNextScanLine(x + 1, y1, ref motion); } y1++; } y1 = y - 1; while (y1 >= 0 && (motion.Motion[x, y1] == 2)) { if (x < motion.Width - 1 && motion.Motion[x + 1, y1] == 1) { DoNextScanLine(x + 1, y1, ref motion); } y1--; } }