Exemplo n.º 1
0
        //function called to read the tracked data and format it as objects for simplified processing
        void ProcessData()
        {
            Tanks = new Tank[(int)(TankCount.x * TankCount.y)];

            //random variable for later
            Random r = new Random();

            //Random names are given to the fish to identify them
            //Each fish has its own first name, but the fish that share a tank have the same last name
            string[] MaleFirstNames   = { "Charles", "Carl", "Thomas", "Dave", "Fishy", "Eddie", "Louie" };
            string[] FemaleFirstNames = { "Henrietta", "Camille", "Carla", "Patricia", "Ella", "Thelma", "Bea" };
            string[] LastNames        = { "Smith", "Da Vinci", "Ramirez", "von Gelsing", "McFishFace", "Pantel", "Olding", "Carlesburg" };


            //Read the tracking file
            //The format for the tracking data is as follows:
            // /FISH_1_X1/FISH_1_Y1/BEHAVIOUR_1(if applicable)/FISH_2_X1/FISH_2_Y2/---/...
            // /FISH_1_X2/FISH_1_Y2/BEHAVIOUR_2(if applicable)/FISH_2_X2/FISH_2_Y2/---/...
            //...
            string[] Lines = System.IO.File.ReadAllLines("Results.csv");

            //Loop through each line one at a time
            for (int i = 2; i < Lines.Length; i++)
            {
                //split each line into its cells (in a csv the cells are separated by commas
                string[] Cells = Lines[i].Split(',');

                //Go through each cell
                for (int j = 1; j < Cells.Length; j += 3)
                {
                    //If the cell is empty, skip it
                    if (Cells[j] == " ")
                    {
                        continue;
                    }

                    //Get the index of the current fish (since there are 3 cells per fish, it equals a third of the current cell index)
                    int CurrentFish = (int)Math.Ceiling((double)j / 3);
                    //If the current fish has no data yet, create a fish
                    if (CurrentFish > fish.Count)
                    {
                        //Creates a new fish, by default with a male first name. If the fish ends up being female, the name will be changed
                        //Also sets the path to a new array of vectors equal to the number of frames of the video
                        Fish f = new Fish(MaleFirstNames[r.Next(0, MaleFirstNames.Length)])
                        {
                            Path = new Vector[Frames]
                        };
                        //Add this fish to the list of fish
                        fish.Add(f);

                        //Gets the tank index based on the current position
                        int TankIndex = (int)(Math.Floor((float.Parse(Cells[j]) * TankCount.x / Dimensions.x)) * (TankCount.y) + Math.Floor((float.Parse(Cells[j + 1]) * TankCount.y / Dimensions.y)));

                        //If the tank doesnt exist yet, add it
                        if (Tanks[TankIndex] == null)
                        {
                            Tanks[TankIndex] = new Tank(LastNames[TankIndex], Frames);
                        }
                        //add the fish to the tank
                        Tanks[TankIndex].FishInTank.Add(f);

                        //Set the behaviour type of the fish, if it exists
                        int Type = -1;
                        int.TryParse(Cells[j + 2], out Type);
                        Tanks[TankIndex].Behaviours[CurrentFrame] = (Behaviour)Type;
                        Console.WriteLine((Behaviour)Type);
                    }

                    //set the location of the fish
                    fish[CurrentFish - 1].Path[i - 2] = new Vector(float.Parse(Cells[j]), float.Parse(Cells[j + 1]));
                }
            }



            //Go through each tank
            foreach (Tank t in Tanks)
            {
                if (t.FishInTank.Count >= 2 && t.FishInTank[0].Path[0] != null && t.FishInTank[1].Path[0] != null)
                {
                    //the male fish is always higher, so set them accordingly
                    if (t.FishInTank[0].Path[0].y < t.FishInTank[1].Path[0].y)
                    {
                        t.Male = t.FishInTank[0];

                        t.Female = t.FishInTank[1];
                    }
                    else
                    {
                        t.Male = t.FishInTank[1];

                        t.Female = t.FishInTank[0];
                    }
                }
                else
                {
                    t.Male   = t.FishInTank[0];
                    t.Female = t.FishInTank[0];
                }
                //Sets the first name of the fish
                t.Female.FirstName = FemaleFirstNames[r.Next(0, FemaleFirstNames.Length)];

                //Removes teh fish in the current tank
                t.FishInTank.Remove(t.Male);

                t.FishInTank.Remove(t.Female);

                //make sure the fish have a position the first frame
                if (t.Male.Path[0] == null)
                {
                    t.Male.Path[0] = t.Female.Path[0];
                }
                else if (t.Female.Path[0] == null)
                {
                    t.Female.Path[0] = t.Male.Path[0];
                }

                //loop through all the frames
                for (int i = 1; i < Frames; i++)
                {
                    //if both fish dont have a current path
                    if (t.Male.Path[i] == null && t.Female.Path[i] == null)
                    {
                        //give them empty vectors
                        t.Male.Path[i]   = new Vector(0, 0);
                        t.Female.Path[i] = new Vector(0, 0);

                        //get all fish currently existing
                        List <Fish> ActiveFish = new List <Fish>();
                        foreach (Fish f in t.FishInTank)
                        {
                            if (f.Path[i] != null)
                            {
                                ActiveFish.Add(f);
                            }
                        }

                        //if there is two fish active...
                        if (ActiveFish.Count == 2)
                        {
                            //merge the active fish with the initial male/female fish based on closeness to each other
                            if ((t.Male.Path[i - 1] - ActiveFish[0].Path[i]).GetMagnitude() > (t.Female.Path[i - 1] - ActiveFish[0].Path[i]).GetMagnitude())
                            {
                                for (int j = i; j < Frames && ActiveFish[0].Path[j] != null; j++)
                                {
                                    t.Male.Path[j] = ActiveFish[0].Path[j];
                                }

                                for (int j = i; j < Frames && ActiveFish[1].Path[j] != null; j++)
                                {
                                    t.Female.Path[j] = ActiveFish[1].Path[j];
                                }
                            }
                            else
                            {
                                for (int j = i; j < Frames && ActiveFish[1].Path[j] != null; j++)
                                {
                                    t.Male.Path[j] = ActiveFish[1].Path[j];
                                }

                                for (int j = i; j < Frames && ActiveFish[0].Path[j] != null; j++)
                                {
                                    t.Female.Path[j] = ActiveFish[0].Path[j];
                                }
                            }

                            //if there is only one fish then they are probably at the same position, so give them both the same position
                        }
                        else if (ActiveFish.Count == 1)
                        {
                            for (int j = i; j < Frames && ActiveFish[0].Path[j] != null; j++)
                            {
                                t.Male.Path[j]   = ActiveFish[0].Path[j];
                                t.Female.Path[j] = ActiveFish[0].Path[j];
                            }
                        }
                        //if only one fish disappears...
                    }
                    else if (t.Male.Path[i] == null)
                    {
                        //by default give it the position of the other fish temporarily
                        t.Male.Path[i] = t.Female.Path[i];

                        //if ther are other active fish that were not active beforehand, then reassign that fish to the male fish
                        foreach (Fish f in t.FishInTank)
                        {
                            if (f.Path[i - 1] == null && f.Path[i] != null)
                            {
                                for (int j = i; j < f.Path.Length && f.Path[j] != null; j++)
                                {
                                    t.Male.Path[j] = f.Path[j];
                                }
                            }
                        }
                        //the same process, but for the female
                    }
                    else if (t.Female.Path[i] == null)
                    {
                        //again, by default give the female the male's position
                        t.Female.Path[i] = t.Male.Path[i];
                        //if any fish become active, then shift their data into this data
                        foreach (Fish f in t.FishInTank)
                        {
                            if (f.Path[i - 1] == null && f.Path[i] != null)
                            {
                                for (int j = i; j < f.Path.Length && f.Path[j] != null; j++)
                                {
                                    t.Female.Path[j] = f.Path[j];
                                }
                            }
                        }
                    }
                }

                //add this tank to the dropdown box
                this.comboBox1.Items.Add(t);
            }
            //update everything
            comboBox1.SelectedIndex = 0;
            UpdateTextBox();
            UpdateVisuals();
        }