Question

I have a rectangle. Its height (RH) is 400. Its width (RW) is 500.

I have circle. Its height (CH) is 10. Its width (CW) is 10. Its starting location (CX1, CY1) is 20, 20.

The circle has moved. Its new location (CX2, CY2) is 30, 35.

Assuming my circle continues to move in a straight line. What is the circle's location when its edge reaches the boundary?

enter image description here

Hopefully you can provide a reusable formula.

Perhaps some C# method with a signature like this?

point GetDest(size itemSize, point itemPos1, point itemPos2, size boundarySize)

I need to calculate what that location WILL be once it arrives - knowing that it is not there yet.

Thank you.

PS: I need this because my application is watching the accelerometer on my Windows Phone. I am calculating the target necessary to animate the motion of the circle inside the rectangle as the user is tilting their device.

Was it helpful?

Solution

The answer is X=270 Y=395

first define the slope V as dy/dx =(y2-y1)/(x2-x1). In your example: (35-20)/(30-20)=1.5

the line equation is y = V * (x-x1) + y1. You are interested in the horizontal locations x at: y= CH/2 OR y= H-CH/2 so (not code, just math)

if (y2-y1)<0:
 x=(CH/2 -y1)/V +x1     10 for your example. OR
if (y2-y1)>0:
 x=(H-CH/2 -y1)/V +x1   270 for your example
else (that is: y2==y1)
 the upper or lower lines were not hit.

if CH/2 <= x <= W-CH/2 the circle did hit the that upper or lower side: since V>0, we use x=270 and that is within CH/2 and W-CH/2. 

So the answer to your question is y=H-CH/2 = 395 , X=270

For the side lines it's similar:

(if (x2-x1)<0)
 y=(CH/2 -x1)*V +y1   
(if (x2-x1)>0)
 y=(W-CH/2 -x1)*V +y1 
else (that is: x2==x1)
 the side lines were not hit.

if CH/2 <= y <= H-CH/2 the circle did hit that side at that y.

be careful with the trivial cases of completely horizontal or vertical movement so that you don't divide by zero. when calculating V or 1/V. Also deal with the case where the circle did not move at all.

Since you now asked, here's metacode which you should easily be able to convert to a real method. It deals with the special cases too. The input is all the variables you listed in your example. I here use just one symbol for the circle size, since it's a circle not an ellipse.

method returning a pair of doubles    getzy(x1,y1,W,H,CH){

  if (y2!=y1){ // test for hitting upper or lower edges
    Vinverse=(x2-x1)/(y2-y1)
    if ((y2-y1)<0){
       xout=(CH/2 -y1)*Vinverse +x1 
       if (CH/2 <= y <= H-CH/2) {
           yout=CH/2
           return xout,yout
       }
     }
    if ((y2-y1)>0){
       xout=(H-CH/2 -y1)*Vinverse +x1 
       if (CH/2 <= y <= H-CH/2) {
           yout=H-CH/2
           return xout,yout
       }
    }
  }     
  // reaching here means upper or lower lines were not hit.
  if (x2!=x1){ // test for hitting upper or lower edges
    V=(y2-y1)/(x2-x1)
    if ((x2-x1)<0){
       yout=(CH/2 -x1)*V +y1 
       if (CH/2 <= x <= W-CH/2) {
           xout=CH/2
           return xout,yout
       }
     }
    if ((x2-x1)>0){
       yout=(H-CH/2 -x1)*V +y1 
       if (CH/2 <= x <= W-CH/2) {
           xout=H-CH/2
           return xout,yout
       }
    }
  }     
  // if you reach here that means the circle does not move...
   deal with using exceptions or some other way.
}

OTHER TIPS

It is 1 radius away from the boundar(y/ies).

It's easy; no calculus required.

Your circle has radius R = CW/2 = CH/2, since the diameter of the circle D = CW = CH.

In order to have the circle touch the vertical edge of the rectangle at a tangent point, you have to move the circle to the right by a distance (W - (CX1 + CW/2))

Likewise, the circle will touch the bottom edge of the rectangle at a tangent point when you move it down by a distance (H - (CY1 + CH/2)).

If you do this in two separate translations (e.g., first to the right by the amount given, then down by the amount given or visa versa), you'll see that the circle will touch both the right hand vertical and the bottom horizontal edges at tangent points.

When the moving circle arrives at a wall (boundary) then it will be tangent at one of four points on the circle, call them N, S, E, and W. You know their initial coordinates.

The points travel in a line with a slope known to you: m=(y2-y1)/(x2-x1); where in your example (x1, y1) - (20,20) and (x2, y2)= (30, 35).

Your problem is to find the trajectory of the first point N, S, E, or W which reaches any wall. The trajectory will be a line with slope m.

You can do this by adding (or subtracting) the direction vector for the line to the point N, S, E, or W, scaled by some t.

For example, N is (20, 15). The direction vector is (x2-x1,y2-y1) = (10, 15). Then (20, 15) + t * (10, 15) will hit the boundary lines at different t's. You can solve for these; for example 20 + t*10 = 0, and 20 + t*10 = 400, etc.

The t that is smallest in magnitude, over all four trajectories, gives you your tangent point.

Not sure its calculus..wouldn't it just be the following:

if y >= 390 then it reached the top edge of the rectangle

if x >= 490 then it reached the right edge of the rectangle

if y <= 0 then it reached the bottom edge of the rectangle

if x <= 0 then it reached the left edge of the rectangle

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top