/// <summary> /// creates a circle shape /// </summary> /// <param name="centre_x"> /// centre x coordinate of the circle <see cref="System.Single"/> /// </param> /// <param name="centre_y"> /// centre y coordinate of the circle <see cref="System.Single"/> /// </param> /// <param name="radius"> /// radius of teh circle <see cref="System.Single"/> /// </param> /// <param name="circumference_steps"> /// number of steps to use when drawing the circle <see cref="System.Int32"/> /// </param> /// <returns> /// polygon representing a circle <see cref="polygon2D"/> /// </returns> public static polygon2D CreateCircle(float centre_x, float centre_y, float radius, int circumference_steps) { polygon2D circle = new polygon2D(); for (int i = 0; i < circumference_steps; i++) { float angle = i * (float)Math.PI * 2 / circumference_steps; float x = centre_x + (radius * (float)Math.Sin(angle)); float y = centre_y + (radius * (float)Math.Cos(angle)); circle.Add(x, y); } return(circle); }
/// <summary> /// detects a square around the centre dot on the calibration pattern /// </summary> /// <param name="dots">detected dots</param> /// <param name="centredots">returned dots belonging to the centre square</param> /// <returns>centre square</returns> private static polygon2D GetCentreSquare(hypergraph dots, ref List<calibrationDot> centredots) { centredots = new List<calibrationDot>(); // find the centre dot calibrationDot centre = null; int i = 0; while ((i < dots.Nodes.Count) && (centre == null)) { calibrationDot dot = (calibrationDot)dots.Nodes[i]; if (dot.centre) centre = dot; i++; } // look for the four surrounding dots List<calibrationDot> centre_dots = new List<calibrationDot>(); List<double> distances = new List<double>(); i = 0; for (i = 0; i < dots.Nodes.Count; i++) { calibrationDot dot = (calibrationDot)dots.Nodes[i]; if (!dot.centre) { double dx = dot.x - centre.x; double dy = dot.y - centre.y; double dist = Math.Sqrt(dx * dx + dy * dy); if (distances.Count == 4) { int index = -1; double max_dist = 0; for (int j = 0; j < 4; j++) { if (distances[j] > max_dist) { index = j; max_dist = distances[j]; } } if (dist < max_dist) { distances[index] = dist; centre_dots[index] = dot; } } else { distances.Add(dist); centre_dots.Add(dot); } } } polygon2D centre_square = null; if (centre_dots.Count == 4) { centre_square = new polygon2D(); for (i = 0; i < 4; i++) centre_square.Add(0, 0); double xx = centre.x; double yy = centre.y; int index = 0; for (i = 0; i < 4; i++) { if ((centre_dots[i].x < xx) && (centre_dots[i].y < yy)) { xx = centre_dots[i].x; yy = centre_dots[i].y; centre_square.x_points[0] = (float)xx; centre_square.y_points[0] = (float)yy; index = i; } } centredots.Add(centre_dots[index]); xx = centre.x; yy = centre.y; for (i = 0; i < 4; i++) { if ((centre_dots[i].x > xx) && (centre_dots[i].y < yy)) { xx = centre_dots[i].x; yy = centre_dots[i].y; centre_square.x_points[1] = (float)xx; centre_square.y_points[1] = (float)yy; index = i; } } centredots.Add(centre_dots[index]); xx = centre.x; yy = centre.y; for (i = 0; i < 4; i++) { if ((centre_dots[i].x > xx) && (centre_dots[i].y > yy)) { xx = centre_dots[i].x; yy = centre_dots[i].y; centre_square.x_points[2] = (float)xx; centre_square.y_points[2] = (float)yy; index = i; } } centredots.Add(centre_dots[index]); xx = centre.x; yy = centre.y; for (i = 0; i < 4; i++) { if ((centre_dots[i].x < xx) && (centre_dots[i].y > yy)) { xx = centre_dots[i].x; yy = centre_dots[i].y; centre_square.x_points[3] = (float)xx; centre_square.y_points[3] = (float)yy; index = i; } } centredots.Add(centre_dots[index]); } return (centre_square); }
/// <summary> /// returns an ideally spaced grid over the actual detected spots /// </summary> /// <param name="grid"></param> /// <returns></returns> private static grid2D OverlayIdealGrid(calibrationDot[,] grid, List<calibrationDot> corners, ref int grid_offset_x, ref int grid_offset_y, int random_seed) { grid2D overlay_grid = null; int grid_tx = -1; int grid_ty = -1; int grid_bx = -1; int grid_by = -1; int offset_x = 0; int offset_y = 0; bool found = false; int max_region_area = 0; // try searching horizontally and vertically // then pick the result with the greatest area for (int test_orientation = 0; test_orientation < 2; test_orientation++) { bool temp_found = false; int temp_grid_tx = -1; int temp_grid_ty = -1; int temp_grid_bx = -1; int temp_grid_by = -1; int temp_offset_x = 0; int temp_offset_y = 0; switch (test_orientation) { case 0: { while ((temp_offset_y < 5) && (!temp_found)) { temp_offset_x = 0; while ((temp_offset_x < 3) && (!temp_found)) { temp_grid_tx = temp_offset_x; temp_grid_ty = temp_offset_y; temp_grid_bx = grid.GetLength(0) - 1 - temp_offset_x; temp_grid_by = grid.GetLength(1) - 1 - temp_offset_y; if ((temp_grid_bx < grid.GetLength(0)) && (temp_grid_tx < grid.GetLength(0)) && (temp_grid_by < grid.GetLength(1)) && (temp_grid_ty < grid.GetLength(1)) && (temp_grid_ty >= 0) && (temp_grid_by >= 0) && (temp_grid_tx >= 0) && (temp_grid_bx >= 0)) { if ((grid[temp_grid_tx, temp_grid_ty] != null) && (grid[temp_grid_bx, temp_grid_ty] != null) && (grid[temp_grid_bx, temp_grid_by] != null) && (grid[temp_grid_tx, temp_grid_by] != null)) { temp_found = true; } } temp_offset_x++; } temp_offset_y++; } break; } case 1: { while ((temp_offset_x < 3) && (!temp_found)) { temp_offset_y = 0; while ((temp_offset_y < 5) && (!temp_found)) { temp_grid_tx = temp_offset_x; temp_grid_ty = temp_offset_y; temp_grid_bx = grid.GetLength(0) - 1 - temp_offset_x; temp_grid_by = grid.GetLength(1) - 1 - temp_offset_y; if ((temp_grid_bx < grid.GetLength(0)) && (temp_grid_tx < grid.GetLength(0)) && (temp_grid_by < grid.GetLength(1)) && (temp_grid_ty < grid.GetLength(1)) && (temp_grid_ty >= 0) && (temp_grid_by >= 0) && (temp_grid_tx >= 0) && (temp_grid_bx >= 0)) { if ((grid[temp_grid_tx, temp_grid_ty] != null) && (grid[temp_grid_bx, temp_grid_ty] != null) && (grid[temp_grid_bx, temp_grid_by] != null) && (grid[temp_grid_tx, temp_grid_by] != null)) { temp_found = true; } } temp_offset_y++; } temp_offset_x++; } break; } } temp_offset_y = temp_grid_ty - 1; while (temp_offset_y >= 0) { if ((temp_offset_y < grid.GetLength(1)) && (temp_offset_y >= 0)) { if ((grid[temp_grid_tx, temp_offset_y] != null) && (grid[temp_grid_bx, temp_offset_y] != null)) { temp_grid_ty = temp_offset_y; temp_offset_y--; } else break; } else break; } temp_offset_y = temp_grid_by + 1; while (temp_offset_y < grid.GetLength(1)) { if ((temp_offset_y < grid.GetLength(1)) && (temp_offset_y >= 0)) { if ((grid[temp_grid_tx, temp_offset_y] != null) && (grid[temp_grid_bx, temp_offset_y] != null)) { temp_grid_by = temp_offset_y; temp_offset_y++; } else break; } else break; } if (temp_found) { int region_area = (temp_grid_bx - temp_grid_tx) * (temp_grid_by - temp_grid_ty); if (region_area > max_region_area) { max_region_area = region_area; found = true; grid_tx = temp_grid_tx; grid_ty = temp_grid_ty; grid_bx = temp_grid_bx; grid_by = temp_grid_by; offset_x = temp_offset_x; offset_y = temp_offset_y; } } } if (found) { // record the positions of the corners corners.Add(grid[grid_tx, grid_ty]); corners.Add(grid[grid_bx, grid_ty]); corners.Add(grid[grid_bx, grid_by]); corners.Add(grid[grid_tx, grid_by]); double dx, dy; double x0 = grid[grid_tx, grid_ty].x; double y0 = grid[grid_tx, grid_ty].y; double x1 = grid[grid_bx, grid_ty].x; double y1 = grid[grid_bx, grid_ty].y; double x2 = grid[grid_tx, grid_by].x; double y2 = grid[grid_tx, grid_by].y; double x3 = grid[grid_bx, grid_by].x; double y3 = grid[grid_bx, grid_by].y; polygon2D perimeter = new polygon2D(); perimeter.Add((float)x0, (float)y0); perimeter.Add((float)x1, (float)y1); perimeter.Add((float)x3, (float)y3); perimeter.Add((float)x2, (float)y2); int grid_width = grid_bx - grid_tx; int grid_height = grid_by - grid_ty; int min_hits = 0; double min_dx = 0, min_dy = 0; // try various perimeter sizes double min_dist = double.MaxValue; int max_perim_size_tries = 100; polygon2D best_perimeter = perimeter; MersenneTwister rnd = new MersenneTwister(random_seed); for (int perim_size = 0; perim_size < max_perim_size_tries; perim_size++) { // try a small range of translations for (int nudge_x = -10; nudge_x <= 10; nudge_x++) { for (int nudge_y = -5; nudge_y <= 5; nudge_y++) { // create a perimeter at this scale and translation polygon2D temp_perimeter = perimeter.Scale(1.0f + (perim_size * 0.1f / max_perim_size_tries)); temp_perimeter = temp_perimeter.ScaleSideLength(0, 0.95f + ((float)rnd.NextDouble() * 0.1f)); temp_perimeter = temp_perimeter.ScaleSideLength(2, 0.95f + ((float)rnd.NextDouble() * 0.1f)); for (int i = 0; i < temp_perimeter.x_points.Count; i++) { temp_perimeter.x_points[i] += nudge_x; temp_perimeter.y_points[i] += nudge_y; } // create a grid based upon the perimeter grid2D temp_overlay_grid = new grid2D(grid_width, grid_height, temp_perimeter, 0, false); // how closely does the grid fit the actual observations ? double temp_min_dist = min_dist; BestFit(grid_tx, grid_ty, grid, temp_overlay_grid, ref min_dist, ref min_dx, ref min_dy, ref min_hits, ref grid_offset_x, ref grid_offset_y); // record the closest fit if (temp_min_dist < min_dist) { best_perimeter = temp_perimeter; overlay_grid = temp_overlay_grid; } } } } if (min_hits > 0) { dx = min_dx; dy = min_dy; Console.WriteLine("dx: " + dx.ToString()); Console.WriteLine("dy: " + dy.ToString()); x0 += dx; y0 += dy; x1 += dx; y1 += dy; x2 += dx; y2 += dy; x3 += dx; y3 += dy; perimeter = new polygon2D(); perimeter.Add((float)x0, (float)y0); perimeter.Add((float)x1, (float)y1); perimeter.Add((float)x3, (float)y3); perimeter.Add((float)x2, (float)y2); overlay_grid = new grid2D(grid_width, grid_height, perimeter, 0, false); } } return (overlay_grid); }
/// <summary> /// finds the interception points between grid lines /// </summary> private void poltLineIntercepts() { if (line != null) { // create an array to store the line intercepts int intercepts_x = line[0].Count/4; int intercepts_y = line[1].Count/4; line_intercepts = new float[intercepts_x, intercepts_y, 2]; for (int i = 0; i < line[0].Count; i += 4) { // get the first line coordinates ArrayList lines0 = line[0]; float x0 = (float)lines0[i]; float y0 = (float)lines0[i + 1]; float x1 = (float)lines0[i + 2]; float y1 = (float)lines0[i + 3]; for (int j = 0; j < line[1].Count; j += 4) { // get the second line coordinates ArrayList lines1 = line[1]; float x2 = (float)lines1[j]; float y2 = (float)lines1[j + 1]; float x3 = (float)lines1[j + 2]; float y3 = (float)lines1[j + 3]; // find the interception between the two lines float ix = 0, iy = 0; geometry.intersection(x0, y0, x1, y1, x2, y2, x3, y3, ref ix, ref iy); // store the intercept position line_intercepts[i/4, j/4, 0] = ix; line_intercepts[i/4, j/4, 1] = iy; } } // update the perimeter border_perimeter = new polygon2D(); float xx = line_intercepts[0, 0, 0]; float yy = line_intercepts[0, 0, 1]; border_perimeter.Add(xx, yy); xx = line_intercepts[intercepts_x - 1, 0, 0]; yy = line_intercepts[intercepts_x - 1, 0, 1]; border_perimeter.Add(xx, yy); xx = line_intercepts[intercepts_x - 1, intercepts_y - 1, 0]; yy = line_intercepts[intercepts_x - 1, intercepts_y - 1, 1]; border_perimeter.Add(xx, yy); xx = line_intercepts[0, intercepts_y - 1, 0]; yy = line_intercepts[0, intercepts_y - 1, 1]; border_perimeter.Add(xx, yy); } }
/// <summary> /// constructor /// </summary> /// <param name="dimension_x">number of cells across the grid</param> /// <param name="dimension_y">number of cells down the grid</param> /// <param name="cx">centre of the grid</param> /// <param name="cy">centre of the grid</param> /// <param name="orientation">orientation of the grid in radians</param> /// <param name="average_spacing_x">grid spacing in the x axis</param> /// <param name="average_spacing_y">grid spacing in the y axis</param> /// <param name="phase_offset_x">phase offset in the x axis</param> /// <param name="phase_offset_y">phase offset in the y axis</param> /// <param name="border_cells">number of cells to use as a border around the grid</param> public grid2D(int dimension_x, int dimension_y, float cx, float cy, float orientation, float average_spacing_x, float average_spacing_y, float phase_offset_x, float phase_offset_y, int border_cells, bool orientation_simple) { // create a perimeter region polygon2D perimeter = new polygon2D(); float length_x = average_spacing_x * dimension_x; float length_y = average_spacing_y * dimension_y; float half_length_x = length_x / 2; float half_length_y = length_y / 2; // adjust for phase cx += (average_spacing_x * phase_offset_x / (2 * (float)Math.PI)) * (float)Math.Sin(orientation); cy -= (average_spacing_y * phase_offset_y / (2 * (float)Math.PI)) * (float)Math.Cos(orientation); // find the mid point of the top line float px1 = cx + (half_length_y * (float)Math.Sin(orientation)); float py1 = cy + (half_length_y * (float)Math.Cos(orientation)); // find the top left vertex float x0 = px1 + (half_length_x * (float)Math.Sin(orientation - (float)(Math.PI / 2))); float y0 = py1 + (half_length_x * (float)Math.Cos(orientation - (float)(Math.PI / 2))); // find the top right vertex float x1 = px1 + (half_length_x * (float)Math.Sin(orientation + (float)(Math.PI / 2))); float y1 = py1 + (half_length_x * (float)Math.Cos(orientation + (float)(Math.PI / 2))); // find the bottom vertices by mirroring around the centre float x2 = cx + (cx - x0); float y2 = cy + (cy - y0); float x3 = cx - (x1 - cx); float y3 = cy - (y1 - cy); // update polygon with the perimeter vertices perimeter.Add(x0, y0); perimeter.Add(x1, y1); perimeter.Add(x2, y2); perimeter.Add(x3, y3); int dim_x = dimension_x; int dim_y = dimension_y; float first_side_length = perimeter.getSideLength(0); float second_side_length = perimeter.getSideLength(1); if (((dimension_x > dimension_y + 2) && (second_side_length > first_side_length)) || ((dimension_y > dimension_x + 2) && (first_side_length > second_side_length))) { dim_x = dimension_y; dim_y = dimension_x; } // initialise using this perimeter init(dim_x, dim_y, perimeter, border_cells, orientation_simple); }
/// <summary> /// simple function used to test grid creation /// </summary> /// <param name="filename">filename of the test image to be created</param> public static void Test(string filename) { int image_width = 640; int image_height = 480; int dimension_x = 10; int dimension_y = 10; Bitmap bmp = new Bitmap(image_width, image_height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); byte[] img = new byte[image_width * image_height * 3]; polygon2D test_poly; grid2D grid; test_poly = new polygon2D(); test_poly.Add(image_width * 15 / 100, image_height * 20 / 100); test_poly.Add(image_width * 40 / 100, image_height * 20 / 100); test_poly.Add(image_width * 40 / 100, image_height * 40 / 100); test_poly.Add(image_width * 15 / 100, image_height * 40 / 100); grid = new grid2D(dimension_x, dimension_y, test_poly, 0, false); grid.ShowLines(img, image_width, image_height, 0, 255, 0, 0); int half_width = image_width / 2; test_poly = new polygon2D(); test_poly.Add(half_width + (image_width * 20 / 100), image_height * 20 / 100); test_poly.Add(half_width + (image_width * 35 / 100), image_height * 20 / 100); test_poly.Add(half_width + (image_width * 40 / 100), image_height * 40 / 100); test_poly.Add(half_width + (image_width * 15 / 100), image_height * 40 / 100); grid = new grid2D(dimension_x, dimension_y, test_poly, 0, false); grid.ShowLines(img, image_width, image_height, 0, 255, 0, 0); int half_height = image_height / 2; test_poly = new polygon2D(); test_poly.Add(image_width * 15 / 100, half_height + (image_height * 24 / 100)); test_poly.Add(image_width * 40 / 100, half_height + (image_height * 20 / 100)); test_poly.Add(image_width * 40 / 100, half_height + (image_height * 40 / 100)); test_poly.Add(image_width * 15 / 100, half_height + (image_height * 36 / 100)); grid = new grid2D(dimension_x, dimension_y, test_poly, 0, false); grid.ShowLines(img, image_width, image_height, 0, 255, 0, 0); test_poly = new polygon2D(); test_poly.Add(half_width + (image_width * 20 / 100), half_height + (image_height * 24 / 100)); test_poly.Add(half_width + (image_width * 35 / 100), half_height + (image_height * 20 / 100)); test_poly.Add(half_width + (image_width * 40 / 100), half_height + (image_height * 40 / 100)); test_poly.Add(half_width + (image_width * 15 / 100), half_height + (image_height * 36 / 100)); grid = new grid2D(dimension_x, dimension_y, test_poly, 0, false); grid.ShowLines(img, image_width, image_height, 0, 255, 0, 0); BitmapArrayConversions.updatebitmap_unsafe(img, bmp); bmp.Save(filename); }
/// <summary> /// returns a polygon representing the periphery of a square region /// </summary> /// <param name="edges"> /// edges within the square region <see cref="List`1"/> /// </param> /// <param name="erode_dilate"> /// erosion or dilation level <see cref="System.Int32"/> /// </param> /// <param name="perim"> /// returned periphery <see cref="polygon2D"/> /// </param> /// <returns> /// set of edges around the periphery <see cref="List`1"/> /// </returns> private static List<List<int>> GetSquarePeriphery(List<int> edges, int erode_dilate, ref polygon2D perim) { List<List<int>> result = new List<List<int>>(); perim = new polygon2D(); // find the bounding box for all edges int tx = 99999; int ty = 99999; int bx = -99999; int by = -99999; for (int i = edges.Count-2; i >= 0; i -= 2) { int x = edges[i]; int y = edges[i+1]; if (x < tx) tx = x; if (y < ty) ty = y; if (x > bx) bx = x; if (y > by) by = y; } int w = bx - tx; int h = by - ty; if ((w > 0) && (h > 0)) { int[] left = new int[h+1]; int[] right = new int[h+1]; int[] top = new int[w+1]; int[] bottom = new int[w+1]; for (int i = edges.Count - 2; i >= 0; i -= 2) { int x = edges[i]; int x2 = x - tx; int y = edges[i+1]; int y2 = y - ty; // left side if ((left[y2] == 0) || (x < left[y2])) left[y2] = x; // right side if ((right[y2] == 0) || (x > right[y2])) right[y2] = x; // top if ((top[x2] == 0) || (y < top[x2])) top[x2] = y; // bottom if ((bottom[x2] == 0) || (y > bottom[x2])) bottom[x2] = y; } #if SHOW_TIMINGS stopwatch timer_best_fit = new stopwatch(); timer_best_fit.Start(); #endif // find a best fit line for the left side int best_start = 0; int best_end = 0; int hits = BestFitLine(left, ref best_start, ref best_end); float left_x0 = left[best_start]; float left_y0 = ty + best_start; float left_x1 = left[best_end]; float left_y1 = ty + best_end; /* BestFitLineAverage(left, ref left_x0, ref left_y0, ref left_x1, ref left_y1); left_y0 += ty; left_y1 += ty; */ // find a best fit line for the right side best_start = 0; best_end = 0; hits = BestFitLine(right, ref best_start, ref best_end); float right_x0 = right[best_start]; float right_y0 = ty + best_start; float right_x1 = right[best_end]; float right_y1 = ty + best_end; /* BestFitLineAverage(right, ref right_x0, ref right_y0, ref right_x1, ref right_y1); right_y0 += ty; right_y1 += ty; */ // find a best fit line for the top side best_start = 0; best_end = 0; hits = BestFitLine(top, ref best_start, ref best_end); float top_x0 = tx + best_start; float top_y0 = top[best_start]; float top_x1 = tx + best_end; float top_y1 = top[best_end]; /* BestFitLineAverage(top, ref top_x0, ref top_y0, ref top_x1, ref top_y1); top_x0 += tx; top_x1 += tx; */ // find a best fit line for the bottom side best_start = 0; best_end = 0; hits = BestFitLine(bottom, ref best_start, ref best_end); float bottom_x0 = tx + best_start; float bottom_y0 = bottom[best_start]; float bottom_x1 = tx + best_end; float bottom_y1 = bottom[best_end]; /* BestFitLineAverage(bottom, ref bottom_x0, ref bottom_y0, ref bottom_x1, ref bottom_y1); bottom_x0 += tx; bottom_x1 += tx; */ #if SHOW_TIMINGS timer_best_fit.Stop(); if (timer_best_fit.time_elapsed_mS > 20) Console.WriteLine("GetSquarePeriphery: best fit " + timer_best_fit.time_elapsed_mS.ToString() ); #endif // find the intersection between the left side and the top side float ix=0; float iy = 0; geometry.intersection(left_x1, left_y1, left_x0, left_y0, top_x1, top_y1, top_x0, top_y0, ref ix, ref iy); perim.Add(ix, iy); // find the intersection between the right side and the top side ix = 0; iy = 0; geometry.intersection(right_x1, right_y1, right_x0, right_y0, top_x0, top_y0, top_x1, top_y1, ref ix, ref iy); perim.Add(ix, iy); // find the intersection between the right side and the bottom side ix = 0; iy = 0; geometry.intersection(right_x1, right_y1, right_x0, right_y0, bottom_x0, bottom_y0, bottom_x1, bottom_y1, ref ix, ref iy); perim.Add(ix, iy); // find the intersection between the left side and the bottom side ix = 0; iy = 0; geometry.intersection(left_x1, left_y1, left_x0, left_y0, bottom_x0, bottom_y0, bottom_x1, bottom_y1, ref ix, ref iy); perim.Add(ix, iy); // left and right List<int> left_edges = new List<int>(); List<int> right_edges = new List<int>(); for (int y = h; y >= 0; y--) { if (left[y] != 0) { left_edges.Add(left[y]); left_edges.Add(ty + y); } if (right[y] != 0) { right_edges.Add(right[y]); right_edges.Add(ty + y); } } // top and bottom List<int> top_edges = new List<int>(); List<int> bottom_edges = new List<int>(); for (int x = w; x >= 0; x--) { if (top[x] != 0) { top_edges.Add(tx + x); top_edges.Add(top[x]); } if (bottom[x] != 0) { bottom_edges.Add(tx + x); bottom_edges.Add(bottom[x]); } } float aspect_check = perim.getShortestSide() / perim.getLongestSide(); if (aspect_check > 0.2f) { result.Add(left_edges); result.Add(right_edges); result.Add(top_edges); result.Add(bottom_edges); } else perim = null; } // shrink the perimeter according to the erosion/dilation value if ((perim != null) && (erode_dilate != 0)) { if (perim.x_points != null) { float shrink_percent = (erode_dilate*2) / (perim.getPerimeterLength()/4.0f); perim = perim.Scale(1.0f - shrink_percent); } else perim = null; } return(result); }
/// <summary> /// returns a copy of the polygon /// </summary> /// <returns></returns> public polygon2D Copy() { polygon2D new_poly = new polygon2D(); new_poly.name = name; new_poly.type = type; new_poly.occupied = occupied; if (x_points != null) { for (int i = 0; i < x_points.Count; i++) { float x = x_points[i]; float y = y_points[i]; new_poly.Add(x, y); } } return (new_poly); }
/// <summary> /// scale the polygon to a new image size /// </summary> /// <param name="original_image_width"></param> /// <param name="original_image_height"></param> /// <param name="new_image_width"></param> /// <param name="new_image_height"></param> /// <returns></returns> public polygon2D Scale(int original_image_width, int original_image_height, int new_image_width, int new_image_height) { polygon2D rescaled = new polygon2D(); for (int i = 0; i < x_points.Count; i++) { float x = x_points[i] * new_image_width / original_image_width; float y = y_points[i] * new_image_height / original_image_height; rescaled.Add(x, y); } return (rescaled); }
/// <summary> /// return a scaled version of the polygon /// </summary> /// <param name="factor"></param> /// <returns></returns> public polygon2D Scale(float factor) { polygon2D rescaled = new polygon2D(); float centre_x = 0, centre_y = 0; getCentreOfGravity(ref centre_x, ref centre_y); for (int i = 0; i < x_points.Count; i++) { float dx = x_points[i] - centre_x; float dy = y_points[i] - centre_y; float x = (float)(centre_x + (dx * factor)); float y = (float)(centre_y + (dy * factor)); rescaled.Add(x, y); } return (rescaled); }
/// <summary> /// snaps the vertices of the polygon to a grid having the given spacing /// </summary> /// <param name="grid_spacing">spacing of the grid</param> /// <returns>fitted polygon</returns> public polygon2D SnapToGrid(float grid_spacing) { polygon2D result = new polygon2D(); if (x_points != null) { for (int i = 0; i < x_points.Count; i++) { float x = x_points[i] / grid_spacing; x = (float)Math.Round(x) * grid_spacing; float y = y_points[i] / grid_spacing; y = (float)Math.Round(y) * grid_spacing; result.Add(x, y); } } return (result);
/// <summary> /// returns a copy of this polygon with each vetex randomly perturbed /// </summary> /// <param name="max_displacement"> /// maximum perturbation <see cref="System.Single"/> /// </param> /// <param name="rnd"> /// random number generator <see cref="Random"/> /// </param> /// <returns> /// polygon object <see cref="polygon2D"/> /// </returns> public polygon2D Jiggle(float max_displacement, Random rnd) { polygon2D result = null; if (x_points != null) { result = new polygon2D(); float max = max_displacement*2; for (int i = 0; i < x_points.Count; i++) { float jiggled_x = x_points[i] + ((float)rnd.NextDouble() * max) - max_displacement; float jiggled_y = x_points[i] + ((float)rnd.NextDouble() * max) - max_displacement; result.Add(jiggled_x, jiggled_y); } } return(result); }