You could always use a parametric algorithm to "walk" through all the discrete pixel coordinates that exist in your line segment. The following sample code does this:
-------------------------
package simulation.math;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// top-level public class
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* an instance of this class lets a user "walk" through all the integer (x,y)
* points that comprise a line segment.
*
* @author John Dove
scjp,
scjd 2005
*/
public class ParametricLineStep
{
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// fields
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/**
* the target line whose coordinates must be "walked" through, and
* returned to the user.
*/
private Line m_line;
/**
* the last point that was parsed from the line.
*/
private Point m_lastPointReturned;
/**
* flag indicating if the entire line has been parsed.
*/
private boolean m_lineParsed;
/**
* the percentage to increment the "step percent increment" by, which dictates
* where on the line the parse is currently at.
*/
private double m_stepPercentIncrement;
/**
* dictates where on the line the parse is currently at.
*/
private double m_stepPercent;
/**
* the x-value of the starting point for parametrically parsing the line.
*/
private int m_startPointX;
/**
* the y-value of the starting point for parametrically parsing the line.
*/
private int m_startPointY;
/**
* the remaining x-axis length that the start point will need to grow by,
* in order to completely parse the line.
*/
private int m_remainingLengthX;
/**
* the remaining y-axis length that the start point will need to grow by,
* in order to completely parse the line.
*/
private int m_remainingLengthY;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// methods
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/**
* creates an empty instance that is not parsing a line yet.
*/
public ParametricLineStep()
{
m_line = null;
m_lastPointReturned = new Point();
}
/**
* resets the line parse to the beginning of the line.
*/
public void rewind()
{
m_stepPercent = 0.0;
m_lineParsed = false;
}
/**
* sets the line to parse to the supplied line.
*
* @param line the supplied line to parse.
*/
public void setLine(Line line)
{
// save the line
m_line = line;
rewind();
// determine the line length
double lineLength = 0;
// if the line is parallel to the x-axis
if (m_line.m_p1.m_y == m_line.m_p2.m_y)
{
lineLength = Math.abs(m_line.m_p1.m_x - m_line.m_p2.m_x) + 1;
}
// else if the line is parallel to the y-axis
else if (m_line.m_p1.m_x == m_line.m_p2.m_x)
{
lineLength = Math.abs(m_line.m_p1.m_y - m_line.m_p2.m_y) + 1;
}
// else, if the line is NOT parallel to either axis, we the use pythagorean
// theorem to compute the line length
else
{
// first get the distance in points (i.e. discrete pixels) between the
// x and y ordinates. +1 is used to ensure that we get an accurate point
// count inclusive of the endpoints themselves. For example, 5-2 = 3,
// but between 2 and 5 *inclusive* there are actually 4 points.
int xDifference = Math.abs(m_line.m_p1.m_x-m_line.m_p2.m_x) + 1;
int yDifference = Math.abs(m_line.m_p1.m_y-m_line.m_p2.m_y) + 1;
lineLength = Math.sqrt(xDifference*xDifference + yDifference*yDifference);
}
// determine the step percent increment, which is equal to the "percentage"
// of the line that *half* a pixel is equal to
m_stepPercentIncrement = 0.5/lineLength;
// determine the starting point for parametrically parsing the line
m_startPointX = line.m_p1.m_x;
m_startPointY = line.m_p1.m_y;
// determine the remaining lengths in BOTH the x and y directions
// that the start point will need to grow by, in order to completely
// parse the line. +1 is NOT needed, as we have a startX/YPoint
m_remainingLengthX = line.m_p2.m_x - line.m_p1.m_x;
m_remainingLengthY = line.m_p2.m_y - line.m_p1.m_y;
}
/**
* returns the next point on the line, else null if no more points remain.
* This method will always return the SAME object reference, however, the
* values will be changed to be that of the next point (x,y).
*
* @return the next point on the line, else null if no more points remain.
*/
public Point getNextPoint()
{
// assume no more points exist, so set return value to null
Point returnValue = null;
// if the line has NOT been completely parsed yet
if (!m_lineParsed)
{
// while the next point has not been determined and the step percent is
// less than 1.0; i.e. this check does NOT cover the 1.0 step percent,
// instead, the 1.0 step percent is covered outside the while loop (below)
// as a special case
while(m_stepPercent <= 1.0)
{
// get the next point
int nextPointX = m_startPointX + (int)Math.round(m_stepPercent * m_remainingLengthX);
int nextPointY = m_startPointY + (int)Math.round(m_stepPercent * m_remainingLengthY);
// if this is the FIRST point to be parsed, return it
if (m_stepPercent == 0.0)
{
m_lastPointReturned.m_x = nextPointX;
m_lastPointReturned.m_y = nextPointY;
returnValue = m_lastPointReturned;
break;
}
// else, if this is the 2ND+ point to be parsed, such that it is NOT
// equal to the last point parsed, return it
else if (!m_lastPointReturned.equals(nextPointX,nextPointY))
{
m_lastPointReturned.m_x = nextPointX;
m_lastPointReturned.m_y = nextPointY;
returnValue = m_lastPointReturned;
break;
}
// increment the step percent and try again. If continually repeated,
// this will eventually cause the while loop to exit without ever
// finding a return point
m_stepPercent = m_stepPercent + m_stepPercentIncrement;
}
//----------------------------------------------------------------------
// SPECIAL CASE: step percent >= 1.0
//----------------------------------------------------------------------
// if the while loop (above) exited WITHOUT finding a return Point, it
// means the step percent must be >= 1.0. In this special case, we will
// attempt to return the other endpoint of the line, if and only if it
// has NOT already been returned in a prior call to this method
//----------------------------------------------------------------------
if (returnValue == null)
{
// in any case, the line will be considered fully parsed after this
// code block executes
m_lineParsed = true;
// get the next point
int nextPointX = m_line.m_p2.m_x;
int nextPointY = m_line.m_p2.m_y;
// if this final point differs from the last that was returned from this
// method, use it as the return value
if (!m_lastPointReturned.equals(nextPointX,nextPointY))
{
m_lastPointReturned.m_x = nextPointX;
m_lastPointReturned.m_y = nextPointY;
returnValue = m_lastPointReturned;
}
}
// else, the while loop exited because the next point was FOUND, which also
// means that the step percent is still LESS THAN 1.0. In this case we
// simply increment the step percent for the NEXT call to this method
else
{
m_stepPercent = m_stepPercent + m_stepPercentIncrement;
}
}
// returns the next point on the line, else null if no more points exist
return returnValue;
}
}