Advertisement
WarPie90

Cluster - kdtree

Mar 17th, 2023 (edited)
1,265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 2.17 KB | None | 0 0
  1. // This builds on TSlackTree which is a 2D implementation of KD-Tree.
  2. // wrote this to see how well it would work (Comparable to SplitTPA)
  3. // It's a lot faster as soon as we are talking about +/-400 points and up.
  4. // This is O(n log n), and effectively come close to linear performance.
  5. //
  6. // For a proper implementation in n dimensions, with optimizations see:
  7. // https://github.com/Villavu/Simba/blob/baaaa37af8cc1ebe7ca656b05fda51353390fcb5/Source/simba.container_kdtree.pas#L719
  8.  
  9. function TSlackTree.Clusters(radX,radY: Double): T2DPointArray;
  10. var
  11.   rescount, qcount: Int32;
  12.   sqx, sqy, sqxy: Double;
  13.  
  14.   function Fits(p,c: TPoint): Boolean;
  15.   begin
  16.     //Result := (Abs(p.x-c.x) < radX) and (Abs(p.y-c.y) < radY);
  17.     Result := (Sqr(p.x-c.x)*sqy)+(Sqr(p.y-c.y)*sqx) <= sqxy;
  18.   end;
  19.  
  20.   procedure Cluster(test: TPoint; var result:TPointArray; this: PSlackNode; depth:Int32=0);
  21.   var
  22.     goright:Boolean = False;
  23.     goleft: Boolean = False;
  24.   begin
  25.     if depth and 1 = 0 then begin
  26.       goleft  := test.x - radX <= this^.split.x;
  27.       goright := test.x + radX >= this^.split.x;
  28.     end else begin
  29.       goleft  := test.y - radY <= this^.split.y;
  30.       goright := test.y + radY >= this^.split.y;
  31.     end;
  32.  
  33.     if (not this^.hidden) and ((goleft=goright)=True) and Fits(test, this^.split) then
  34.     begin
  35.       if rescount = Length(result) then Setlength(result, rescount*2);
  36.       result[rescount] := this^.split;
  37.       Inc(rescount);
  38.       this^.hidden := True;
  39.       Cluster(this^.split, result, @self.data[0], 0);
  40.     end;
  41.  
  42.     if goleft  and (this^.l <> -1) then Cluster(test, result, @self.data[this^.l], depth+1);
  43.     if goright and (this^.r <> -1) then Cluster(test, result, @self.data[this^.r], depth+1);
  44.   end;
  45. var
  46.   i,j,r:Int32;
  47.   t: TIntegerArray;
  48. begin
  49.   sqx := Sqr(radx);
  50.   sqy := Sqr(rady);
  51.   sqxy := sqx*sqy;
  52.  
  53.   j := 0;
  54.   for i:=0 to High(self.data) do
  55.   begin
  56.     if self.data[i].hidden then
  57.       continue;
  58.  
  59.     SetLength(result, j+1);
  60.     rescount := 0;
  61.     SetLength(result[j], 64);
  62.  
  63.     Cluster(self.data[i].split, result[j], @self.data[0]);
  64.     self.data[i].hidden := True;
  65.     SetLength(result[j], rescount);
  66.     Inc(j);
  67.   end;
  68. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement