Mega Code Archive

 
Categories / Delphi / Algorithm Math
 

Calculate find the points on a line

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;