Exemple #1
0
        /// <summary>
        /// initialise the snake based upon a polygon shape
        /// </summary>
        /// <param name="binary_image"></param>
        /// <param name="BlackOnWhite"></param>
        /// <param name="initial_points"></param>
        /// <param name="max_itterations"></param>
        /// <param name="rnd"></param>
        public void Snake(bool[,] binary_image, bool BlackOnWhite,
                          polygon2D initial_points,
                          int max_itterations,
                          Random rnd)
        {
            if (initial_points.x_points.Count > 1)
            {
                // get the perimeter length of the initial shape
                float perimeter_length = initial_points.getPerimeterLength();

                // distribute points evenly along the perimeter
                int   side_index        = 0;
                float side_length_total = 0;
                for (int i = 0; i < no_of_points; i++)
                {
                    // position of this point along the perimeter
                    float perimeter_position = i * perimeter_length / no_of_points;

                    float total = side_length_total;
                    while (total < perimeter_position)
                    {
                        side_length_total = total;
                        total            += initial_points.getSideLength(side_index);
                        if (total < perimeter_position)
                        {
                            side_index++;
                        }
                    }

                    float side_length = initial_points.getSideLength(side_index);
                    if (side_length > 0)
                    {
                        float perimeter_diff = perimeter_position - side_length_total;
                        float fraction = perimeter_diff / side_length;
                        float tx = 0, ty = 0, bx = 0, by = 0;
                        initial_points.getSidePositions(side_index, ref tx, ref ty, ref bx, ref by);
                        float dx = bx - tx;
                        float dy = by - ty;
                        SnakePoint[i, SNAKE_X] = tx + (dx * fraction);
                        SnakePoint[i, SNAKE_Y] = ty + (dy * fraction);
                    }
                }

                Snake(binary_image, BlackOnWhite, max_itterations, rnd);
            }
        }
Exemple #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);
        }
Exemple #3
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 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];

                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];

                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();
        }
Exemple #4
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);
        }
Exemple #5
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 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];

                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];

                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();
        }