Title: Calculate / find the points on a line.
This function will return the list of points found on a line from (x1,y1) to (x2,y2).
The procedure will calculate the points in the direction the line is drawn. For the line (x1,y1)--------(x2,y2) or the line (x2,y2)-------(x1,y1) the first point in the list is always (x1,y1) and the last point in the list is always (x2, y2).
Points are calculated along the axis with the most change so that as many points as possible are created for the line.
// The point object
TPointFill = class
X : Integer;
Y : Integer;
end;
// ----------------------------------------------------------------------------
// GetLinePoints
// ----------------------------------------------------------------------------
function GetLinePoints(X1, Y1, X2, Y2 : Integer) : TList;
var
ChangeInX, ChangeInY, i, MinX, MinY, MaxX, MaxY, LineLength : Integer;
ChangingX : Boolean;
Point : TPointFill;
ReturnList, ReversedList : TList;
begin
ReturnList := TList.Create;
ReversedList := TList.Create;
// Get the change in the X axis and the Max & Min X values
if X1 X2 then
begin
ChangeInX := X1 - X2;
MaxX := X1;
MinX := X2;
end
else
begin
ChangeInX := X2 - X1;
MaxX := X2;
MinX := X1;
end;
// Get the change in the Y axis and the Max & Min Y values
if Y1 Y2 then
begin
ChangeInY := Y1 - Y2;
MaxY := Y1;
MinY := Y2;
end
else
begin
ChangeInY := Y2 - Y1;
MaxY := Y2;
MinY := Y1;
end;
// Find out which axis has the greatest change
if ChangeInX ChangeInY then
begin
LineLength := ChangeInX;
ChangingX := True;
end
else
begin
LineLength := ChangeInY;
ChangingX := false;
end;
// If the x's match then the line changes only on the Y axis
if X1 = X2 then
begin
// Loop thru the points on the list, lowest to highest.
for i := MinY to MaxY do
begin
Point := TPointFill.Create;
Point.X := X1;
Point.Y := i;
ReturnList.Add(Point);
end;
// If the point was started on the right and went to the left then reverse the list.
if Y1 Y2 then
begin
ReversedList := ReversePointOrder(ReturnList);
ReturnList := ReversedList;
end;
end
// If the x's match then the line changes only on the Y axis
else if Y1 = Y2 then
begin
// Loop thru the points on the list, lowest to highest.
for i := MinX to MaxX do
begin
Point := TPointFill.Create;
Point.X := i;
Point.Y := Y1;
ReturnList.Add(Point);
end;
// If the point was started on the bottom and went to the top then reverse the list.
if X1 X2 then
begin
ReversedList := ReversePointOrder(ReturnList);
ReturnList := ReversedList;
end;
end
// The line is on an angle
else
begin
// Add the first point to the list.
Point := TPointFill.Create;
Point.X := X1;
Point.Y := Y1;
ReturnList.Add(Point);
// Loop thru the longest axis
for i := 1 to (LineLength - 1) do
begin
Point := TPointFill.Create;
// If we are moving on the x axis then get the related Y point.
if ChangingX then
begin
Point.y := Round((ChangeInY * i)/ChangeInX);
Point.x := i;
end
// otherwise we are moving on the y axis so get the related X point.
else
begin
Point.y := i;
Point.x := Round((ChangeInX * i)/ChangeInY);
end;
// if y1 is smaller than y2 then we are moving in a Top to Bottom direction.
// we need to add y1 to get the next y value.
if Y1
Point.y := Point.Y + Y1
// otherwise we are moving in a Bottom to Top direction.
// we need to subtract y1 to get the next y value.
else
Point.Y := Y1 - Point.Y;
// if X1 is smaller than X2 then we are moving in a Left to Right direction
// we need to add x1 to get the next x value
if X1
Point.X := Point.X + X1
// otherwise we are moving in a Right to Left direction
// we need to subtract x1 to get the next x value.
else
Point.X := X1 - Point.X;
ReturnList.Add(Point);
end;
// Add the second point to the list.
Point := TPointFill.Create;
Point.X := X2;
Point.Y := Y2;
ReturnList.Add(Point);
end;
Result := ReturnList;
end;
// ----------------------------------------------------------------------------
// ReversePointOrder
// ----------------------------------------------------------------------------
function ReversePointOrder(LinePointList : TList) : TList;
var
i : integer;
NewPointList : TList;
CurrentPointFill : TPointFill;
begin
NewPointList := TList.Create;
i := LinePointList.Count -1;
While i -1 do
begin
CurrentPointFill := TPointFill(LinePointList.Items);
NewPointList.Add(CurrentPointFill);
dec(i);
end;
Result := NewPointList;
end;