예제 #1
0
        /// <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();
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }