Let's assume you've developed a hinge joint! =)
Actually there could be several issues.
E.g: when you check for a free space, another circle can already occupy it;
I think that scenario is next:
lets assume that two circles have
r=1; y =0;
circle1.x = 1, circle2.x =4;
checking next step:
circle1.canMoveToX(2) //=> true; coz border will move to x=3 it's empty at the moment;
circle2.canMoveToX(3) // => true; coz border will move to x=2 it's empty at the moment;
and at this step they join.