mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-21 22:59:27 +02:00
TAChart: Fix merging of intervals in TIntervalList, add test case. Issue #35268, part of "patch2" by Marcin Wiazowski
git-svn-id: trunk@60788 -
This commit is contained in:
parent
2c3ac872b4
commit
2e629563b1
@ -715,16 +715,24 @@ begin
|
||||
if not (ioOpenStart in ALimits) then AStart -= FEpsilon;
|
||||
if not (ioOpenEnd in ALimits) then AEnd += FEpsilon;
|
||||
if AStart > AEnd then exit;
|
||||
i := 0;
|
||||
while (i <= High(FIntervals)) and (FIntervals[i].FEnd < AStart) do
|
||||
i += 1;
|
||||
|
||||
// In most cases we will be adding ranges in the ascending order,
|
||||
// so the code here is optimized for this case
|
||||
|
||||
// Find index of the first interval, having its FEnd >= AStart
|
||||
i := High(FIntervals) + 1;
|
||||
while (i > 0) and (FIntervals[i-1].FEnd >= AStart) do
|
||||
i -= 1;
|
||||
if i <= High(FIntervals) then
|
||||
AStart := Min(AStart, FIntervals[i].FStart);
|
||||
|
||||
// Find index of the last interval, having its FStart <= AEnd
|
||||
j := High(FIntervals);
|
||||
while (j >= 0) and (FIntervals[j].FStart > AEnd) do
|
||||
j -= 1;
|
||||
if j >= 0 then
|
||||
AEnd := Max(AEnd, FIntervals[j].FEnd);
|
||||
|
||||
if i < j then begin
|
||||
for k := j + 1 to High(FIntervals) do
|
||||
FIntervals[i + k - j] := FIntervals[j];
|
||||
@ -774,31 +782,24 @@ end;
|
||||
|
||||
function TIntervalList.Intersect(
|
||||
var ALeft, ARight: Double; var AHint: Integer): Boolean;
|
||||
var
|
||||
fi, li: Integer;
|
||||
begin
|
||||
Result := false;
|
||||
if Length(FIntervals) = 0 then exit;
|
||||
if (Length(FIntervals) = 0) or (ALeft > ARight) then exit;
|
||||
|
||||
AHint := EnsureRange(AHint, 0, High(FIntervals));
|
||||
while (AHint > 0) and (FIntervals[AHint].FStart >= ARight) do
|
||||
while (AHint > 0) and (FIntervals[AHint].FStart > ALeft) do
|
||||
Dec(AHint);
|
||||
|
||||
while
|
||||
(AHint <= High(FIntervals)) and (FIntervals[AHint].FStart < ARight)
|
||||
do begin
|
||||
if FIntervals[AHint].FEnd > ALeft then begin
|
||||
if not Result then fi := AHint;
|
||||
li := AHint;
|
||||
Result := true;
|
||||
ALeft := FIntervals[AHint].FStart;
|
||||
ARight := FIntervals[AHint].FEnd;
|
||||
exit(true);
|
||||
end;
|
||||
Inc(AHint);
|
||||
end;
|
||||
|
||||
if Result then begin
|
||||
ALeft := FIntervals[fi].FStart;
|
||||
ARight := FIntervals[li].FEnd;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIntervalList.SetOnChange(AValue: TNotifyEvent);
|
||||
|
@ -151,6 +151,23 @@ begin
|
||||
AssertTrue(FIList.Intersect(l, r, hint));
|
||||
AssertEquals(501.0, l);
|
||||
AssertEquals(502.0, r);
|
||||
FIList.Epsilon := DEFAULT_EPSILON; // don't alter other tests
|
||||
|
||||
FIList.Clear;
|
||||
FIList.AddRange(10.0, 20.0, [ioOpenStart, ioOpenEnd]);
|
||||
FIList.AddRange(30.0, 40.0, [ioOpenStart, ioOpenEnd]);
|
||||
l := 0.0;
|
||||
r := 100.0;
|
||||
hint := 0;
|
||||
AssertTrue(FIList.Intersect(l, r, hint));
|
||||
AssertEquals(10.0, l);
|
||||
AssertEquals(20.0, r);
|
||||
l := 0.0;
|
||||
r := 100.0;
|
||||
hint := 1;
|
||||
AssertTrue(FIList.Intersect(l, r, hint));
|
||||
AssertEquals(10.0, l);
|
||||
AssertEquals(20.0, r);
|
||||
end;
|
||||
|
||||
procedure TIntervalListTest.Merge;
|
||||
|
Loading…
Reference in New Issue
Block a user