public static QuadtreeNode BuildTree(List <DataRow> data, byte zoomLevelsCount = 1) { QuadtreeNode node = new QuadtreeNode(); QuadtreeNode startNode = node; for (byte zoomLevel = zoomLevelsCount; zoomLevel >= 1; zoomLevel--) { QuadtreeNode newParent = null; int counter = 0; foreach (DataRow row in data) { SimpleNode newNode = new SimpleNode() { X = row.Argument, Y = row.Value, SourceIndex = counter }; node = startNode; int maxDepth = QuadtreeNode.MaxIterations; do { newParent = node.Connect(newNode, zoomLevel, zoomLevelsCount); if (newParent != null) { node = newParent; } }while (newParent != null && maxDepth-- > 0); counter++; } } return(startNode); }
public MainWindow() { InitializeComponent(); List <DataRow> data = Generator.Generate2(); startNode = QuardtreeBuilder.BuildTree(data, zoomLevelsCount); wholeRange = QuardtreeBuilder.GetWholeRange(startNode); LayoutUpdated += MainWindow_LayoutUpdated; }
public void VisitNodes(Tuple <Range, Range> visibleRange, double zoomLevel, Action <SimpleNode> callback) { QuadtreeNode currentNode = this; int watchdog = MaxIterations; Stack <QuadtreeNode> nodes = new Stack <QuadtreeNode>(); do { QuadtreeNodeTypes orientationMin = currentNode.CalculateOrientation(visibleRange.Item1.Min, visibleRange.Item2.Min); QuadtreeNodeTypes orientationMax = currentNode.CalculateOrientation(visibleRange.Item1.Max, visibleRange.Item2.Max); foreach (QuadtreeNodeTypes nodeType in Enum.GetValues(typeof(QuadtreeNodeTypes))) { QuadtreeNode node = currentNode.GetChildNode(nodeType); if (node == null || node.IsEmpty) { continue; } if (node.ZoomLevel < zoomLevel) { continue; } if (node == currentNode) { callback(node); continue; } if (orientationMax == orientationMin && orientationMin != nodeType) { continue; } if (orientationMin == QuadtreeNodeTypes.SW && orientationMax == QuadtreeNodeTypes.SE && (nodeType == QuadtreeNodeTypes.NE || nodeType == QuadtreeNodeTypes.NW)) { continue; } if (orientationMin == QuadtreeNodeTypes.SW && orientationMax == QuadtreeNodeTypes.NW && (nodeType == QuadtreeNodeTypes.NE || nodeType == QuadtreeNodeTypes.SE)) { continue; } if (orientationMin == QuadtreeNodeTypes.NW && orientationMax == QuadtreeNodeTypes.NE && (nodeType == QuadtreeNodeTypes.SE || nodeType == QuadtreeNodeTypes.SW)) { continue; } nodes.Push(node); } if (nodes.Count == 0) { break; } currentNode = nodes.Pop(); }while (nodes.Count >= 0 && watchdog-- > 0); }
public static Tuple <Range, Range> GetWholeRange(QuadtreeNode startNode) { QuadtreeNode ne = GetEdgeNode(startNode, QuadtreeNodeTypes.NE); QuadtreeNode nw = GetEdgeNode(startNode, QuadtreeNodeTypes.NW); QuadtreeNode se = GetEdgeNode(startNode, QuadtreeNodeTypes.SE); QuadtreeNode sw = GetEdgeNode(startNode, QuadtreeNodeTypes.SW); return(new Tuple <Range, Range>( new Range() { Min = SimpleNode.GetMin(nw.X, sw.X), Max = SimpleNode.GetMax(ne.X, se.X) }, new Range() { Min = SimpleNode.GetMin(sw.Y, se.Y), Max = SimpleNode.GetMax(ne.Y, nw.Y) })); }
void CheckNodes(QuadtreeNodeTypes hint) { if (NW == null && hint == QuadtreeNodeTypes.NW) { NW = new QuadtreeNode(); } if (NE == null && hint == QuadtreeNodeTypes.NE) { NE = new QuadtreeNode(); } if (SW == null && hint == QuadtreeNodeTypes.SW) { SW = new QuadtreeNode(); } if (SE == null && hint == QuadtreeNodeTypes.SE) { SE = new QuadtreeNode(); } }
public static QuadtreeNode GetEdgeNode(QuadtreeNode startNode, QuadtreeNodeTypes corner) { QuadtreeNode result = startNode; QuadtreeNode newParent = null; int maxDepth = QuadtreeNode.MaxIterations; do { newParent = result.GetChildNode(corner); if (newParent != null) { result = newParent; } if (maxDepth < 1) { throw new Exception("too large data"); } }while (newParent != null && maxDepth-- > 0); return(result); }
public QuadtreeNode Connect(SimpleNode newNode, byte zoomLevel, int zoomLevelsCount) { QuadtreeNode whereToAdd = null; if (IsEmpty) { whereToAdd = this; } else { if (CanSimplify(newNode, zoomLevel, zoomLevelsCount)) { whereToAdd = this; } else { whereToAdd = GetChildNode(CalculateOrientation(newNode.X, newNode.Y), true); } } if (whereToAdd != null) { if (whereToAdd.IsEmpty) { whereToAdd.X = newNode.X; whereToAdd.Y = newNode.Y; whereToAdd.SourceIndex = newNode.SourceIndex; whereToAdd.ZoomLevel = zoomLevel; } else { if (whereToAdd != this) { return(whereToAdd); } } } return(null); }