I'm assuming that you already have sorting capability in your code, and am not going to attempt to explain how to sort here. The RTL provides TArray.Sort<T> for this purpose.
Instead of sorting the values, sort indices. Add a level of indirection.
- Create an array of integer,
Indices, containing the indices 0, 1, ..., N-1.
- Sort this array of integers.
- When comparing two values L and R from the array of indices, instead of comparing L and R, compare
X[L] and X[R].
So, to expand on the final point, a standard compare function when sorting integers looks like this:
function Compare(L, R: Integer): Integer;
begin
if L<R then
Result := -1
else if L>R then
Result := 1
else
Result := 0;
end;
But instead, you apply indirection at this point:
function Compare(L, R: Integer): Integer;
begin
if X[L]<X[R] then
Result := -1
else if X[L]>X[R] then
Result := 1
else
Result := 0;
end;
At the end of this process you have indices that tell you the order of the points. The ith point is:
X[Indices[i]], Y[Indices[i]]
This technique is known as indirect sorting.
The problem that you present does suggest though that you may not have defined your data structures correctly. Instead of two distinct arrays, one containing the X coordinates, and one containing the Y coordinates, it would seem more appropriate to store a single array of points:
type
TPoint = record
X: Real;
Y: Real;
end;
var
Points: array of TPoint;
Now you can sort Points by ordering on the X values, but exchanging entire points. When you represent the data this way, there is no possibility for the coordinates to get jumbled up. And X coordinate can never get separated from its matching Y coordinate.
type TRealPoint=Record x:Double; y:Double; End; aArray=Array of TRealPoint;