mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 14:09:16 +02:00
TAChart: Correctly calculate TFuncSeries.GetNearestPoint
git-svn-id: trunk@32075 -
This commit is contained in:
parent
dd9ce14656
commit
64c42d5290
@ -273,6 +273,9 @@ type
|
|||||||
ADrawer: IChartDrawer; ASeries: TCustomChartSeries;
|
ADrawer: IChartDrawer; ASeries: TCustomChartSeries;
|
||||||
ADomainExclusions: TIntervalList; ACalc: TTransformFunc; AStep: Integer);
|
ADomainExclusions: TIntervalList; ACalc: TTransformFunc; AStep: Integer);
|
||||||
procedure DrawFunction;
|
procedure DrawFunction;
|
||||||
|
function GetNearestPoint(
|
||||||
|
const AParams: TNearestPointParams;
|
||||||
|
out AResults: TNearestPointResults): Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function DoublePointRotated(AX, AY: Double): TDoublePoint;
|
function DoublePointRotated(AX, AY: Double): TDoublePoint;
|
||||||
@ -355,6 +358,68 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TDrawFuncHelper.GetNearestPoint(
|
||||||
|
const AParams: TNearestPointParams;
|
||||||
|
out AResults: TNearestPointResults): Boolean;
|
||||||
|
|
||||||
|
procedure CheckPoint(AXg, AXa: Double);
|
||||||
|
var
|
||||||
|
inExtent: Boolean;
|
||||||
|
gp: TDoublePoint;
|
||||||
|
ip: TPoint;
|
||||||
|
d: Integer;
|
||||||
|
begin
|
||||||
|
CalcAt(AXg, AXa, gp, inExtent);
|
||||||
|
if not inExtent then exit;
|
||||||
|
ip := FChart.GraphToImage(gp);
|
||||||
|
d := AParams.FDistFunc(AParams.FPoint, ip);
|
||||||
|
if (d >= AResults.FDist) or (d > Sqr(AParams.FRadius)) then exit;
|
||||||
|
AResults.FDist := d;
|
||||||
|
AResults.FImg := ip;
|
||||||
|
AResults.FValue.X := AXa;
|
||||||
|
Result := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
hint: Integer;
|
||||||
|
xg, xa, xg1, xa1, xmax: Double;
|
||||||
|
begin
|
||||||
|
AResults.FIndex := -1;
|
||||||
|
AResults.FDist := MaxInt;
|
||||||
|
Result := false;
|
||||||
|
|
||||||
|
with AParams do
|
||||||
|
if FSeries.IsRotated then begin
|
||||||
|
xg := Max(FExtent.a.Y, FChart.YImageToGraph(FPoint.Y - FRadius));
|
||||||
|
xmax := Min(FExtent.b.Y, FChart.YImageToGraph(FPoint.Y + FRadius));
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
xg := Max(FExtent.a.X, FChart.XImageToGraph(FPoint.X - FRadius));
|
||||||
|
xmax := Min(FExtent.b.X, FChart.XImageToGraph(FPoint.X + FRadius));
|
||||||
|
end;
|
||||||
|
|
||||||
|
hint := 0;
|
||||||
|
xa := FGraphToAxisXr(xg);
|
||||||
|
if FDomainExclusions.Intersect(xa, xa, hint) then
|
||||||
|
xg := FAxisToGraphXr(xa);
|
||||||
|
|
||||||
|
CheckPoint(xg, xa);
|
||||||
|
|
||||||
|
while xg < xmax do begin
|
||||||
|
xg1 := xg + FGraphStep;
|
||||||
|
xa1 := FGraphToAxisXr(xg1);
|
||||||
|
if FDomainExclusions.Intersect(xa, xa1, hint) then begin
|
||||||
|
CheckPoint(FAxisToGraphXr(xa), xa);
|
||||||
|
xg1 := FAxisToGraphXr(xa1);
|
||||||
|
CheckPoint(xg1, xa1);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
CheckPoint(xg1, xa1);
|
||||||
|
xg := xg1;
|
||||||
|
xa := xa1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDrawFuncHelper.LineTo(AXg, AXa: Double);
|
procedure TDrawFuncHelper.LineTo(AXg, AXa: Double);
|
||||||
var
|
var
|
||||||
p, t: TDoublePoint;
|
p, t: TDoublePoint;
|
||||||
@ -492,23 +557,17 @@ end;
|
|||||||
function TFuncSeries.GetNearestPoint(
|
function TFuncSeries.GetNearestPoint(
|
||||||
const AParams: TNearestPointParams;
|
const AParams: TNearestPointParams;
|
||||||
out AResults: TNearestPointResults): Boolean;
|
out AResults: TNearestPointResults): Boolean;
|
||||||
var
|
|
||||||
t: Double;
|
|
||||||
dummy: Integer = 0;
|
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
AResults.FIndex := -1;
|
AResults.FIndex := -1;
|
||||||
if OnCalculate = nil then exit;
|
if not Assigned(OnCalculate) then exit;
|
||||||
// Instead of true nearest point, just calculate the function at the cursor.
|
|
||||||
with GraphToAxis(ParentChart.ImageToGraph(AParams.FPoint)) do begin
|
with TDrawFuncHelper.Create(nil, Self, DomainExclusions, @DoCalculate, Step) do
|
||||||
t := X;
|
try
|
||||||
if DomainExclusions.Intersect(t, t, dummy) then exit;
|
Result := GetNearestPoint(AParams, AResults);
|
||||||
AResults.FValue.X := X;
|
finally
|
||||||
end;
|
Free;
|
||||||
OnCalculate(AResults.FValue.X, AResults.FValue.Y);
|
end;
|
||||||
AResults.FImg := ParentChart.GraphToImage(AxisToGraph(AResults.FValue));
|
|
||||||
AResults.FDist := AParams.FDistFunc(AParams.FPoint, AResults.FImg);
|
|
||||||
Result := AResults.FDist <= Sqr(AParams.FRadius);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFuncSeries.IsEmpty: Boolean;
|
function TFuncSeries.IsEmpty: Boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user