/// <summary> /// initialise the grid /// </summary> /// <param name="dimension_x"></param> /// <param name="dimension_y"></param> /// <param name="perimeter"></param> /// <param name="border_cells"></param> /// <param name="simple_orientation"></param> public void init(int dimension_x, int dimension_y, polygon2D perimeter, int border_cells, bool simple_orientation) { this.border_cells = border_cells; this.perimeter = perimeter; cell = new grid2Dcell[dimension_x][]; for (int x = 0; x < dimension_x; x++) cell[x] = new grid2Dcell[dimension_y]; line = new ArrayList[2]; float length1, length2, length3, length4; int index = 0; for (int i = 0; i < 2; i++) { line[i] = new ArrayList(); int idx1 = index + i; if (idx1 >= 4) idx1 -= 4; int idx2 = index + i + 1; if (idx2 >= 4) idx2 -= 4; float x0 = (float)perimeter.x_points[idx1]; float y0 = (float)perimeter.y_points[idx1]; float x1 = (float)perimeter.x_points[idx2]; float y1 = (float)perimeter.y_points[idx2]; length1 = perimeter.getSideLength(idx1); int next_idx1 = idx1 + 1; if (next_idx1 >= 4) next_idx1 -= 4; length3 = perimeter.getSideLength(next_idx1); float w0 = Math.Abs(x1 - x0); float h0 = Math.Abs(y1 - y0); int idx3 = index + i + 2; if (idx3 >= 4) idx3 -= 4; int idx4 = index + i + 3; if (idx4 >= 4) idx4 -= 4; float x2 = (float)perimeter.x_points[idx3]; float y2 = (float)perimeter.y_points[idx3]; float x3 = (float)perimeter.x_points[idx4]; float y3 = (float)perimeter.y_points[idx4]; length2 = perimeter.getSideLength(idx3); int next_idx3 = next_idx1 + 2; if (next_idx3 >= 4) next_idx3 -= 4; length4 = perimeter.getSideLength(next_idx3); float w1 = Math.Abs(x3 - x2); float h1 = Math.Abs(y3 - y2); int dimension = dimension_x; if (!simple_orientation) { if (i > 0) dimension = dimension_y; } else { if (h0 > w0) dimension = dimension_y; } // how much shorter is one line than the other on the opposite axis? float shortening = 0; //if (h0 > w0) { if (length3 > length4) shortening = (length3 - length4) / length3; else shortening = (length4 - length3) / length4; } for (int j = -border_cells; j <= dimension + border_cells; j++) { // locate the position along the first line float xx0, yy0; // position along the first line float fraction = j / (float)dimension; // modify for foreshortening //if ((h0 > w0) && (shortening > 0)) if (shortening > 0) { fraction = (fraction * (1.0f - shortening)) + ((float)Math.Sin(fraction * (float)Math.PI / 2) * shortening); if (length3 > length4) fraction = 1.0f - fraction; } if (w0 > h0) { float grad = (y1 - y0) / (x1 - x0); if (x1 > x0) xx0 = x0 + (w0 * fraction); else xx0 = x0 - (w0 * fraction); yy0 = y0 + ((xx0 - x0) * grad); } else { float grad = (x1 - x0) / (y1 - y0); if (y1 > y0) yy0 = y0 + (h0 * fraction); else yy0 = y0 - (h0 * fraction); xx0 = x0 + ((yy0 - y0) * grad); } // locate the position along the second line float xx1, yy1; // position along the second line if (w1 > h1) { float grad = (y2 - y3) / (x2 - x3); if (x2 > x3) xx1 = x3 + (w1 * fraction); else xx1 = x3 - (w1 * fraction); yy1 = y3 + ((xx1 - x3) * grad); } else { float grad = (x2 - x3) / (y2 - y3); if (y2 > y3) yy1 = y3 + (h1 * fraction); else yy1 = y3 - (h1 * fraction); xx1 = x3 + ((yy1 - y3) * grad); } // add the line to the list line[i].Add(xx0); line[i].Add(yy0); line[i].Add(xx1); line[i].Add(yy1); } } // find interceptions between lines poltLineIntercepts(); // create grid cells initialiseCells(); }
/// <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> /// returns a value indicating how square the given region is /// </summary> /// <param name="square"> /// region to be processed <see cref="polygon2D"/> /// </param> /// <returns> /// squareness value <see cref="System.Single"/> /// </returns> private static float Squareness(polygon2D square) { float measure1 = square.getSideLength(0) / square.getSideLength(1); measure1 = Math.Abs(1.0f - measure1); float measure2 = square.getSideLength(0) / square.getSideLength(2); measure2 = Math.Abs(1.0f - measure2); float measure3 = square.getSideLength(1) / square.getSideLength(3); measure3 = Math.Abs(1.0f - measure3); float result = 1.0f / (1.0f + (measure1 + measure2 + measure3)); return(result); }