예제 #1
0
        public void SortHilbertTestSteps4()
        {
            var n = 4;

            // build locations.
            var locations = new List <Coordinate>();

            locations.Add(new Coordinate(-90, -180));
            locations.Add(new Coordinate(-90, -60));
            locations.Add(new Coordinate(-90, 60));
            locations.Add(new Coordinate(-90, 180));
            locations.Add(new Coordinate(-30, -180));
            locations.Add(new Coordinate(-30, -60));
            locations.Add(new Coordinate(-30, 60));
            locations.Add(new Coordinate(-30, 180));
            locations.Add(new Coordinate(30, -180));
            locations.Add(new Coordinate(30, -60));
            locations.Add(new Coordinate(30, 60));
            locations.Add(new Coordinate(30, 180));
            locations.Add(new Coordinate(90, -180));
            locations.Add(new Coordinate(90, -60));
            locations.Add(new Coordinate(90, 60));
            locations.Add(new Coordinate(90, 180));

            // build graph.
            var graph = new GeometricGraph(1);

            for (var vertex = 0; vertex < locations.Count; vertex++)
            {
                graph.AddVertex((uint)vertex, locations[vertex].Latitude,
                                locations[vertex].Longitude);
            }

            // build a sorted version in-place.
            graph.Sort(n);

            // test if sorted.
            for (uint vertex = 1; vertex < graph.VertexCount - 1; vertex++)
            {
                Assert.IsTrue(
                    graph.Distance(n, vertex) <=
                    graph.Distance(n, vertex + 1));
            }

            // sort locations.
            locations.Sort((x, y) =>
            {
                return(HilbertCurve.HilbertDistance(x.Latitude, x.Longitude, n).CompareTo(
                           HilbertCurve.HilbertDistance(y.Latitude, y.Longitude, n)));
            });

            // confirm sort.
            for (uint vertex = 0; vertex < graph.VertexCount; vertex++)
            {
                float latitude, longitude;
                graph.GetVertex(vertex, out latitude, out longitude);
                Assert.AreEqual(latitude, locations[(int)vertex].Latitude);
                Assert.AreEqual(longitude, locations[(int)vertex].Longitude);
            }
        }
예제 #2
0
        public void SortHilbertTestSteps4()
        {
            var n = 4;

            // build locations.
            var locations = new List <Coordinate>();

            locations.Add(new Coordinate(-90, -180));
            locations.Add(new Coordinate(-90, -60));
            locations.Add(new Coordinate(-90, 60));
            locations.Add(new Coordinate(-90, 180));
            locations.Add(new Coordinate(-30, -180));
            locations.Add(new Coordinate(-30, -60));
            locations.Add(new Coordinate(-30, 60));
            locations.Add(new Coordinate(-30, 180));
            locations.Add(new Coordinate(30, -180));
            locations.Add(new Coordinate(30, -60));
            locations.Add(new Coordinate(30, 60));
            locations.Add(new Coordinate(30, 180));
            locations.Add(new Coordinate(90, -180));
            locations.Add(new Coordinate(90, -60));
            locations.Add(new Coordinate(90, 60));
            locations.Add(new Coordinate(90, 180));

            // build db.
            var stops = new StopsDb();

            for (var stop = 0; stop < locations.Count; stop++)
            {
                stops.Add((float)locations[stop].Latitude, (float)locations[stop].Longitude, (uint)stop);
            }

            // build a sorted version in-place.
            stops.Sort(null);

            // test if sorted.
            var stopsDbEnumerator = stops.GetEnumerator();

            for (uint stop = 1; stop < stops.Count - 1; stop++)
            {
                Assert.IsTrue(
                    stopsDbEnumerator.Distance(n, stop) <=
                    stopsDbEnumerator.Distance(n, stop + 1));
            }

            // sort locations.
            locations.Sort((x, y) =>
            {
                return(HilbertCurve.HilbertDistance((float)x.Latitude, (float)x.Longitude, n).CompareTo(
                           HilbertCurve.HilbertDistance((float)y.Latitude, (float)y.Longitude, n)));
            });

            // confirm sort.
            for (uint stop = 0; stop < stops.Count; stop++)
            {
                stopsDbEnumerator.MoveTo(stop);
                Assert.AreEqual(stopsDbEnumerator.Latitude, locations[(int)stop].Latitude);
                Assert.AreEqual(stopsDbEnumerator.Longitude, locations[(int)stop].Longitude);
            }
        }
예제 #3
0
 public void TestHilbertDistance2()
 {
     Assert.AreEqual(0, HilbertCurve.HilbertDistance(-45, -90, 2));
     Assert.AreEqual(1, HilbertCurve.HilbertDistance(+45, -90, 2));
     Assert.AreEqual(2, HilbertCurve.HilbertDistance(+45, +90, 2));
     Assert.AreEqual(3, HilbertCurve.HilbertDistance(-45, +90, 2));
 }
예제 #4
0
        public TabViewModel(HilbertCurve iteration)
        {
            this.iteration = iteration;

            this.CoordintesList = new List <Coordinates>();

            this.RaisePropertyChanged("Points");
        }
예제 #5
0
 void OnDrawGizmos()
 {
     if (path.Count != 0)
     {
         //HilbertCurve.DrawRooms(HilbertCurve.hilbertPoints, Color.black);
         //HilbertCurve.DrawRooms(path, Color.white);
         HilbertCurve.DrawPath(path, Color.red);
     }
 }
예제 #6
0
        // DISCLAIMER: some of this stuff is straight from wikipedia:
        // http://en.wikipedia.org/wiki/Hilbert_curve#Applications_and_mapping_algorithms

        /// <summary>
        /// Calculates hilbert distance.
        /// </summary>
        /// <param name="latitude">The latitude.</param>
        /// <param name="longitude">The longitude.</param>
        /// <param name="n">The accuracy, used to divide the lat/lon space.</param>
        /// <returns></returns>
        public static ulong HilbertDistance(float latitude, float longitude, int n)
        {
            // calculate x, y.
            ulong x = (ulong)(((longitude + 180) / 360.0) * n);
            ulong y = (ulong)(((latitude + 90) / 180.0) * n);

            // calculate hilbert value for x-y and n.
            return(HilbertCurve.xy2d(n, x, y));
        }
예제 #7
0
 /// <summary>
 /// Returns the hibert distance for n and the given stop.
 /// </summary>
 /// <returns></returns>
 public static long Distance(this StopsDb.Enumerator stopsDbEnumerator, int n, uint stop)
 {
     if (!stopsDbEnumerator.MoveTo(stop))
     {
         throw new Exception(string.Format("Cannot calculate hilbert distance, stop {0} does not exist.",
                                           stop));
     }
     return(HilbertCurve.HilbertDistance(stopsDbEnumerator.Latitude, stopsDbEnumerator.Longitude, n));
 }
예제 #8
0
        public static long Distance(this RoutingNetwork graph, int n, uint vertex)
        {
            float latitude;
            float longitude;

            if (!graph.GetVertex(vertex, out latitude, out longitude))
            {
                throw new Exception(string.Format("Cannot calculate hilbert distance, vertex {0} does not exist.", (object)vertex));
            }
            return(HilbertCurve.HilbertDistance(latitude, longitude, (long)n));
        }
예제 #9
0
        /// <summary>
        /// Returns the hibert distance for n and the given vertex.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        /// <param name="graph"></param>
        /// <param name="n"></param>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public static long HilbertDistance <TEdgeData>(this GraphBase <TEdgeData> graph, int n, uint vertex)
            where TEdgeData : struct, IGraphEdgeData
        {
            float latitude, longitude;

            if (!graph.GetVertex(vertex, out latitude, out longitude))
            {
                throw new Exception(string.Format("Vertex {0} does not exist in graph.", vertex));
            }
            return(HilbertCurve.HilbertDistance(latitude, longitude, n));
        }
예제 #10
0
        public static HashSet <uint> Search(this GeometricGraph graph, int n, float minLatitude, float minLongitude, float maxLatitude, float maxLongitude)
        {
            List <long> longList = HilbertCurve.HilbertDistances(System.Math.Max(minLatitude, -90f), System.Math.Max(minLongitude, -180f), System.Math.Min(maxLatitude, 90f), System.Math.Min(maxLongitude, 180f), (long)n);

            longList.Sort();
            HashSet <uint> uintSet = new HashSet <uint>();
            int            index   = 0;
            uint           vertex1 = 0;
            uint           vertex2 = graph.VertexCount - 1U;

            for (; index < longList.Count && vertex1 < graph.VertexCount; ++index)
            {
                long num1 = longList[index];
                long maxHilbert;
                for (maxHilbert = num1; index < longList.Count - 1 && longList[index + 1] <= maxHilbert + 1L; ++index)
                {
                    maxHilbert = longList[index + 1];
                }
                uint  vertex;
                int   count;
                float latitude;
                float longitude;
                if (num1 == maxHilbert)
                {
                    if (graph.Search(num1, n, vertex1, vertex2, out vertex, out count))
                    {
                        int num2 = count;
                        for (; count > 0; --count)
                        {
                            if (graph.GetVertex(vertex + (uint)(count - 1), out latitude, out longitude) && (double)minLatitude < (double)latitude && ((double)minLongitude < (double)longitude && (double)maxLatitude > (double)latitude) && (double)maxLongitude > (double)longitude)
                            {
                                uintSet.Add(vertex + (uint)(count - 1));
                            }
                        }
                        vertex1 = vertex + (uint)num2;
                    }
                }
                else if (graph.SearchRange(num1, maxHilbert, n, vertex1, vertex2, out vertex, out count))
                {
                    int num2 = count;
                    for (; count > 0; --count)
                    {
                        if (graph.GetVertex(vertex + (uint)(count - 1), out latitude, out longitude) && (double)minLatitude < (double)latitude && ((double)minLongitude < (double)longitude && (double)maxLatitude > (double)latitude) && (double)maxLongitude > (double)longitude)
                        {
                            uintSet.Add(vertex + (uint)(count - 1));
                        }
                    }
                    vertex1 = vertex + (uint)num2;
                }
            }
            return(uintSet);
        }
예제 #11
0
        /// <summary>
        /// Returns all hibert distances for n.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        /// <returns></returns>
        public static long[] HilbertDistances <TEdgeData>(this GraphBase <TEdgeData> graph, int n)
            where TEdgeData : struct, IGraphEdgeData
        {
            var distances = new long[graph.VertexCount];

            for (uint vertex = 1; vertex <= graph.VertexCount; vertex++)
            {
                float latitude, longitude;
                graph.GetVertex(vertex, out latitude, out longitude);
                distances[vertex - 1] = HilbertCurve.HilbertDistance(latitude, longitude, n);
            }
            return(distances);
        }
예제 #12
0
        /// <summary>
        /// Searches the graph for nearby vertices assuming it has been sorted.
        /// </summary>
        /// <typeparam name="TEdgeData"></typeparam>
        public static List <uint> SearchHilbert <TEdgeData>(this GraphBase <TEdgeData> graph, int n, float latitude, float longitude,
                                                            float offset)
            where TEdgeData : struct, IGraphEdgeData
        {
            var targets = HilbertCurve.HilbertDistances(
                System.Math.Max(latitude - offset, -90),
                System.Math.Max(longitude - offset, -180),
                System.Math.Min(latitude + offset, 90),
                System.Math.Min(longitude + offset, 180), n);

            targets.Sort();
            var vertices = new List <uint>();

            var   targetIdx = 0;
            var   vertex1 = (uint)1;
            var   vertex2 = (uint)graph.VertexCount;
            float vertexLat, vertexLon;

            while (targetIdx < targets.Count)
            {
                uint vertex;
                int  count;
                if (GraphExtensions.SearchHilbert(graph, targets[targetIdx], n, vertex1, vertex2, out vertex, out count))
                {         // the search was successful.
                    while (count > 0)
                    {     // there have been vertices found.
                        if (graph.GetVertex((uint)vertex + (uint)(count - 1), out vertexLat, out vertexLon))
                        { // the vertex was found.
                            if (System.Math.Abs(latitude - vertexLat) < offset &&
                                System.Math.Abs(longitude - vertexLon) < offset)
                            { // within offset.
                                vertices.Add((uint)vertex + (uint)(count - 1));
                            }
                        }
                        count--;
                    }

                    // update vertex1.
                    vertex1 = vertex;
                }

                // move to next target.
                targetIdx++;
            }
            return(vertices);
        }
예제 #13
0
        private void GenerateLayout()
        {
            int                 initialD         = HilbertCurve.xy2d(n, initialHilbertTile.x, initialHilbertTile.y);
            int                 i                = initialD;
            int                 maxSteps         = n * n - 1;
            Connections         direction        = Connections.None;
            List <List <int2> > unconnectedPaths = new List <List <int2> >();
            List <int2>         currentPath      = new List <int2>();
            int2                currentTile      = new int2(initialHilbertTile.x, initialHilbertTile.y);

            currentPath.Add(Hilbert2Layout(currentTile));

            while (i < maxSteps)
            {
                int2 nextTile = HilbertCurve.d2xy(n, i + 1);

                if (IsInsideOffsetFrame(nextTile.x, nextTile.y))
                {
                    direction = GetDirection(currentTile, nextTile);

                    if (direction != Connections.None)                     // we can connect currentTile and nextTile directly.
                    {
                        int2 layoutTile = Hilbert2Layout(currentTile);
                        layoutConnections[layoutTile.x, layoutTile.y] |= direction;
                    }
                    else
                    {
                        unconnectedPaths.Add(currentPath);
                        currentPath = new List <int2>();
                    }

                    currentPath.Add(Hilbert2Layout(nextTile));
                    currentTile = nextTile;
                }

                i++;
            }

            unconnectedPaths.Add(currentPath);
            ConnectUnconnectedPaths(unconnectedPaths);
            exit = currentTile;
        }
예제 #14
0
    // Use this for initialization
    void Start()
    {
        //Generate map:
        var hilbert = HilbertCurve.GenerateHilbert(7);
        // HilbertCurve.Print(hilbert);
        var path = HilbertCurve.GetPath(hilbert, 10, Random.Range(8, 15), Random.Range(15, 23));
        var map  = ProceduralMap.GenerateMap(path, 3);

        //randomize boss order:
        Utils.Shuffle(stage.emitters);

        //place player and bosses:
        SetupPositions(map);

        //fill stageManagers list
        StageManager manager = new StageManager();

        manager.LoadEmitters(stage);
        stageManager = manager;
    }
예제 #15
0
        private int2 FindEntrance()
        {
            int2 result = int2.zero;
            bool found  = false;
            int  i      = 0;
            int  max    = n * n - 1;

            while (!found && i <= max)
            {
                int2 candidate = HilbertCurve.d2xy(n, i);

                if (IsInsideOffsetFrame(candidate.x, candidate.y))
                {
                    result = candidate;
                    found  = true;
                }

                i++;
            }
            return(result);
        }
예제 #16
0
        public void TestHilbertDistances1()
        {
            var distances         = HilbertCurve.HilbertDistances(-90, -180, 90, 180, 2);
            var expectedDistances = new long[] { 0, 1, 2, 3 };

            Assert.AreEqual(expectedDistances.Length, distances.Count);
            foreach (var expectedDistance in expectedDistances)
            {
                Assert.IsTrue(distances.Remove(expectedDistance));
            }
            Assert.AreEqual(0, distances.Count);

            distances         = HilbertCurve.HilbertDistances(-90, -180, 90, 180, 4);
            expectedDistances = new long[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            Assert.AreEqual(expectedDistances.Length, distances.Count);

            foreach (var expectedDistance in expectedDistances)
            {
                Assert.IsTrue(distances.Remove(expectedDistance));
            }
            Assert.AreEqual(0, distances.Count);
        }
예제 #17
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            var m = default(int);
            var i = default(int);

            if (DA.GetData(0, ref m))
            {
                return;
            }
            if (DA.GetData(1, ref i))
            {
                return;
            }

            var hilbert = new HilbertCurve(2);

            var p = hilbert.PointAt((ulong)i);

            DA.SetData(0, p[0]);
            DA.SetData(1, p[1]);
            DA.SetData(2, p[2]);
        }
예제 #18
0
    public void GeneratePath()
    {
        n = lastPowerOf2(n);

        System.Random pseudoRandom = new System.Random(seed);

        xOffset = pseudoRandom.Next(0, n + 1);
        yOffset = pseudoRandom.Next(0, n + 1);
        //Vector3 pos = new Vector3(-n / 2 + .5f, 0, -n / 2 + .5f);
        Vector3 pos = new Vector3((1 - n) * (roomDist + roomSize), 0, (1 - n) * (roomDist + roomSize));

        HilbertCurve.GenerateCurve(powerOf + 1, pos, roomDist, roomSize);

        List <Vector3> subGrid = HilbertCurve.GetSubGrid(xOffset, yOffset, n);

        path = HilbertCurve.GeneratePath(HilbertCurve.hilbertPoints, subGrid, deadEndsNumb, maxRooms);

        if (changeMap)
        {
            ResetRooms();
        }
    }
예제 #19
0
        public void TestHilbertDistance4()
        {
            Assert.AreEqual(0, HilbertCurve.HilbertDistance(-90 + (45 * 0) + 25.5f, -180 + (90 * 0) + 45f, 4));
            Assert.AreEqual(1, HilbertCurve.HilbertDistance(-90 + (45 * 0) + 25.5f, -180 + (90 * 1) + 45f, 4));
            Assert.AreEqual(2, HilbertCurve.HilbertDistance(-90 + (45 * 1) + 25.5f, -180 + (90 * 1) + 45f, 4));
            Assert.AreEqual(3, HilbertCurve.HilbertDistance(-90 + (45 * 1) + 25.5f, -180 + (90 * 0) + 45f, 4));

            Assert.AreEqual(4, HilbertCurve.HilbertDistance(-90 + (45 * 2) + 25.5f, -180 + (90 * 0) + 45f, 4));
            Assert.AreEqual(5, HilbertCurve.HilbertDistance(-90 + (45 * 3) + 25.5f, -180 + (90 * 0) + 45f, 4));
            Assert.AreEqual(6, HilbertCurve.HilbertDistance(-90 + (45 * 3) + 25.5f, -180 + (90 * 1) + 45f, 4));
            Assert.AreEqual(7, HilbertCurve.HilbertDistance(-90 + (45 * 2) + 25.5f, -180 + (90 * 1) + 45f, 4));

            Assert.AreEqual(8, HilbertCurve.HilbertDistance(-90 + (45 * 2) + 25.5f, -180 + (90 * 2) + 45f, 4));
            Assert.AreEqual(9, HilbertCurve.HilbertDistance(-90 + (45 * 3) + 25.5f, -180 + (90 * 2) + 45f, 4));
            Assert.AreEqual(10, HilbertCurve.HilbertDistance(-90 + (45 * 3) + 25.5f, -180 + (90 * 3) + 45f, 4));
            Assert.AreEqual(11, HilbertCurve.HilbertDistance(-90 + (45 * 2) + 25.5f, -180 + (90 * 3) + 45f, 4));

            Assert.AreEqual(12, HilbertCurve.HilbertDistance(-90 + (45 * 1) + 25.5f, -180 + (90 * 3) + 45f, 4));
            Assert.AreEqual(13, HilbertCurve.HilbertDistance(-90 + (45 * 1) + 25.5f, -180 + (90 * 2) + 45f, 4));
            Assert.AreEqual(14, HilbertCurve.HilbertDistance(-90 + (45 * 0) + 25.5f, -180 + (90 * 2) + 45f, 4));
            Assert.AreEqual(15, HilbertCurve.HilbertDistance(-90 + (45 * 0) + 25.5f, -180 + (90 * 3) + 45f, 4));
        }
예제 #20
0
        private void HilbertFill()
        {
            var curve = HilbertCurve.GenerateHilbertCurve(HilbertIterationsRequired());
            // inflate curve to gridSize (this could be a grid method eventually)
            var temp = new Grid <bool>(curve.gridSize.Times(gridSize));

            foreach (Cell <bool> C in curve.EachCell())
            {
                bool value = curve.GetCell(C.loc);
                foreach (var C2 in Methods.EachPoint(new Coord(gridSize)))
                {
                    temp.SetCell(C.loc.Times(gridSize).Plus(C2), value);
                }
            }
            curve = temp;

            curve = curve.Crop(new Coord(0, 0), size);

            foreach (var cell in curve.EachCell())
            {
                ArtColor color = BinaryColor(cell.value, ArtColor.White.Blend(ArtColor.White, 75), ArtColor.Green.Blend(ArtColor.Red, 25));//funColor2(cell.loc, cell.value);
                canvas.SetCell(cell.loc, color);
            }
        }
예제 #21
0
        public ArtLayer Generate(CommonInfo _Info)
        {
            Info = _Info;
            var result = new ArtLayer(Info.Size);
            var curve  = HilbertCurve.GenerateHilbertCurve(HilbertIterationsRequired());
            // inflate curve to gridSize (this could be a grid method eventually)
            var temp = new Grid <bool>(curve.gridSize.Times(Info.PatternScale));

            foreach (Cell <bool> C in curve.EachCell())
            {
                bool value = curve.GetCell(C.loc);
                foreach (var C2 in Methods.EachPoint(new Coord(Info.PatternScale)))
                {
                    temp.SetCell(C.loc.Times(Info.PatternScale).Plus(C2), value);
                }
            }
            curve = temp;

            curve = curve.Crop(new Coord(0, 0), Info.Size);

            foreach (var cell in curve.EachCell())
            {
                if (cell.value == true)
                {
                    Info.Phase = 0;
                }
                else
                {
                    Info.Phase = 1;
                }
                Info.Position = cell.loc;
                ArtColor color = Info.Fill.Fill(Info);
                result.grid.SetCell(cell.loc, color);
            }
            return(result);
        }
예제 #22
0
        public void GenerateShape(float divDuration, float divSize, DateTime zeroTime, Transform parent,
                                  Material baseMat)
        {
            DateTime now = DateTime.Now;

            List <Vector3> verts = new List <Vector3>();
            List <int>     tris  = new List <int>();

            pointList = new List <Coord2>();

            if (shape)
            {
                Destroy(shape.gameObject);
            }

            if (guideSpan != SpanAlignment.None)
            {
                labels.DestroyAll();
            }

            GameObject shapeObject = new GameObject(name);

            shape = shapeObject.transform;
            shapeObject.transform.parent = parent;
            // Debug.Log( "Generated color for " + name + ": " + color );

            LineRenderer edgePrefabToUse = instance.edgePrefab;

            if (guideSpan == SpanAlignment.Months)
            {
                edgePrefabToUse = instance.monthEdgePrefab;
            }
            if (guideSpan == SpanAlignment.Years)
            {
                edgePrefabToUse = instance.yearEdgePrefab;
            }
            if (guideSpan == SpanAlignment.Decades)
            {
                edgePrefabToUse = instance.decadeEdgePrefab;
            }

            if (guideSpan != SpanAlignment.None)
            {
                blocks.Clear();
            }

            switch (guideSpan)
            {
            case SpanAlignment.Months: {
                DateTime currStartDate = instance.mapStartTime;

                while (currStartDate <= now)
                {
                    DateTime endDate = currStartDate.AddMonths(1).AddDays(1 - currStartDate.Day);
                    if (endDate > now)
                    {
                        endDate = now;
                    }
                    blocks.Add(new TimeBlock(currStartDate, endDate, currStartDate.Month.ToString()));
                    if (endDate == now)
                    {
                        break;
                    }
                    currStartDate = endDate;
                }
            } break;

            case SpanAlignment.Years: {
                DateTime currStartDate = calendarAligned ? instance.mapStartTime : instance.lifeStartTime;
                int      age           = 0;

                while (currStartDate <= now)
                {
                    DateTime endDate = currStartDate.AddYears(1);
                    if (calendarAligned)
                    {
                        endDate = endDate.AddDays(1 - endDate.DayOfYear);
                    }
                    if (endDate > now)
                    {
                        endDate = now;
                    }
                    blocks.Add(new TimeBlock(currStartDate, endDate,
                                             (calendarAligned ? currStartDate.Year : age).ToString()));
                    if (endDate == now)
                    {
                        break;
                    }
                    currStartDate = endDate;
                    age++;
                }
            } break;

            case SpanAlignment.Decades: {
                DateTime currStartDate = calendarAligned ? instance.mapStartTime : instance.lifeStartTime;
                int      age           = 0;

                while (currStartDate <= now)
                {
                    DateTime endDate = currStartDate.AddYears(10);
                    if (calendarAligned)
                    {
                        endDate = new DateTime(endDate.Year - endDate.Year % 10, 1, 1);
                    }
                    if (endDate > now)
                    {
                        endDate = now;
                    }
                    blocks.Add(new TimeBlock(currStartDate, endDate,
                                             (calendarAligned ? currStartDate.Year - currStartDate.Year % 10 : age) + "s"));
                    if (endDate == now)
                    {
                        break;
                    }
                    currStartDate = endDate;
                    age          += 10;
                }
            } break;
            }

            foreach (var block in blocks)
            {
                int startDiv = (int)(block.startTime.Subtract(zeroTime).TotalDays / divDuration);
                int endDiv   = (int)(block.endTime.Subtract(zeroTime).TotalDays / divDuration);
                bool[,]                   blockPoints = new bool[size, size];
                bool[,]                   vertLines   = new bool[size + 1, size + 1];
                bool[,]                   horizLines  = new bool[size + 1, size + 1];
                List <Coord2>            blockPointList = new List <Coord2>();
                HashSet <Coord2>         coveredPoints  = new HashSet <Coord2>();
                Dictionary <Coord2, int> rectSizes      = new Dictionary <Coord2, int>();

                /*
                 * bool debug = Random.value < 0.1f;
                 * /*/
                bool debug = false;
                //*/

                // Debug.Log( "Drawing shape for " + name + "; start: " + block.startTime + "; startDiv: " + startDiv
                //               + "; end: " + block.endTime + "; endDiv: " + endDiv );

                for (int i = startDiv; i < endDiv; i++)
                {
                    int[] originCoords = HilbertCurve.IntToHilbert(i, 2);

                    points     [originCoords[0], originCoords[1]] = true;
                    blockPoints[originCoords[0], originCoords[1]] = true;
                    blockPointList.Add(new Coord2(originCoords[0], originCoords[1]));
                    pointList.Add(new Coord2(originCoords[0], originCoords[1]));
                }

                blockPointList = blockPointList.OrderByDescending(p =>
                                                                  Enumerable.Range(0, 8)
                                                                  .Select(n => (int)Mathf.Pow(2, n))
                                                                  .Where(n => p.x % n == 0 && p.y % n == 0)
                                                                  .Max()).ToList();

                if (debug)
                {
                    Debug.Log("points in block: " + Utils.PrintVals(blockPointList.ToArray(), false, true));
                }

                foreach (var point in blockPointList)
                {
                    if (coveredPoints.Contains(point))
                    {
                        continue;
                    }
                    //coveredPoints.Add( point );
                    int         rectSize = 1;
                    Coord2Range range    = new Coord2Range(point);

                    for (rectSize = 1; rectSize < 256; rectSize *= 2)
                    {
                        if (point.x % rectSize != 0 || point.y % rectSize != 0)
                        {
                            break;
                        }
                        if (point.x + rectSize > size || point.y + rectSize > size)
                        {
                            break;
                        }

                        var newRange = new Coord2Range(point, point + Coord2.one * (rectSize - 1));
                        if (newRange.Any(p => !blockPoints[p.x, p.y] || coveredPoints.Contains(p)))
                        {
                            break;
                        }

                        range = newRange;

                        if (debug)
                        {
                            Debug.Log("rect size: " + rectSize + "; range: " + range + "; covered by range: "
                                      + Utils.PrintVals(range.ToArray(), false, true));
                        }
                    }
                    rectSize /= 2;
                    foreach (var covered in range)
                    {
                        coveredPoints.Add(covered);
                    }
                    if (debug)
                    {
                        Debug.Log("covered points is now: " + Utils.PrintVals(coveredPoints.ToArray(), false, true));
                    }
                    rectSizes[point] = rectSize;
                }

                if (debug)
                {
                    Debug.Log("Rect sizes for block in " + name + ":\n"
                              + string.Join("\n", rectSizes.Select(r => r.Key + ": " + r.Value).ToArray()));
                }

                foreach (var rect in rectSizes)
                {
                    int     vertInd = verts.Count;
                    Vector3 origin  = new Vector3(rect.Key.x, instance.elementMeshY, rect.Key.y) * divSize;

                    verts.Add(origin);
                    verts.Add(origin + Vector3.forward * divSize * rect.Value);
                    verts.Add(origin + Vector3.right * divSize * rect.Value);
                    verts.Add(origin + new Vector3(divSize, 0.0f, divSize) * rect.Value);

                    tris.Add(vertInd);
                    tris.Add(vertInd + 1);
                    tris.Add(vertInd + 3);
                    tris.Add(vertInd);
                    tris.Add(vertInd + 3);
                    tris.Add(vertInd + 2);
                }

                // add corners
                CornerDir[,] corners = new CornerDir[size + 1, size + 1];

                // add individual edge segments
                for (int x = 0; x < size; x++)
                {
                    for (int y = 0; y < size; y++)
                    {
                        if (!blockPoints[x, y])
                        {
                            continue;
                        }

                        if (((x == 0 || !blockPoints[x - 1, y]) && (y == 0 || !blockPoints[x, y - 1])) ||
                            ((x > 0 && blockPoints[x - 1, y]) && (y > 0 && blockPoints[x, y - 1])))
                        {
                            corners[x, y] = CornerDir.LowerLeft;
                        }

                        if (((x == 0 || !blockPoints[x - 1, y]) && (y == size - 1 || !blockPoints[x, y + 1])) ||
                            ((x > 0 && blockPoints[x - 1, y]) && (y < size - 1 && blockPoints[x, y + 1])))
                        {
                            corners[x, y + 1] = CornerDir.UpperLeft;
                        }

                        if (((x == size - 1 || !blockPoints[x + 1, y]) && (y == size - 1 || !blockPoints[x, y + 1])) ||
                            ((x < size - 1 && blockPoints[x + 1, y]) && (y < size - 1 && blockPoints[x, y + 1])))
                        {
                            corners[x + 1, y + 1] = CornerDir.UpperRight;
                        }

                        if (((x == size - 1 || !blockPoints[x + 1, y]) && (y == 0 || !blockPoints[x, y - 1])) ||
                            ((x < size - 1 && blockPoints[x + 1, y]) && (y > 0 && blockPoints[x, y - 1])))
                        {
                            corners[x + 1, y] = CornerDir.LowerRight;
                        }

                        if (x == 0 || !blockPoints[x - 1, y])
                        {
                            vertLines[x, y] = true;
                        }
                        if (x == size - 1 || !blockPoints[x + 1, y])
                        {
                            vertLines[x + 1, y] = true;
                        }

                        if (y == 0 || !blockPoints[x, y - 1])
                        {
                            horizLines[x, y] = true;
                        }
                        if (y == size - 1 || !blockPoints[x, y + 1])
                        {
                            horizLines[x, y + 1] = true;
                        }
                    }
                }

                // combine edge segments into lines
                List <LineSpan> spans = new List <LineSpan>();

                // vertical lines first
                for (int x = 0; x <= size; x++)
                {
                    for (int y = 0; y <= size; y++)
                    {
                        if (!vertLines[x, y])
                        {
                            continue;
                        }

                        int startY = y;
                        while (vertLines[x, y])
                        {
                            y++;
                        }

                        spans.Add(new LineSpan(x, startY, x, y));
                    }
                }

                for (int y = 0; y <= size; y++)
                {
                    for (int x = 0; x <= size; x++)
                    {
                        if (!horizLines[x, y])
                        {
                            continue;
                        }

                        int startX = x;
                        while (horizLines[x, y])
                        {
                            x++;
                        }

                        spans.Add(new LineSpan(startX, y, x, y));
                    }
                }

                //Debug.Log( name + " block has " + spans.Count + " line spans" );

                if (spans.Count == 0)
                {
                    continue;
                }
                List <Coord2> lineCoords = new List <Coord2>();
                LineSpan      currSpan   = spans.Random();
                spans.Remove(currSpan);
                LineSpan nextSpan = null;
                Coord2   currEnd  = currSpan.end;
                lineCoords.Add(currSpan.start);
                lineCoords.Add(currSpan.end);

                // Debug.Log( "currSpan is " + currEnd + "; all other spans:\n"
                //               + Utils.PrintVals( spans.ToArray(), false, true ) );

                // foreach (var span in spans) {

                //    Debug.Log( "Match " + span + ": " + (span.start == currEnd || span.end == currEnd) );
                // }

                while ((nextSpan = spans.FirstOrDefault(s => s.start == currEnd || s.end == currEnd)) != null)
                {
                    currEnd = nextSpan.start == currEnd ? nextSpan.end : nextSpan.start;
                    spans.Remove(nextSpan);
                    currSpan = nextSpan;
                    lineCoords.Add(currEnd);
                }

                LineRenderer lineRenderer = Instantiate(edgePrefabToUse, shapeObject.transform);
                lineRenderer.positionCount = lineCoords.Count;
                float yPosition = guideSpan == SpanAlignment.None ? instance.elementEdgeY : instance.guideEdgeY;
                lineRenderer.widthMultiplier *= divSize * 0.333f;
                float cornerShift = lineRenderer.widthMultiplier * 0.5f;
                // Vector3[] shunkLineVerts = instance.ShrinkPath( lineVerts.Select( c => ((Vector3) (Vector2) c) * divSize ).ToArray(),
                //                                                 lineRenderer.widthMultiplier * 0.5f );
                Vector3[] lineVerts = lineCoords.Select(coord => {
                    var cornerDir = corners[coord.x, coord.y];
                    Vector3 vert  = new Vector3(coord.x * divSize, yPosition, coord.y * divSize);
                    if (guideSpan != SpanAlignment.None)
                    {
                        return(vert);
                    }
                    if (cornerDir == CornerDir.UpperLeft || cornerDir == CornerDir.LowerLeft)
                    {
                        vert.x += cornerShift;
                    }
                    else
                    {
                        vert.x -= cornerShift;
                    }
                    if (cornerDir == CornerDir.UpperLeft || cornerDir == CornerDir.UpperRight)
                    {
                        vert.z -= cornerShift;
                    }
                    else
                    {
                        vert.z += cornerShift;
                    }
                    return(vert);
                }).ToArray();
                lineRenderer.SetPositions(lineVerts);

                if (guideSpan == SpanAlignment.None)
                {
                    Color edgeColor = color.ShiftLuma(0.1f);
                    edgeColor.a             = 1.0f;
                    lineRenderer.startColor = lineRenderer.endColor = edgeColor;
                }
                // Debug.Log( "Generated edge color for " + name + ": " + edgeColor );

                if (guideSpan != SpanAlignment.None)
                {
                    Vector3 position = blockPointList.Select(v => new Vector3(v.x, 0.0f, v.y)).Average() * divSize
                                       + Vector3.up * instance.guideLabelY;

                    if (!block.label)
                    {
                        block.label = Instantiate(labelPrefabToUse, labelParent.transform as RectTransform);
                        //label.transform.position = position;
                        block.label.localPosition = Utils.WorldToCanvasSpace(position, labelParent.transform as RectTransform,
                                                                             block.label);
                        Text labelText = block.label.GetComponentInChildren <Text>();
                        labelText.text = block.labelString;
                        labels.Add(block.label);
                    }

                    block.label.localPosition
                        = Utils.WorldToCanvasSpace(position, labelParent.transform as RectTransform,
                                                   block.label.transform as RectTransform);
                }
            }

            if (guideSpan == SpanAlignment.None)
            {
                Mesh mesh = new Mesh();
                mesh.vertices  = verts.ToArray();
                mesh.triangles = tris.ToArray();
                mesh.RecalculateBounds();
                mesh.RecalculateNormals();
                MeshFilter meshFilter = shapeObject.AddComponent <MeshFilter>();
                meshFilter.sharedMesh = mesh;
                Material mat = new Material(baseMat);
                mat.color = color * 0.6f;
                // Debug.Log( "Applying mesh material color for " + name + ": " + color );
                MeshRenderer meshRenderer = shapeObject.AddComponent <MeshRenderer>();
                meshRenderer.sharedMaterial = mat;

                Vector3 position = pointList.Select(v => new Vector3(v.x, 0.0f, v.y)).Average() * divSize
                                   + Vector3.up * instance.elementLabelY;
                //Debug.Log( name + " average point position: " + position );
                //label.transform.position = position;
                label.localPosition = Utils.WorldToCanvasSpace(position, labelParent.transform as RectTransform,
                                                               label.transform as RectTransform);
            }
        }
예제 #23
0
        public TabView(HilbertCurve iteration)
        {
            InitializeComponent();

            this.DataContext = new TabViewModel(iteration);
        }
예제 #24
0
        public void TestSorting()
        {
            // build locations.
            var locations = new List <Coordinate>();

            locations.Add(new Coordinate(-90, -180));
            locations.Add(new Coordinate(-90, -60));
            locations.Add(new Coordinate(-90, 60));
            locations.Add(new Coordinate(-90, 180));
            locations.Add(new Coordinate(-30, -180));
            locations.Add(new Coordinate(-30, -60));
            locations.Add(new Coordinate(-30, 60));
            locations.Add(new Coordinate(-30, 180));
            locations.Add(new Coordinate(30, -180));
            locations.Add(new Coordinate(30, -60));
            locations.Add(new Coordinate(30, 60));
            locations.Add(new Coordinate(30, 180));
            locations.Add(new Coordinate(90, -180));
            locations.Add(new Coordinate(90, -60));
            locations.Add(new Coordinate(90, 60));
            locations.Add(new Coordinate(90, 180));

            // build db.
            var db = new StopsDb(locations.Count);

            for (var stop = 0; stop < locations.Count; stop++)
            {
                db.Add((float)locations[stop].Latitude,
                       (float)locations[stop].Longitude, (uint)(stop * 2));
            }

            // build a sorted version in-place.
            db.Sort(null);

            // test if sorted.
            var enumerator = db.GetEnumerator();

            for (var stop = 1; stop < locations.Count; stop++)
            {
                enumerator.MoveTo((uint)stop - 1);
                var latitude1  = enumerator.Latitude;
                var longitude1 = enumerator.Longitude;
                enumerator.MoveTo((uint)stop);
                var latitude2  = enumerator.Latitude;
                var longitude2 = enumerator.Longitude;

                Assert.IsTrue(
                    HilbertCurve.HilbertDistance(latitude1, longitude1, HilbertExtensions.DefaultHilbertSteps) <=
                    HilbertCurve.HilbertDistance(latitude2, longitude2, HilbertExtensions.DefaultHilbertSteps));
            }

            // sort locations.
            locations.Sort((x, y) =>
            {
                return(HilbertCurve.HilbertDistance(x.Latitude, x.Longitude, HilbertExtensions.DefaultHilbertSteps).CompareTo(
                           HilbertCurve.HilbertDistance(y.Latitude, y.Longitude, HilbertExtensions.DefaultHilbertSteps)));
            });

            // confirm sort.
            enumerator = db.GetEnumerator();
            for (var stop = 0; stop < locations.Count; stop++)
            {
                enumerator.MoveTo((uint)stop);
                Assert.AreEqual(enumerator.Latitude, locations[(int)stop].Latitude);
                Assert.AreEqual(enumerator.Longitude, locations[(int)stop].Longitude);
            }
        }
        public BlockCompressor(int chunkSize)
        {
            _chunkSize = chunkSize;

            if (!IntervalToBlockMappings.ContainsKey(_chunkSize))
            {
                var count               = _chunkSize * _chunkSize * _chunkSize;
                var mappingFunctions    = new Dictionary <CompressionFlag, int[]>();
                var bitsPerAxis         = (int)Math.Ceiling(Math.Log(chunkSize, 2));
                var hilbertToBlockIndex = new int[count];
                for (uint index = 0; index < count; ++index)
                {
                    var arr        = HilbertCurve.HilbertAxes(index, bitsPerAxis);
                    var blockIndex = General.BlockIndex(arr.x, arr.y, arr.z, _chunkSize);
                    hilbertToBlockIndex[index] = blockIndex;
                }
                mappingFunctions[CompressionFlag.Hilbert] = hilbertToBlockIndex;
                foreach (ScanDirection scanDirection in Enum.GetValues(typeof(ScanDirection)))
                {
                    var workCoords = new Vector3Int();
                    var mapping    = new int[count];
                    for (var i = 0; i < count; ++i)
                    {
                        mapping[GetNextIndex(scanDirection, _chunkSize, ref workCoords)] = i;
                    }
                    CompressionFlag compressionFlag;
                    switch (scanDirection)
                    {
                    case ScanDirection.Xyz:
                        compressionFlag = CompressionFlag.LinearXyz;
                        break;

                    case ScanDirection.Xzy:
                        compressionFlag = CompressionFlag.LinearXzy;
                        break;

                    case ScanDirection.Yxz:
                        compressionFlag = CompressionFlag.LinearYxz;
                        break;

                    case ScanDirection.Yzx:
                        compressionFlag = CompressionFlag.LinearYzx;
                        break;

                    case ScanDirection.Zxy:
                        compressionFlag = CompressionFlag.LinearZxy;
                        break;

                    case ScanDirection.Zyx:
                        compressionFlag = CompressionFlag.LinearZyx;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    mappingFunctions[compressionFlag] = mapping;
                }
                IntervalToBlockMappings[chunkSize] = mappingFunctions;
                BlockToIntervalMappings[chunkSize] = new Dictionary <CompressionFlag, int[]>();
                foreach (var pair in IntervalToBlockMappings[chunkSize])
                {
                    var mappingFunction = pair.Value;
                    var inverseFunction = new int[mappingFunction.Length];
                    for (int i = 0; i < mappingFunction.Length; i++)
                    {
                        inverseFunction[mappingFunction[i]] = i;
                    }
                    BlockToIntervalMappings[chunkSize][pair.Key] = inverseFunction;
                }
            }
            _intervalToBlock = IntervalToBlockMappings[chunkSize];
            _blockToInterval = BlockToIntervalMappings[chunkSize];
        }