/// <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 = (float)x_points[i] - centre_x; float dy = (float)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> /// 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 = (float)x_points[i] - centre_x; float dy = (float)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> /// 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 = (float)x_points[i]; float y = (float)y_points[i]; new_poly.Add(x, y); } } return (new_poly); }
/// <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 = (float)x_points[i]; float y = (float)y_points[i]; new_poly.Add(x, y); } } return(new_poly); }
/// <summary> /// create a polygon from the corners /// </summary> private polygon2D createPolygon() { polygon2D new_polygon = new sluggish.utilities.polygon2D(); for (int i = 0; i < corners.Count; i += 2) { float x = (float)corners[i]; float y = (float)corners[i + 1]; new_polygon.Add(x, y); } return (new_polygon); }
/// <summary> /// after finding the horizontal and vertical axis of a region /// this removes any spots which are unlikely to lie inside the /// axis of a square or rectangular region /// </summary> /// <param name="spots">list of spot features</param> /// <param name="shear_angle_point">angle defining the primary axis of the region</param> /// <param name="spot_culling_threshold">the ratio of possible out of bounds spots to the total number of spots must be below this threshold in order for out of bounds cases to be removed</param> private void removeSpots(ArrayList spots, float[,] shear_angle_point, float spot_culling_threshold) { if (shear_angle_point != null) { polygon2D area_perimeter = new polygon2D(); float tx = shear_angle_point[0, 0]; float ty = shear_angle_point[0, 1]; float cx = shear_angle_point[1, 0]; float cy = shear_angle_point[1, 1]; float bx = shear_angle_point[2, 0]; float by = shear_angle_point[2, 1]; float dx1 = cx - tx; float dy1 = cy - ty; float dx2 = cx - bx; float dy2 = cy - by; float dx = dx1; if (Math.Abs(dx2) > Math.Abs(dx1)) dx = dx2; float dy = dy1; if (Math.Abs(dy2) > Math.Abs(dy1)) dy = dy2; // add a small border float x_offset = 4; float y_offset = 4; if (dx < 0) x_offset = -x_offset; if (dy < 0) y_offset = -y_offset; // create a polygon inside which the spot features are expected to lie area_perimeter.Add(tx + x_offset, ty + y_offset); area_perimeter.Add(cx + x_offset, cy + y_offset); area_perimeter.Add(bx + x_offset, by + y_offset); area_perimeter.Add(bx + (tx - cx) + x_offset, by + (ty - cy) + y_offset); // remove any spots outside of this perimeter ArrayList potential_victims = new ArrayList(); for (int i = spots.Count - 1; i >= 0; i--) { blob spot = (blob)spots[i]; if (!area_perimeter.isInside(spot.interpolated_x, spot.interpolated_y)) { // add the index of this spot to the list of potential victims <evil laughter> potential_victims.Add(i); } } if (potential_victims.Count > 0) { // what fraction of the spots are potential victims? // if this ratio is too large then perhaps we have made a dreadful mistake! float victims_ratio = potential_victims.Count / (float)spots.Count; if (victims_ratio < spot_culling_threshold) { // let the slaughter commence for (int i = 0; i < potential_victims.Count; i++) { int victim_index = (int)potential_victims[i]; spots.RemoveAt(victim_index); } } } } }
/// <summary> /// returns a polygon shape based upon the corner points located /// </summary> /// <returns></returns> public polygon2D GetPolygon() { polygon2D poly = new polygon2D(); for (int i = 0; i < corners.Count; i += 2) { float x = tx + (float)corners[i]; float y = ty + (float)corners[i + 1]; poly.Add(x, y); } return (poly); }
/// <summary> /// returns a polygon describing the perimeter of a grid cell /// at the given coordinate /// </summary> /// <param name="grid_x">x grid coordinate</param> /// <param name="grid_y">y grid coordinate</param> /// <param name="horizontal_maxima">horizontal grid line positions</param> /// <param name="vertical_maxima">vertical grid line positions</param> /// <param name="dominant_orientation">oprientation of the grid pattern</param> /// <param name="shear angle_radians">deviation from perfectly perpendicular axes</param> /// <returns>polygon object for the grid cell</returns> private polygon2D getGridCellPerimeter(int grid_x, int grid_y, ArrayList horizontal_maxima, ArrayList vertical_maxima, float dominant_orientation, float secondary_orientation, float shear_angle_radians) { polygon2D perimeter = new polygon2D(); float r0 = (float)horizontal_maxima[grid_y]; float x0 = centre_x + (float)(r0 * Math.Sin(dominant_orientation)); float y0 = centre_y + (float)(r0 * Math.Cos(dominant_orientation)); float r1 = (float)horizontal_maxima[grid_y + 1]; float x1 = centre_x + (float)(r1 * Math.Sin(dominant_orientation)); float y1 = centre_y + (float)(r1 * Math.Cos(dominant_orientation)); float r2 = (float)vertical_maxima[grid_x]; //float secondary_orientation = dominant_orientation + // shear_angle_radians + // (float)(Math.PI / 2); float x2 = (float)(r2 * Math.Sin(secondary_orientation)); float y2 = (float)(r2 * Math.Cos(secondary_orientation)); float r3 = (float)vertical_maxima[grid_x + 1]; float x3 = (float)(r3 * Math.Sin(secondary_orientation)); float y3 = (float)(r3 * Math.Cos(secondary_orientation)); perimeter.Add(x0 + x2, y0 + y2); perimeter.Add(x0 + x3, y0 + y3); perimeter.Add(x1 + x3, y1 + y3); perimeter.Add(x1 + x2, y1 + y2); return (perimeter); }
} /// <summary> /// after finding the horizontal and vertical axis of a region /// this removes any spots which are unlikely to lie inside the /// axis of a square or rectangular region /// </summary> /// <param name="spots">list of spot features</param> /// <param name="shear_angle_point">angle defining the primary axis of the region</param> private void removeSpots(ArrayList spots, float[,] shear_angle_point) { if (shear_angle_point != null) { polygon2D area_perimeter = new polygon2D(); float tx = shear_angle_point[0, 0]; float ty = shear_angle_point[0, 1]; float cx = shear_angle_point[1, 0]; float cy = shear_angle_point[1, 1]; float bx = shear_angle_point[2, 0]; float by = shear_angle_point[2, 1]; float dx1 = cx - tx; float dy1 = cy - ty; float dx2 = cx - bx; float dy2 = cy - by; float dx = dx1; if (Math.Abs(dx2) > Math.Abs(dx1)) dx = dx2; float dy = dy1; if (Math.Abs(dy2) > Math.Abs(dy1)) dy = dy2; // add a small border float x_offset = 4; float y_offset = 4; if (dx < 0) x_offset = -x_offset; if (dy < 0) y_offset = -y_offset; // create a polygon inside which the spot features are expected to lie area_perimeter.Add(tx + x_offset, ty + y_offset); area_perimeter.Add(cx + x_offset, cy + y_offset); area_perimeter.Add(bx + x_offset, by + y_offset); area_perimeter.Add(bx + (tx - cx) + x_offset, by + (ty - cy) + y_offset); // remove any spots outside of this perimeter for (int i = spots.Count - 1; i >= 0; i--) { blob spot = (blob)spots[i]; if (!area_perimeter.isInside(spot.interpolated_x, spot.interpolated_y)) spots.RemoveAt(i); }
private void Snake(bool[,] binary_image, bool BlackOnWhite, int max_itterations, Random rnd) { bool SnakeComplete = false; //set the initial parameters for the snake prevSnakeStationaryPoints = 0; snakeStationary = 0; // itterate until the snake can get no smaller int i = 0; while ((!SnakeComplete) && (i < max_itterations)) { SnakeComplete = Update(binary_image, BlackOnWhite, elasticity, gravity, rnd); i++; } // create a new polygon shape shape = new polygon2D(); for (i = 0; i < no_of_points; i++) shape.Add((int)SnakePoint[i, SNAKE_X], (int)SnakePoint[i, SNAKE_Y]); }