0

Currently i'm trying to produce a simple 2D map generation program, and it is pretty much finished apart from one key thing; The movement of the generated islands. The way the program functions it keeps all the islands in the middle of the map separated by colour like so in some like disco ball of puke thing, but my main problem is trying to move the islands into new locations.

The program should randomly place the islands in new places based on colour, but i am having a considerable amount of difficulty doing this, as all solutions i have attempted have either fell on their face in a tsunami of 'index out of bounds of the array' errors or have worked, but taken literal hours to move a single island.

TLDR; Do any algorithms exist that would potentially allow me to move shapes made of pixels to random locations while keeping their existing shapes? mine suck.

Edit: I will try and rewrite this to be easier to read later since i'm in a rush, but in essence it reads all the pixels from the circle using .getpixel and stores them in an array based on their colour, it then generates a random location and runs the same code again, only this time it will accept a colour as an argument and will place the colour at the pixel relative to the centre of the circle if it finds a colour that is the same as the colour it is currently accepting.

In theory this should go through every colour and generate a new position for each one that maintains the shape of the island upon generation, but in practice it just takes forever.

                //Thoughts - use the circle generator as a radar to find all the seperate colors, then for each color randomly generate an x and a y. then use the circle generator but only apply the colors that are selected

                if (tempi >= 716 || tempib > 0)
                {
                    if(tempib <= 0)
                    {
                        tempi = 0;
                        tempib = 1;
                        randxb = Rander.Next(10, xlen - 10);
                        randyb = Rander.Next(10, ylen - 10);
                    }

                    tempi += 1;

                    day += 1;
                    if(day >= 31)
                    {
                        month += 1;
                        day = 1;
                    }

                    if(month >= 13)
                    {
                        year += 1;
                        month = 1;
                    }

                    AD = "PF";
                    era = "Prehistoric era";
                    age = "Islandic Age";

                    Point temppb = new Point(randxb, randyb);

                    if (colours[tempib] == Color.DarkBlue || colours[tempib] == Color.FromArgb(0, 0, 0))
                    {
                        tempib += 1;
                    }
                    else
                    {
                        Radar(0, temppb, "write", colours[tempib]);
                    }

                    tempi = 0;
                    tempib += 1;
                    randxb = Rander.Next(10, xlen - 10);
                    randyb = Rander.Next(10, ylen - 10);

                    if (tempib >= islandnuma)
                    {
                        age = "Neanderthalic Age";
                    }
                }
                else
                {
                    year += Rander.Next(1, 3);
                    day = 1;
                    AD = "PF";
                    era = "Prehistoric era";

                    Point tempp = new Point(xlen / 2 - 150, ylen / 2 - 150);
                    tempi += 1;
                    Radar(tempi, tempp, "scan", Color.White);
                    if(tempi >= 716)
                    {
                        clearmap();
                    }
                }

            }

This is the terrible algorithm it calls

        Color[,] scanresults = new Color[717, 4499]; //shell, place in shell

    private void Radar(int circle, Point pos, string mode, Color col) //Fuck this doesnt work i need to change it
    { 
        using (var g = Graphics.FromImage(pictureBox1.Image))
        {
            if (mode == "scan")
            {
                int mj = 0;
                if (circle <= 716)
                    {
                        for (double i = 0.0; i < 360.0; i += 0.1)
                        {
                            mj += 1;
                            int radius = circle / 2; //max size = 716 
                            double angle = i * System.Math.PI / 180;
                            int x = pos.X - (int)(radius * System.Math.Cos(angle));
                            int y = pos.Y - (int)(radius * System.Math.Sin(angle));
                            Color m = Map.GetPixel(x, y);
                            scanresults[circle, mj] = Map.GetPixel(x, y);
                        }
                    }
                    else
                    {
                        return;
                    }
            }
            else
            {
                if(mode == "write")
                {
                    for(int c2 = 0; c2 <= 716; c2++)
                    {
                        int bmj = 0;

                        for (double i = 0.0; i < 360.0; i += 0.1)
                            {
                            try
                            {
                                if (mode == "write")
                                {
                                    bmj += 1;
                                    int radius = (716 - c2) / 2; //max size = 716 
                                    double angle = i * System.Math.PI / 180;
                                    int x = pos.X - (int)(radius * System.Math.Cos(angle));
                                    int y = pos.Y - (int)(radius * System.Math.Sin(angle));
                                    if (scanresults[c2, bmj] == col)
                                    {
                                        Map.SetPixel(x, y, col);
                                    }
                                }
                            }
                            catch (Exception em)
                            {
                                Console.Write("error: " + em);
                            }
                                //Color m = Map.GetPixel(x, y);
                                //scanresults[circle, mj] = Map.GetPixel(x, y);
                            }
                        }

                }
            }
            //Dont hate me im defensive about my terrible coding style
        }
        }
  • could you explain what you have done so far and the errors you got? and could you also create a [MCVE](https://stackoverflow.com/help/mcve) to help us recreate – WhatsThePoint Oct 06 '17 at 12:41
  • 1
    While I don't know what you're doing, use of `GetPixel` would immediately explain why it takes an hours to process. Stop using that, use lockbits. – harold Oct 06 '17 at 13:07
  • 1
    Can you store the islands as bitmaps and render them in their final place. – user2867342 Oct 06 '17 at 13:07
  • @harold , whats wrong with GetPixel? Is it slower than other methods or something? – Jamie Gorman Oct 06 '17 at 13:12
  • 2
    Yes, extremely slow. See for example https://stackoverflow.com/q/24701703/555045 – harold Oct 06 '17 at 13:33
  • @harold Thanks for the assistance, i think i can use the code linked to draw the pixels, but getting their Colors doesn't seem to be discussed in that article, is there a better alternative to GetPixel? – Jamie Gorman Oct 06 '17 at 15:06
  • Sounds like what you want is this: Let each 'island' live in a bitmap of its own, with all surrounding pixels staying transparent. Then you can 'move' them around by drawing them to different locations onto one target canvas. You will need to decide on how to handle overlapping pixels. – TaW Oct 06 '17 at 15:10
  • @TaW That seems like it would be an easy solution to the problem, but since the islands are random i'd need to make a new bitmap during run time (and there are about 7500 per run) which seems like it might end up killing the memory? i also dont really understand how i could go about actually making a new bitmap with the pixels, so information would be appreciated if possible, thanks. – Jamie Gorman Oct 06 '17 at 15:14
  • Well 7500 bitmaps is a lot, indeed. What sizes will they have? And what exactly is it about the 'moving' part? Is that interactive? If so it should be not problem to access an image from disk; which still would leave the issue of what the pixels at the previous location would show.. – TaW Oct 06 '17 at 16:54

0 Answers0