mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 23:16:09 +02:00
TAChart: Optimize GetNearestPoint for the case of sorted source and at least linear on X point distance
git-svn-id: trunk@38853 -
This commit is contained in:
parent
f33a977acb
commit
c66a6f83f6
@ -33,6 +33,7 @@ const
|
||||
type
|
||||
TNearestPointParams = record
|
||||
FDistFunc: TPointDistFunc;
|
||||
FOptimizeX: Boolean;
|
||||
FPoint: TPoint;
|
||||
FRadius: Integer;
|
||||
end;
|
||||
@ -1013,14 +1014,32 @@ end;
|
||||
function TBasicPointSeries.GetNearestPoint(
|
||||
const AParams: TNearestPointParams;
|
||||
out AResults: TNearestPointResults): Boolean;
|
||||
|
||||
function GetGrabBound(ARadius: Integer): Double;
|
||||
begin
|
||||
if IsRotated then
|
||||
Result := ParentChart.YImageToGraph(AParams.FPoint.Y + ARadius)
|
||||
else
|
||||
Result := ParentChart.XImageToGraph(AParams.FPoint.X + ARadius);
|
||||
Result := GraphToAxisX(Result);
|
||||
end;
|
||||
|
||||
var
|
||||
dist, i: Integer;
|
||||
dist, i, lb, ub: Integer;
|
||||
pt: TPoint;
|
||||
sp: TDoublePoint;
|
||||
begin
|
||||
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
||||
AResults.FIndex := -1;
|
||||
for i := 0 to Count - 1 do begin
|
||||
if AParams.FOptimizeX then
|
||||
Source.FindBounds(
|
||||
GetGrabBound(-AParams.FRadius),
|
||||
GetGrabBound( AParams.FRadius), lb, ub)
|
||||
else begin
|
||||
lb := 0;
|
||||
ub := Count - 1;
|
||||
end;
|
||||
for i := lb to ub do begin
|
||||
sp := Source[i]^.Point;
|
||||
if IsNan(sp) then continue;
|
||||
// Since axis transformation may be non-linear, the distance should be
|
||||
|
@ -644,19 +644,25 @@ function TDrawFuncHelper.GetNearestPoint(
|
||||
const AParams: TNearestPointParams;
|
||||
out AResults: TNearestPointResults): Boolean;
|
||||
var
|
||||
x, r: Integer;
|
||||
x: Integer;
|
||||
r: TDoubleInterval;
|
||||
begin
|
||||
AResults.FIndex := -1;
|
||||
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
||||
FNearestPointParams := @AParams;
|
||||
FNearestPointResults := @AResults;
|
||||
|
||||
x := TPointBoolArr(AParams.FPoint)[FSeries.IsRotated];
|
||||
r := IfThen(FSeries.IsRotated, -1, 1) * AParams.FRadius;
|
||||
with AParams do
|
||||
if FOptimizeX then begin
|
||||
x := TPointBoolArr(FPoint)[FSeries.IsRotated];
|
||||
r := DoubleInterval(FImageToGraph(x - FRadius), FImageToGraph(x + FRadius));
|
||||
EnsureOrder(r.FStart, r.FEnd);
|
||||
end
|
||||
else
|
||||
r := DoubleInterval(NegInfinity, SafeInfinity);
|
||||
with XRange do
|
||||
ForEachPoint(
|
||||
Max(FImageToGraph(x - r), FStart),
|
||||
Min(FImageToGraph(x + r), FEnd),
|
||||
Max(r.FStart, FStart), Min(r.FEnd, FEnd),
|
||||
@CheckForNearestPoint, @CheckForNearestPoint);
|
||||
|
||||
Result := AResults.FDist < Sqr(AParams.FRadius) + 1;
|
||||
|
@ -1169,6 +1169,7 @@ begin
|
||||
p.FDistFunc := DIST_FUNCS[FChart.ReticuleMode];
|
||||
p.FPoint := APoint;
|
||||
p.FRadius := Trunc(Sqrt(MaxInt));
|
||||
p.FOptimizeX := false;
|
||||
for s in CustomSeries(FChart) do
|
||||
if
|
||||
(not (s is TBasicPointSeries) or TBasicPointSeries(s).UseReticule) and
|
||||
@ -1463,6 +1464,7 @@ begin
|
||||
p.FDistFunc := DIST_FUNCS[DistanceMode];
|
||||
p.FPoint := APoint;
|
||||
p.FRadius := GrabRadius;
|
||||
p.FOptimizeX := DistanceMode <> cdmOnlyY;
|
||||
best.FDist := MaxInt;
|
||||
for s in CustomSeries(FChart, FAffectedSeries.AsBooleans(FChart.SeriesCount)) do
|
||||
if
|
||||
|
Loading…
Reference in New Issue
Block a user