2010-05-09

how to: new point on a line

If people ever asked me questions, they would probably never ask me, "hey, if I've got a point on a line, how do I find a new point that's d distance away?"


Maybe you're not asking because you're smarter than me, and already know how. Or maybe you're not asking because up until now you just didn't realize how crazy fun it is to find new points on a line.

When I realized how fun it is, I went looking for a solution but couldn't find one, probably because it's a simple problem that is immediately obvious to most everyone but me. I ended up reversing the distance formula, but I'd love to know any simpler solutions.

Here's the C++ code.

(Note: the pre tag in Blogger seems buggy, sometimes preserving whitespace, sometimes not)


#define SQR(a)   ((a)*(a))

// Given a line in point slope form, find a new point
// that's distance away.
void new_pt_on_line( const float x,
const float y,
const float  m,
const float dist,
float* newX,
float* newY)
{
if (m == 0) {
        *newX = x + dist;
        *newY = y;
        return;
} else if (isinf(m)) {
        *newX = x;
        *newY = y + dist;
        return;
}

/* This is basically the reverse of the distance formula
*   dist = sqrt(SQR(x2 - x1) + SQR(y2 - 1))
* It works by taking the final result -- the requested new distance,
* and deconstructing it into the xPart (SQR(x2 - x1) and the yPart,
* the sqrt of which can be added to the x and y values.
*
* The only trick is finding the xPart, which is just solved via
* the equation x + (x + (slope * slope)) = newDistance.
*/
const float  xPart = (SQR(dist) * (1 / SQR(m))) / ( (1 / SQR(m)) + 1);
const float  yPart = xPart * SQR(m);

if (m < 0) {
        if (dist < 0) {
            *newX = x + sqrt(xPart);
            *newY = y - sqrt(yPart);
        } else {
            *newX = x - sqrt(xPart);
            *newY = y + sqrt(yPart);
            }
    } else {
        if (dist < 0) {
            *newX = x - sqrt(xPart);
            *newY = y - sqrt(yPart);
        } else {
            *newX = x + sqrt(xPart);
            *newY = y + sqrt(yPart);
        }
    }
}

No comments:

Post a Comment