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); } }
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); } }
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)); }
public TabViewModel(HilbertCurve iteration) { this.iteration = iteration; this.CoordintesList = new List <Coordinates>(); this.RaisePropertyChanged("Points"); }
void OnDrawGizmos() { if (path.Count != 0) { //HilbertCurve.DrawRooms(HilbertCurve.hilbertPoints, Color.black); //HilbertCurve.DrawRooms(path, Color.white); HilbertCurve.DrawPath(path, Color.red); } }
// 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)); }
/// <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)); }
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)); }
/// <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)); }
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); }
/// <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); }
/// <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); }
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; }
// 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; }
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); }
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); }
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]); }
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(); } }
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)); }
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); } }
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); }
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); } }
public TabView(HilbertCurve iteration) { InitializeComponent(); this.DataContext = new TabViewModel(iteration); }
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]; }