Skip to content

Commit 03dafe8

Browse files
committed
Fixes KDTree.RangeQueryEx
1 parent f79e177 commit 03dafe8

1 file changed

Lines changed: 38 additions & 26 deletions

File tree

Source/simba.container_kdtree.pas

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
319324
begin
320325
Result := FindNode(0, 0);
321326
end;
@@ -563,32 +568,35 @@ function TKDTree.RangeQuery(Low, High: TSingleArray; Setting: TTreeSettings = []
563568
function TKDTree.RangeQueryEx(Center: TSingleArray; Radii: TSingleArray; Setting: TTreeSettings = []; WorkingRef: Integer = NONE): TKDItems;
564569
var
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

616624
begin
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

Comments
 (0)