Let's assume you have written an extremely useful library for co-ordinate manipulation, which includes
PointF Add(PointF p0, PointF p1)
PointF Sub(PointF p0, PointF p1)
PointF Multiply(PointF p0, float factor)
PointF Multiply(float factor, PointF p0) float Length(PointF p0)
But you did it overriding the appropriate operators so we can conveniently use them from now on. Maybe you had to create a custom PointF class for that since System.Drawing.PointF may not be capable of being tuned in that way.
P2, seen from P1 has the coordinates
P2 - P1
which itself can be an instance of the super-cool point class you invented above.
Seen from the origin of coordinates instead as from P1, P2 would be
P1 + P2 - P1
Sounds weird, as P1 is added and subtracted, but it will help later on. Because we can look at the problem nearly entirely from P1's perspective. At the very end, we'll have to add P1's co-ordinates again and have a correct result.
So we can say this
PointF P2FromP1 = P2 - P1;
float P2DistP1 = Length(P2FromP1);
PointF NormalInP2Direction = (1 / P2DistP1) * P2FromP1;
PointF XFromP1 = xTargetDistanceFromP1 * NormalInP2Direction;
We now can add P1's coordinates and have our result for X:
PointF X = XFromP1 + P1;
And you're done. Plus you have a spectacular tool at your fingertips for future daddling-around-with-geometry.