Öhm, sortiert und nur für eine Achse ginge das doch noch VIEL einfacher! Die Fenstergrenzen müssen dafür auch nach gleicher Weise wie die Punkte sortiert sein, und du kommst mit nur einem Durchlauf aus.
Mal so ein Fetzen Pseudocode:
Delphi-Quellcode:
type
TWindow = class;
TEdge = class
public
Value: Float;
IsLeftEdge: Boolean; // im Konstruktor zuweisen, wird noch wichtig :)
Window: TWindow; // im Konstruktor zuweisen, quasi der Parent, also Rückbezug
end;
TWindow = class
public
Left, Right: TEdge;
LeftPointLeft: Float;
LeftPointRight: Float;
RightPointLeft: Float;
RightPointRight: Float;
end;
var
Windows: array of TWindow;
Edges: array of TEdge; // referenzen auf alle Edges aus dem Windows-Array sortiert nach Value
CurrentEdgeIndex: Integer;
begin
for i := 0 to maxPoints do
begin
if Points[i].X > Edges[CurrentEdgeIndex].Value then
begin
if Edges[CurrentEdgeIndex].IsLeftEdge then
begin
Edges[CurrentEdgeIndex].Window.LeftPointLeft := Points[i-1].Value;
Edges[CurrentEdgeIndex].Window.LeftPointRight := Points[i].Value;
end
else
begin
Edges[CurrentEdgeIndex].Window.RightPointLeft := Points[i-1].Value;
Edges[CurrentEdgeIndex].Window.RightPointRight := Points[i].Value;
end;
inc(CurrentEdgeIndex);
end;
end;
end;
Und schwupps stehen im TWindows-Array alle Punkte, die links und rechts der X-Fenstergrenzen liegen, in O(n).
Man könnte natürlich auch die Punkte in die TEdge Instanzen werfen, und sich dieses IsLeftEdge damit sparen:
Delphi-Quellcode:
type
TWindow = class;
TEdge = class
public
Value: Float;
LeftValue, RightValue: Float;
end;
TWindow = class
public
Left, Right: TEdge;
end;
var
Windows: array of TWindow;
Edges: array of TEdge; // referenzen auf alle Edges aus dem Windows-Array sortiert nach Value
CurrentEdgeIndex: Integer;
begin
for i := 0 to maxPoints do
begin
if Points[i].X > Edges[CurrentEdgeIndex].Value then
begin
Edges[CurrentEdgeIndex].LeftValue := Points[i-1].Value;
Edges[CurrentEdgeIndex].RightValue := Points[i].Value;
inc(CurrentEdgeIndex);
end;
end;
end;
Das spart evtl. noch (sehr minimal) Zeit in der Schleife (ein Vergleich und ein paar Dereferenzierungen, uhu), und die Werte stehen ggf. an sinnvollerer Stelle, je nach dem wie du es nachher brauchst.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)