// prekresli sa vrchol private void repaintNodes(KDNode n) { System.Drawing.Font font = new System.Drawing.Font("Verdana", 10); System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black); System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Black); if (n.highlight) { myBrush.Color = System.Drawing.Color.Green; myPen.Color = System.Drawing.Color.Green; } if (n.highlightRed) { myBrush.Color = System.Drawing.Color.Red; myPen.Color = System.Drawing.Color.Red; } if (n.highligthIn) { myBrush.Color = System.Drawing.Color.Red; myPen.Color = System.Drawing.Color.Red; g.DrawEllipse(myPen, n.getPoint().X - (RADIUS + 2), n.getPoint().Y - (RADIUS + 2), 2 * (RADIUS + 2), 2 * (RADIUS + 2)); myPen.Color = System.Drawing.Color.Black; } g.FillEllipse(myBrush, n.getPoint().X - RADIUS, n.getPoint().Y - RADIUS, 2*RADIUS, 2*RADIUS); string s = "(" + n.getPoint().X.ToString() + "," + n.getPoint().Y.ToString() + ")"; g.DrawString(s, font, myBrush, n.getPoint().X - 35, n.getPoint().Y); }
private Boolean alreadyIn(KDNode n) { KDNode k = findBlockIn(n); if ((k.getPoint().X == n.getPoint().X) && (k.getPoint().Y == n.getPoint().Y)) { return true; } return false; }
// zistuje, ci je vrchol n vo vnutri obdlznika from, to public void findInside(KDNode n, Point from, Point to) { if (n.isLeaf) { // je vrchol vnutri obdlznika? if (pointInsideRect(n.getPoint(), from, to)) { inside.Add(n); } return; } // ak ma obdlznik s bunkou nejaky prienik vnori sa if (intersects(n, from, to)) { findInside(n.getLeft(), from, to); findInside(n.getRight(), from, to); } else { return; } }
private KDNode findIn(KDNode click, KDNode n, int dim) { if (n.isLeaf) { return n; } if (dim == 0) { if (n.getSplit() >= click.getPoint().X) { return findIn(click, n.getLeft(), 1 - dim); } else { return findIn(click, n.getRight(), 1 - dim); } } else { if (n.getSplit() >= click.getPoint().Y) { return findIn(click, n.getLeft(), 1 - dim); } else { return findIn(click, n.getRight(), 1 - dim); } } }
// najde najmensiu vzdialenost medzi target a bunkou further. public Point nearestTo(KDNode further, KDNode target) { Point from = further.getFrom(); Point to = further.getTo(); Point tar = target.getPoint(); Point result = new Point(); result.X = (tar.X <= from.X) ? from.X: ((tar.X >= to.X) ? to.X : tar.X); result.Y = (tar.Y <= from.Y) ? from.Y : ((tar.Y >= to.Y) ? to.Y : tar.Y); return result; }
// najde numNearest najblizsich vrcholov ku target // na konci budu v usporiadanom zozname nearestK public void findNearest(KDNode subTree, KDNode target) { // ak je to list, zistime, ci je blizsie ako doposial najdene, ak ich je dost if (subTree.isLeaf) { subTree.dist = distance(target.getPoint(), subTree.getPoint()); if (nearestK.Count < numNearest) { nearestK.Add(subTree); } else { if (nearestK.Last().dist > subTree.dist) { nearestK.Remove(nearestK.Last()); nearestK.Add(subTree); } } return; } int dim = subTree.getDim(); // ak je target v lavom podstrome, nearer je lavy a further je pravy, inak opacne KDNode nearer; KDNode further; if (dim == 0) { if (subTree.getSplit() >= target.getPoint().X) { nearer = subTree.getLeft(); further = subTree.getRight(); } else { further = subTree.getLeft(); nearer = subTree.getRight(); } } else { if (subTree.getSplit() >= target.getPoint().Y) { nearer = subTree.getLeft(); further = subTree.getRight(); }else { further = subTree.getLeft(); nearer = subTree.getRight(); } } // najprv prehladavame blizsi podstrom // (prvy prehladany blok bude ten, v kt. je target) // teda si ohranicime v priemere celkom slusne najblizsie vrcholy findNearest(nearer, target); // zrata najblizsi bod od target na bunke further // ak je dalej ako doposial najdeny k-ty nejmensi, tak vo further // nemoze byt blizsi bod => nevnara sa Point nearestF = nearestTo(further, target); double dist = distance(nearestF, target.getPoint()); if ((nearestK.Last().dist > dist) || (nearestK.Count < numNearest)) { findNearest(further, target); } }
// pre kazdy vrchol podstromu n updatne pocet listov, // ktore su pod nim public int updateNumLeafsDown(KDNode n) { if (n.isLeaf) { n.setNumLeafs(1); Console.WriteLine("update " + n.getPoint() + " numLeafs = 1"); return 1; } int r = updateNumLeafsDown(n.getRight()); int l = updateNumLeafsDown(n.getLeft()); n.setNumLeafs(r + l); Console.WriteLine("update " + n.getSplit() + " numLeafs = " + n.getNumLeafs()); return r + l; }
//vrati podstrom, do ktoreho syna ma ist novy vrchol a bola by v nom narusena rovnovaha public KDNode findPlace(KDNode n, KDNode leaf) { // ak n je list, potom sa rovnovaha nenarusi a iba sa novy vrchol vlozi. // z listu spravime otca dvoch listov v procedure rebuilt if(n.isLeaf) { //Console.Write(n.getPoint()); //Console.WriteLine(" numLeafs " + n.getNumLeafs()); return n; } //Console.Write(n.getSplit()); //Console.WriteLine(" numLeafs right" + n.getRight().getNumLeafs()); //Console.WriteLine(" numLeafs left" + n.getLeft().getNumLeafs()); // ak to nie je list, potom hladame podstrom, ktoremu sa narusi rovnovaha. if (n.getDim() == 0) // split je v x-ovej suradnici { if (n.getSplit() >= leaf.getPoint().X) // ak ma ist do laveho podstromu { // a uz teraz je vlavo viac listov ako vpravo, narusi sa rovnovaha n if (n.getLeft().getNumLeafs() > n.getRight().getNumLeafs()) { return n; } else { // inak sa vrati podstrom z laveho podstromu, v ktorom je narusena rovnovaha return findPlace(n.getLeft(), leaf); } } else { // ak ma ist do praveho podstromu // a uz teraz je vpravo viac listov ako vlavo, narusi sa rovnovaha n if (n.getLeft().getNumLeafs() < n.getRight().getNumLeafs()) { return n; } else { // inak sa vrati podstrom z praveho podstromu, v ktorom je narusena rovnovaha return findPlace(n.getRight(), leaf); } } } else { // split je v y-ovej suradnici if (n.getSplit() >= leaf.getPoint().Y) // ak ma ist do laveho podstromu (= patri hore, nad split) { // a uz teraz je vlavo viac listov ako vpravo, narusi sa rovnovaha n if (n.getLeft().getNumLeafs() > n.getRight().getNumLeafs()) { return n; } else { // inak sa vrati podstrom z laveho podstromu, v ktorom je narusena rovnovaha return findPlace(n.getLeft(), leaf); } } else { // ak ma ist do praveho podstromu (= patri dole, pod split) // a uz teraz je vpravo viac listov ako vlavo, narusi sa rovnovaha n if (n.getLeft().getNumLeafs() < n.getRight().getNumLeafs()) { return n; } else { // inak sa vrati podstrom z praveho podstromu, v ktorom je narusena rovnovaha return findPlace(n.getRight(), leaf); } } } }