@@ -289,17 +289,15 @@ function TKDTree.IndexOf(const Value: TSingleArray): Integer;
289289 function FindNode (Node: Integer; Depth: Integer): Integer;
290290 var
291291 Axis, i: Integer;
292+ SplitVal, Val: Single;
292293 Equal: Boolean;
293- This: PKDNode;
294294 begin
295295 if Node = NONE then
296296 Exit(NONE);
297297
298- This := @Self.Data[Node];
299-
300298 Equal := True;
301299 for i := 0 to Self.Dimensions - 1 do
302- if not FloatEqual(This^ .Split.Vector[i], Value [i]) then
300+ if not FloatEqual(Self.Data[Node] .Split.Vector[i], Value [i]) then
303301 begin
304302 Equal := False;
305303 Break;
@@ -309,13 +307,20 @@ function TKDTree.IndexOf(const Value: TSingleArray): Integer;
309307 Exit(Node);
310308
311309 Axis := Depth mod Self.Dimensions;
310+ SplitVal := Self.Data[Node].Split.Vector[Axis];
311+ Val := Value [Axis];
312312
313- if Value [Axis] < This^.Split.Vector[Axis] then
314- Result := FindNode(This^.L, Depth + 1 )
313+ if FloatEqual(Val, SplitVal) then
314+ begin
315+ Result := FindNode(Self.Data[Node].L, Depth + 1 );
316+ if Result = NONE then
317+ Result := FindNode(Self.Data[Node].R, Depth + 1 );
318+ end
319+ else if Val < SplitVal then
320+ Result := FindNode(Self.Data[Node].L, Depth + 1 )
315321 else
316- Result := FindNode(This^ .R, Depth + 1 );
322+ Result := FindNode(Self.Data[Node] .R, Depth + 1 );
317323 end ;
318-
319324begin
320325 Result := FindNode(0 , 0 );
321326end ;
@@ -563,32 +568,35 @@ function TKDTree.RangeQuery(Low, High: TSingleArray; Setting: TTreeSettings = []
563568function TKDTree.RangeQueryEx (Center: TSingleArray; Radii: TSingleArray; Setting: TTreeSettings = []; WorkingRef: Integer = NONE): TKDItems;
564569var
565570 i, ResultSize: Integer;
566- SumSqRadii: Single;
571+ sqrProduct: Single;
572+ sqRadii: array of single;
573+
574+ function Fits (const p,c: TSingleArray): Boolean; { inline; produces worse machinecode}
575+ var
576+ dsqr: Single;
577+ i: Integer;
578+ begin
579+ dsqr := 0 ;
580+ for i := 0 to High(p) do
581+ begin
582+ dsqr += (Sqr(p[i] - c[i]) * sqRadii[i]);
583+ if dsqr > sqrProduct then Exit(False);
584+ end ;
585+
586+ Result := dsqr <= sqrProduct;
587+ end ;
567588
568589 procedure Query (Node: Integer; Depth: UInt8);
569590 var
570591 This: PKDNode;
571592 Axis: Integer;
572- i: Integer;
573- DistSq: Single;
574- WithinRange: Boolean;
575593 begin
576594 if Node = NONE then Exit;
577595
578596 This := @Self.Data[Node];
579597 Axis := Depth mod Self.Dimensions;
580598
581- DistSq := 0 ;
582- for i := 0 to Self.Dimensions - 1 do
583- begin
584- DistSq += Sqr(This^.Split.Vector[i] - Center[i]);
585- if DistSq > SumSqRadii then
586- break;
587- end ;
588-
589- WithinRange := DistSq <= SumSqRadii;
590-
591- if WithinRange then
599+ if Fits(This^.Split.Vector, Center) then
592600 begin
593601 if (tsIgnoreHidden in Setting) and This^.Hidden then
594602 Exit;
@@ -614,9 +622,13 @@ function TKDTree.RangeQueryEx(Center: TSingleArray; Radii: TSingleArray; Setting
614622 end ;
615623
616624begin
617- SumSqRadii := 0 ;
618- for i := 0 to Self.Dimensions - 1 do
619- SumSqRadii := SumSqRadii + Sqr(Radii[i]);
625+ SetLength(sqRadii, Self.Dimensions);
626+ for i:=0 to High(radii) do
627+ sqRadii[i] := Sqr(Radii[i]);
628+
629+ sqrProduct := 1.0 ;
630+ for i:=0 to High(radii) do
631+ sqrProduct *= sqradii[i];
620632
621633 SetLength(Result, 1024 );
622634 ResultSize := 0 ;
0 commit comments