mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-22 18:19:23 +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
|
type
|
||||||
TNearestPointParams = record
|
TNearestPointParams = record
|
||||||
FDistFunc: TPointDistFunc;
|
FDistFunc: TPointDistFunc;
|
||||||
|
FOptimizeX: Boolean;
|
||||||
FPoint: TPoint;
|
FPoint: TPoint;
|
||||||
FRadius: Integer;
|
FRadius: Integer;
|
||||||
end;
|
end;
|
||||||
@ -1013,14 +1014,32 @@ end;
|
|||||||
function TBasicPointSeries.GetNearestPoint(
|
function TBasicPointSeries.GetNearestPoint(
|
||||||
const AParams: TNearestPointParams;
|
const AParams: TNearestPointParams;
|
||||||
out AResults: TNearestPointResults): Boolean;
|
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
|
var
|
||||||
dist, i: Integer;
|
dist, i, lb, ub: Integer;
|
||||||
pt: TPoint;
|
pt: TPoint;
|
||||||
sp: TDoublePoint;
|
sp: TDoublePoint;
|
||||||
begin
|
begin
|
||||||
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
||||||
AResults.FIndex := -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;
|
sp := Source[i]^.Point;
|
||||||
if IsNan(sp) then continue;
|
if IsNan(sp) then continue;
|
||||||
// Since axis transformation may be non-linear, the distance should be
|
// Since axis transformation may be non-linear, the distance should be
|
||||||
|
@ -644,19 +644,25 @@ function TDrawFuncHelper.GetNearestPoint(
|
|||||||
const AParams: TNearestPointParams;
|
const AParams: TNearestPointParams;
|
||||||
out AResults: TNearestPointResults): Boolean;
|
out AResults: TNearestPointResults): Boolean;
|
||||||
var
|
var
|
||||||
x, r: Integer;
|
x: Integer;
|
||||||
|
r: TDoubleInterval;
|
||||||
begin
|
begin
|
||||||
AResults.FIndex := -1;
|
AResults.FIndex := -1;
|
||||||
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
AResults.FDist := Sqr(AParams.FRadius) + 1;
|
||||||
FNearestPointParams := @AParams;
|
FNearestPointParams := @AParams;
|
||||||
FNearestPointResults := @AResults;
|
FNearestPointResults := @AResults;
|
||||||
|
|
||||||
x := TPointBoolArr(AParams.FPoint)[FSeries.IsRotated];
|
with AParams do
|
||||||
r := IfThen(FSeries.IsRotated, -1, 1) * AParams.FRadius;
|
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
|
with XRange do
|
||||||
ForEachPoint(
|
ForEachPoint(
|
||||||
Max(FImageToGraph(x - r), FStart),
|
Max(r.FStart, FStart), Min(r.FEnd, FEnd),
|
||||||
Min(FImageToGraph(x + r), FEnd),
|
|
||||||
@CheckForNearestPoint, @CheckForNearestPoint);
|
@CheckForNearestPoint, @CheckForNearestPoint);
|
||||||
|
|
||||||
Result := AResults.FDist < Sqr(AParams.FRadius) + 1;
|
Result := AResults.FDist < Sqr(AParams.FRadius) + 1;
|
||||||
|
@ -1169,6 +1169,7 @@ begin
|
|||||||
p.FDistFunc := DIST_FUNCS[FChart.ReticuleMode];
|
p.FDistFunc := DIST_FUNCS[FChart.ReticuleMode];
|
||||||
p.FPoint := APoint;
|
p.FPoint := APoint;
|
||||||
p.FRadius := Trunc(Sqrt(MaxInt));
|
p.FRadius := Trunc(Sqrt(MaxInt));
|
||||||
|
p.FOptimizeX := false;
|
||||||
for s in CustomSeries(FChart) do
|
for s in CustomSeries(FChart) do
|
||||||
if
|
if
|
||||||
(not (s is TBasicPointSeries) or TBasicPointSeries(s).UseReticule) and
|
(not (s is TBasicPointSeries) or TBasicPointSeries(s).UseReticule) and
|
||||||
@ -1463,6 +1464,7 @@ begin
|
|||||||
p.FDistFunc := DIST_FUNCS[DistanceMode];
|
p.FDistFunc := DIST_FUNCS[DistanceMode];
|
||||||
p.FPoint := APoint;
|
p.FPoint := APoint;
|
||||||
p.FRadius := GrabRadius;
|
p.FRadius := GrabRadius;
|
||||||
|
p.FOptimizeX := DistanceMode <> cdmOnlyY;
|
||||||
best.FDist := MaxInt;
|
best.FDist := MaxInt;
|
||||||
for s in CustomSeries(FChart, FAffectedSeries.AsBooleans(FChart.SeriesCount)) do
|
for s in CustomSeries(FChart, FAffectedSeries.AsBooleans(FChart.SeriesCount)) do
|
||||||
if
|
if
|
||||||
|
Loading…
Reference in New Issue
Block a user