예제 #1
0
        /// <summary>
        /// At a resolution determined by <paramref name="gridSize"/>, determine the relative traffic of all areas in the experiment.
        /// </summary>
        /// <param name="gridSize">The width and height of the grid the experiment should be superimposed upon.</param>
        /// <param name="maxTime">The amount of seconds within the simulation to include when making the grid (up until the end of the simluation)</param>
        /// <param name="mode">The type of mapping to perform between vertices on the grid and the bots</param>
        /// <returns>Traffic grid</returns>
        /// <remarks>
        /// Weighted at 1 unit of weight per second.
        /// </remarks>
        protected Tuple <float[][], float[][][]> ProjectBoidsToGrid(int gridSize = 21, float maxTime = float.PositiveInfinity, MappingMode mode = MappingMode.SAME_QUAD)
        {
            // Initialization
            float[][]   trafficGrid = new float[gridSize][];
            float[][][] pathGrid    = new float[gridSize][][];
            float[][]   weightGrid  = new float[gridSize][];
            for (int row = 0; row < gridSize; row++)
            {
                trafficGrid[row] = new float[gridSize];
                pathGrid[row]    = new float[gridSize][];
                weightGrid[row]  = new float[gridSize];
                for (int col = 0; col < gridSize; col++)
                {
                    trafficGrid[row][col] = 0;
                    float[] zeroVector = { 0, 0, 0 };
                    pathGrid[row][col]   = zeroVector;
                    weightGrid[row][col] = 0;
                }
            }

            if (mode == MappingMode.SAME_QUAD)
            {
                // Add weights
                for (int i = 0; i < Current.Count - 1; i++)
                {
                    BoidsSnapshot snapshot = Current[i];
                    if (snapshot.Timestamp < maxTime) // Since the list is not garunteed to be sorted, we can't break when we pass the max time.
                    {
                        for (int j = 0; j < snapshot.Coords.Count; j++)
                        {
                            float[] coord     = snapshot.Coords[j];
                            float[] direction =
                            {
                                Current[i + 1].Coords[j][0] - snapshot.Coords[j][0], // x
                                Current[i + 1].Coords[j][1] - snapshot.Coords[j][1], // y
                                0                                                    // z
                            };
                            DistributeBoidWeightOverQuad(ref trafficGrid, ref pathGrid, coord, direction, ref weightGrid, DeltaTime[i]);
                        }
                    }
                }
                // Special case for last snapshot; no next vector direction, so vector must be either considered zero or set to the last vector for that boid.
                BoidsSnapshot lastSnapshot = Current[Current.Count - 1];
                if (lastSnapshot.Timestamp < maxTime)
                {
                    for (int j = 0; j < lastSnapshot.Coords.Count; j++)
                    {
                        float[] coord     = lastSnapshot.Coords[j];
                        float[] direction = { 0, 0, 0 };
                        DistributeBoidWeightOverQuad(ref trafficGrid, ref pathGrid, coord, direction, ref weightGrid, DeltaTime[Current.Count - 1]);
                    }
                }
            }
            else if (mode == MappingMode.ALL_QUAD)
            {
                throw new System.NotImplementedException("Mapping mode not supported: All quads.");
            }

            return(new Tuple <float[][], float[][][]>(trafficGrid, pathGrid));
        }
예제 #2
0
        /// <summary>
        /// Initializes the boids experiment from a serialized representation.
        /// </summary>
        /// <remarks>
        /// Instead of using the convenience function, the beginning of a proper setup would look something like:
        /// FileStream input = File.OpenRead(inputFile);
        /// Span<byte> inputBuffer; // Alternative consideration if this were a more serious project.
        /// </remarks>
        /// <param name="snapshotsRaw">A serialized representation of the snapshot conforming to <see href="https://regex101.com/r/2eIGmk/6/"/>.  May have multiple lines.</param>
        protected void InitializeSnapshots(string[] snapshotsRaw)
        {
            Current = new List <BoidsSnapshot>();

            // Reads the snapshot as a whole.
            Regex snapshotReader = new Regex(@"(?<time>[\d\.,\-]+):(?:(?:-?[\d,\.]+);(?:-?[\d,\.]+)#)*",
                                             RegexOptions.Compiled | RegexOptions.IgnoreCase);
            // Reads each ordered pair in the snapshot.
            Regex orderedPairFinder = new Regex(@"(?<coordx>-?[\d,\.]+);(?<coordy>-?[\d,\.]+)#",
                                                RegexOptions.Compiled | RegexOptions.IgnoreCase);


            for (int i = 0; i < snapshotsRaw.Length; i++)
            { // For each snapshot
                // Clean up erronious parts of the lines (no idea how those got there):
                // Get the overallsnapshat data.
                if (snapshotsRaw.Equals("") && i == snapshotsRaw.Length - 1)
                {
                    return;                                                          // Allow blank line at EOF.
                }
                Match parsedSnapshot = snapshotReader.Match(snapshotsRaw[i]);
                if (!parsedSnapshot.Success)
                {
                    string err = "Could not interpret line " + i + " of input.";
                    Console.WriteLine(err);
                    throw new ArgumentException(err);
                }

                float t = float.Parse(parsedSnapshot.Groups["time"].Value);

                // Get snapshot data for each boid.
                List <float[]> pairs = new List <float[]>();

                MatchCollection rawPairs = orderedPairFinder.Matches(snapshotsRaw[i]);

                for (int j = 0; j < rawPairs.Count; j++)
                {
                    Match   currentPair = rawPairs[j];
                    float[] parsedPair  =
                    {
                        float.Parse(currentPair.Groups["coordx"].Value),
                        float.Parse(currentPair.Groups["coordy"].Value)
                    };
                    pairs.Add(parsedPair);
                }

                // Save the snapshot
                BoidsSnapshot s = new BoidsSnapshot(t, pairs);
                Current.Add(s);
            }
        }
예제 #3
0
        private void InitializeBounds(float margin = 0.1f)
        {
            if (Current.Count == 0 || Current[0].Coords.Count == 0)
            {
                return; // Can't calculate bounds on an empty experiment
            }
            BoidsSnapshot firstSnapshot = Current[0];

            bounds = new float[] { firstSnapshot.Coords[0][0] - margin, firstSnapshot.Coords[0][1] - margin, firstSnapshot.Coords[0][0] + margin, firstSnapshot.Coords[0][1] + margin };

            for (int i = 0; i < Current.Count; i++)
            {
                BoidsSnapshot s = Current[i];
                for (int j = 0; j < s.Coords.Count; j++)
                {
                    float[] c = s.Coords[j];
                    if (c[0] - margin < bounds[0])
                    {
                        bounds[0] = c[0] - margin;
                    }
                    if (c[1] - margin < bounds[1])
                    {
                        bounds[1] = c[1] - margin;
                    }
                    if (c[0] + margin > bounds[2])
                    {
                        bounds[2] = c[0] + margin;
                    }
                    if (c[1] + margin > bounds[3])
                    {
                        bounds[3] = c[1] + margin;
                    }
                }
            }
            //throw new System.NotImplementedException();
        }