Google Answers Logo
View Question
 
Q: swinging on a rope ( Answered 5 out of 5 stars,   3 Comments )
Question  
Subject: swinging on a rope
Category: Science > Physics
Asked by: mxnmatch-ga
List Price: $7.00
Posted: 15 Sep 2003 15:59 PDT
Expires: 15 Oct 2003 15:59 PDT
Question ID: 257088
I know that the equation for using acceleration and velocity to
determine position is:
  x(t) = a*a*t + v*t + x(0)
I have a computer game where I have a guy that can move around and
jump,
etc. That equation is used to determine realistic movement.

However, I want to add the capability to swing on a rope.
Here are the values I know:
  x,y = where the character is holding the rope
  cX,cY = the center point that the rope is attached to
  r = the length of the rope
  g = the acceleration downward due to gravity
  t = the current time value

I need an equation which I can use to determine the next point to
display the character at. That means that given the values above I
need to know:
  x(t),y(t) = the position of the character at that time
  vx(t),vy(t) = the velocity vector of the character at that time
  ax(t),ay(t) = the acceleration vector of the character at that time
I need to know the velocities and accelerations because if the swing
gets interrupted (i.e. they let go of the rope or swing into a wall)
then I need to know what their acceleration and velocity vectors where
at the time they were interrupted. I also need to be able to start the
swing at any point in the arc. That means I could jump onto the rope
while the rope is hanging straight down, or I could start swinging
while the rope is pulled a ways to the side.

I started with the equation for a half circle:
  x*x + y*y = r*r
and messed around with the acceleration and velocity vectors and came
up with an equation for the acceleration (who knows if it's right):
  Ax(t) = g*x(t) / sqrt( r*r - x(t)*x(t) )
but then I got stuck and wasn't able to figure out the rest.
Answer  
Subject: Re: swinging on a rope
Answered By: hedgie-ga on 16 Sep 2003 02:36 PDT
Rated:5 out of 5 stars
 
hi   mxnmatch-ga,

    For uniformly accelerated motion your equation is 

                  x(t) = .5 *a*t*t + v*t + x(0) 

  For swinging, motion is constrained to an arc,
  so that the only independent coordinate is the angle.

  In both cases, easiest way to display the motion is to use
  the energy conservation equation:

    1/2 * m * v * v +  m * g *h = constant

  m cancels out, of course
 g= 9.81 m / (s * s) is your a in free fall

  In both cases h is height above some level, e.g. above cy.

  For  pendulum  (polar coordinates)

     h or y =      cy - r*sin(alpha(t))
            x=       cx + r*cos(alpha(t))

   where alpha is angle from vertical  

                The energy equation gives you v for every h you pick
                and polar coordinates above give you time t
                (or vice versa).
                from v and t you can get all other quantities,
                 it is just trigonometry then.

 The diagram is shown at
       http://members.aol.com/calgea/l03eqatn.htm  
but you really need not to complicate your life with 
most of that. If you stick to the energy equation above
 and realize that the moment your guy lets go of the rope, the only
acceleration is the gravity g.
The speed vector vx, vy is given by the angle (theta in the drawing)
and magnitude v (same as used above). The state of your guy is just
[position, velocity]. The acceleration is gravity is known. So the
state allows you to continue the motion to any next state, where you
change the 'binding' [on the rope, in free flight].

 Search Terms

 Pendulum, equation

 Please do rate my answer or ask
 if anything is not clear.

hedgie

Request for Answer Clarification by mxnmatch-ga on 17 Sep 2003 11:31 PDT
Ok, so I solved the energy conservation equation for v and got:
  v(t) = sqrt( 2*g*(cY-y(t)) )
but what is y(t)?

You equation you have below allows me to get y(t) if given alpha(t),
but I don't know alpha(t). I know alpha(0) (since that's just the
initial angle from vertical), but I don't know alpha(t).

Of course I still need to know x(t). If I knew x(t) then I could get
y(t) by using the circle equation. You have an equation to give me
x(t) if given alpha(t), but again I don't know how to get alpha(t).

I've been working under the assumption that the initial equation you
gave for uniformly accelerated motion doesn't really apply here
because a pendulum isn't uniformly accelerated in either the x or y
direction.

Request for Answer Clarification by mxnmatch-ga on 17 Sep 2003 21:36 PDT
Ok, so to calculate it using Runge-Kutta I would do:
  A' = f(t,A)
  k1 = f(tn, An)
  k2 = f(tn + h/2, An + (h/2)k1)
  k3 = f(tn + h/2, An + (h/2)k2)
  k4 = f(tn + h, An + h k3) 
  An+1 = An + (h/6)(k1 + 2k2 + 2k3 + k4)

But I'm having trouble translating that further because tn isn't an
independent variable of An.
Would k1 and k2 be:
  A''(t) = -g / L * sin( A(t) )
  k1 = A''( A(tn) )
  k2 = A''( A(tn) + (h/2)*k1 )
or would it be something like:
  A''(t) = -g / L * sin( A(t) )
  k1(tn) = A''( A(tn) )
  k2(tn) = A''( A(tn) + (h/2) * k1(tn+h/2) )

Neither looks at all good to me. The first one drops the time
component completely which obviously can't be right. The second one
requires that I know what A(tn+h/2) is. That's just silly because
A(tn+h) is the value I'm solving for. I don't know what A(tn+h/2) is.

Clarification of Answer by hedgie-ga on 17 Sep 2003 21:46 PDT
mxnmatch
              
You are quite right. 
Swinging is not uniformly accelerated motion.
equation:
 x(t) = .5 *a*t*t + v*t + x(0)
was there to gently correct yours 
 x(t) = a*a*t + v*t + x(0)


Now to the algorithm:

 The 'state' of your guy is  x,v, vx, vy  and mode 

 mode is either 'free' or 'swing' as determined by logic of the game
   --- you keep updating that state in each step 

if mode is same as before, then

step: If mode = free then

x=x + vx*dt
y=y + vy*dt

vy= = vy - g *dt

draw guy at x,y

goto step


if mode = swing



 these x, vx, .. are the state, which you know at each t 
 what happens next, at t+dt ?
 
 Well, we know velocity vx, vy , so we update

update:  

x=x + vx*dt
y=y + vy*dt

draw guy

   now we need new velocities:
   magnitude v from energy equation

  v=sqrt( E- gh/2)
 alfa = arc tg x/y

vx = v * cos alfa
vy = v * sin alfa

 goto step


 If mode just changed from mode to swing
 calculate energy E (that is constant in the energy equation
 I gave yo., You cannot ignore it.
 First, let pick a coordinate system at xc yc
 Let E=0 when pendulum is at equilibrium xe=0 y= - R 
 then energy NOW is

E =y*g + 1/2 * m * v *v    where v= sqrt (vx ^2 + vy^2) , right?

these x, vx, .. are the state, which you know at each t 
 

 That is. Do not mess up cordinate systems:

 We placed center to Cx Cy here for simplicty
  so you need to transform as you jump 
 That should be easy - but feel free to ask
 for clarificarion
 or,
if all is clear, rate the answer please.

comment:
Comment by Shawf is 'All Correct' but is it a clumsy approach to
the algorithm. Energy equation represent Eq. of. Motion already
solved exactly, so you can choose any dt your graphics requires
and not worry about accuracy of the slover. By staying with x,y,
you have directly what your graphics needs.


hedgie

Clarification of Answer by hedgie-ga on 17 Sep 2003 22:00 PDT
errata:

line 
  I gave yo., You cannot ignore it
should be
 I gave you, You cannot ignore it

line
That is. Do not mess up cordinate systems:
should be
That is it. Do not mess up cordinate systems:

   Sorry about that. Nobody's perfect - but then
what do you want? Good grammar or good algorithm?
                  Good spelling or good logic?  :-)

hedgie

Clarification of Answer by hedgie-ga on 17 Sep 2003 22:08 PDT
I assume you can correct yourself 
few tiny typos like:

v=sqrt( E- gh/2)

should be

v=sqrt ( 2* (E - g * y))

and we take mass m=1, h=y

etc

Request for Answer Clarification by mxnmatch-ga on 18 Sep 2003 20:50 PDT
Thanks! We're on the home stretch now. However, I'm still having some
trouble.

vx should start out as a small positive value and then increase until
the center (x=0) and then it should become negative. I think it would
then increase in value until we reach the right limit of the swing at
which point it becomes 0 and then a small negative value again.

However, in the equation you've given, vx never goes negative as far
as I can tell. I made a graph of the following in MuPAD:
  cos(arctan(x/sqrt(50*50-x*x))
where x is in the range [-50,50].

The result is an arc where vx is 0 at -50 and 50 and vx is 1 at x=0.
vx is never negative in that equation.

In case it's not clear, the equation started out as:
  cos(arctan(x/y))
  x*x + y*y = r*r
In this situation I have r=50, so I solved the circle equation for y
and substituted it into the first equation and then graphed it.


On the other hand, the equation for vy seems to show that vy is always
negative.  vy should be 0 when x=0, positive when x>0, and negative
when x<0.
  sin(arctan(sqrt(50*50-y*y)/y)

Of course, in both cases you need to multiple those values by v in
order to get the actual vx and vy. But since v is always positive it
wouldn't affect the signs of the result.

Right now, if I start swinging from the left then it actually looks
like a little jump instead of a swing. If it starts out at x=-25 then
when it reaches x=+25 it goes toward down-right for infinity.

By fiddling things around I found that if I start my swing on the left
side and change
  y=y + vy*dt
to instead be
  y=y - vy*dt
then I am able to swing from left to right (and the radius stays
constant). However, it never stops swinging. It just keeps going
faster and faster until it becomes horizontal at which point it
wiggles up and down across y=0 but stays on  the right side.

Request for Answer Clarification by mxnmatch-ga on 18 Sep 2003 20:51 PDT
Oh wait, I didn't see your correction. I'll try that and get back to you.

Request for Answer Clarification by mxnmatch-ga on 18 Sep 2003 20:55 PDT
Nope. Even after I fixed the equation for v, it still does the same
thing (just faster).

Request for Answer Clarification by mxnmatch-ga on 18 Sep 2003 20:59 PDT
BTW, if I start my swing on the right side it immediately starts
moving further toward the right. Obviously it is supposed to start
moving left.

Clarification of Answer by hedgie-ga on 19 Sep 2003 09:24 PDT
Please do nottake the pseudocode to represent a debuged program.

 It sketches the general idea and usually needs some checking,
 of signs, etc.



 In the meantime, please check things like 

 alfa = arc tg x/y 

may it is   arc ctg x/y  

You need to draw the triangle V, vx. vy etc 

I usually  do details like that during coding and debuging
usually. Not in the  algorithm design stage.

 I have to run right now - and will return to this soon.

hedgie

Clarification of Answer by hedgie-ga on 19 Sep 2003 13:31 PDT
sorry for a delay mxnmatch

        Let's check those signs:  The coordinate system
has center at Cx, Cy,  x axis is positive to the right, y up ...

 Let's say the extreme right position is alpha= -30

(we swing from 250 to 330, 330 = -30,
 as we measure angles from the x axis  OK?)

 x is positive R+cos alpha
 y is R* sin alpha  (which is negative)

 height h= R+y    ,  E= m* g *h  both positive

 v  which you get from E is magnitude, it is positive 

 You look at the triangle formed by tangential velocity vector V

size is v,  vx= v * sin alpha which is negative  vy= v * cos alpha

so x gets smaller, returning to the y-axis
   y gets larger (but being negative, smaller in absolute value)

I do not see a problem here. 

Just be careful not to let the 'remaining energy D=  E- 1/2 * m* v *v
get too small (or even negative). Reverse the motion before that happens.

 Is it working now ?

Clarification of Answer by hedgie-ga on 20 Sep 2003 03:19 PDT
I guess , from your nonresponse, that it is not working.

  So I went to the next step, reducing pseudocode
 to code, and after a bit of debugging I decided 
 to modify it a bit:

The MODE =0  for FREE
         +1   for swinging right
         -1    for swinging left

 we keep a track if the kinetic energy Ekin = E-m*g*h )
 and when it get small (depending on time step, ..)
 we explicitly reverse

              MODE = - MODE

 That way  v= sqrt( 2 * Ekin/m)) is always OK
 (no root of negative number) 

NOW
 v always come out positive - that is property of function sqrt

in reality both + -, both  positive and negative root have 
physical meaning (same energy for swinging Left and Right)
so we use MODE to decide which way we go:

 alfa= alfa +adot * dt * MODE

adot = v/radius -- angular velocity

than we update x and y from the alfa

and so on 

It works. I would post the code, but it is in  tcl
so I will just give you printout:

time     @     x       y               angle(in rd)      Ekin     
sin(alfa)
 wish swing.tcl
 =====   case start
 $== now  @ -3.26821810432 -3.78401247654   angle: 4.0  Ekin 
0.556802495308 -0.756802495308
 ===== -.2  1.40712472795 9.9 5
 4.5  @ -2.0039958604 -4.58082968374   angle: 4.3  Ekin 
0.556802495308 -0.916165936749
 4.6  @ -1.65691857462 -4.71748034835   angle: 4.37461919963  Ekin 
0.716165936749 -0.94349606967
 4.7  @ -1.25224105388 -4.84064999178   angle: 4.45924578746  Ekin 
0.74349606967 -0.968129998357
 4.8  @ -0.830714835702 -4.93050837762   angle: 4.54547200561  Ekin 
0.768129998357 -0.986101675523
 4.9  @ -0.395954719993 -4.98429732858   angle: 4.63311503148  Ekin 
0.786101675523 -0.996859465717
 5.0  @ 0.0469414412798 -4.99977964525   angle: 4.72177740656  Ekin 
0.796859465717 -0.999955929051
 5.1  @ 0.492477277911 -4.97568750333   angle: 4.81104439182  Ekin 
0.799955929051 -0.995137500665
 5.2  @ 0.934942452283 -4.9118105227   angle: 4.90048464725  Ekin 
0.795137500665 -0.98236210454
 5.3  @ 1.36863618696 -4.80903680457   angle: 4.98965513007  Ekin 
0.78236210454 -0.961807360915
 5.4  @ 1.78809664516 -4.66933725357   angle: 5.07810636548  Ekin 
0.761807360915 -0.933867450714
 5.5  @ 2.18831990208 -4.49569305071   angle: 5.16538794205  Ekin 
0.733867450714 -0.899138610141
 5.6  @ 2.56495257356 -4.29197137634   angle: 5.25105400597  Ekin 
0.699138610141 -0.858394275269
 5.7  @ 2.91444456673 -4.06275926772   angle: 5.33466851489  Ekin 
0.658394275269 -0.812551853544
 5.8  @ 3.23415231296 -3.81316913034   angle: 5.41581001323  Ekin 
0.612551853544 -0.762633826068
 5.9  @ 3.52238766844 -3.5486314423   angle: 5.49407570517  Ekin 
0.562633826068 -0.709726288459
 6.0  @ 3.77841272556 -3.27469040908   angle: 5.56908462638  Ekin 
0.509726288459 -0.654938081815
 6.1  @ 4.00238537215 -2.99681686674   angle: 5.64047974445  Ekin 
0.454938081815 -0.599363373348
 6.2  @ 4.19526400185 -2.7202499802   angle: 5.70792884243  Ekin 
0.399363373348 -0.54404999604
 6.3  @ 4.35868196708 -2.44987581519   angle: 5.77112404584  Ekin 
0.34404999604 -0.489975163039
 6.4  @ 4.49480307358 -2.19014733059   angle: 5.82977982101  Ekin 
0.289975163039 -0.438029466119
 6.5  @ 4.6061687443 -1.94504742849   angle: 5.88362916298  Ekin 
0.238029466119 -0.389009485698
 6.6  @ 4.6955456567 -1.71809516206   angle: 5.93241742654  Ekin 
0.189009485698 -0.343619032411
 6.7  @ 4.76577988168 -1.51239615159   angle: 5.97589264772  Ekin 
0.143619032411 -0.302479230319
 6.8  @ 4.81965972035 -1.33074422036   angle: 6.01378974951  Ekin 
0.102479230319 -0.266148844072
 6.8  !!!!! reversal
 6.9  @ 4.72464241832 -1.63638443497   angle: 5.94976499482  Ekin  5
-0.327276886993
 7.0  @ 4.24415261358 -2.64332529074   angle: 5.72615819707  Ekin 
0.127276886993 -0.528665058147
 7.1  @ 4.14716901765 -2.79302508743   angle: 5.69048231068  Ekin 
0.328665058147 -0.558605017486
 7.2  @ 3.98032121237 -3.02606064817   angle: 5.63315299373  Ekin 
0.358605017486 -0.605212129634
 7.3  @ 3.79208329296 -3.25885014987   angle: 5.57326935511  Ekin 
0.405212129634 -0.651770029973
 7.4  @ 3.57709670741 -3.49347665598   angle: 5.50961308051  Ekin 
0.451770029973 -0.698695331196
 7.5  @ 3.33438640242 -3.725837801   angle: 5.44239924042  Ekin 
0.498695331196 -0.7451675602
 7.6  @ 3.0631817068 -3.9518246205   angle: 5.37178087658  Ekin 
0.5451675602 -0.790364924099
 7.7  @ 2.76331600934 -4.16702347396   angle: 5.29794541354  Ekin 
0.590364924099 -0.833404694792
 7.8  @ 2.43530402009 -4.3668403142   angle: 5.2211102052  Ekin 
0.633404694792 -0.87336806284
 7.9  @ 2.08041967751 -4.54663105666   angle: 5.14152347925  Ekin 
0.67336806284 -0.909326211333
 8.0  @ 1.70074570941 -4.70185750868   angle: 5.05946447226  Ekin 
0.709326211333 -0.940371501736
 8.1  @ 1.29918782137 -4.82826169597   angle: 4.97524296602  Ekin 
0.740371501736 -0.965652339195
 8.2  @ 0.879446812004 -4.92204970565   angle: 4.88919812296  Ekin 
0.765652339195 -0.984409941129
 8.3  @ 0.445944552299 -4.98007363965   angle: 4.80169656073  Ekin 
0.784409941129 -0.996014727929
 8.4  @ 0.00370329873796 -4.99999862856   angle: 4.7131296402  Ekin 
0.796014727929 -0.999999725712
 8.5  @ -0.441817996874 -4.980441432   angle: 4.62390998273  Ekin 
0.799999725712 -0.996088286401
 8.6  @ -0.884922336547 -4.92106822329   angle: 4.53446727896  Ekin 
0.796088286401 -0.984213644658
 8.7  @ -1.31989625755 -4.8226417936   angle: 4.44524349926  Ekin 
0.784213644658 -0.964528358719
 8.8  @ -1.74123934567 -4.68701243236   angle: 4.35668766124  Ekin 
0.764528358719 -0.937402486472
 8.9  @ -2.14388522243 -4.51705171025   angle: 4.26925034891  Ekin 
0.737402486472 -0.903410342049
 9.0  @ -2.5233979141 -4.31653367497   angle: 4.18337820637  Ekin 
0.703410342049 -0.863306734993
 9.1  @ -2.87612971072 -4.08997284674   angle: 4.09950864443  Ekin 
0.663306734993 -0.817994569349
 9.2  @ -3.19933037248 -3.84243219429   angle: 4.01806499919  Ekin 
0.617994569349 -0.768486438858
 9.3  @ -3.49120229463 -3.57931649033   angle: 3.93945236857  Ekin 
0.568486438858 -0.715863298066
 9.4  @ -3.75090130957 -3.30616686903   angle: 3.86405432888  Ekin 
0.515863298066 -0.661233373805
 9.5  @ -3.97848748314 -3.0284711236   angle: 3.79223070477  Ekin 
0.461233373805 -0.60569422472
 9.6  @ -4.17483396782 -2.75150165203   angle: 3.72431654028  Ekin 
0.40569422472 -0.550300330407
 9.7  @ -4.3415043298 -2.48018954001   angle: 3.66062240988  Ekin 
0.350300330407 -0.496037908001
 9.8  @ -4.48060964163 -2.21903971107   angle: 3.60143623494  Ekin 
0.296037908001 -0.443807942213
 9.9  @ -4.59465610715 -1.97208905911   angle: 3.5470268692  Ekin 
0.243807942213 -0.394417811822
 10.0  @ -4.68639228094 -1.74290773972   angle: 3.49764995737  Ekin 
0.194417811822 -0.348581547944
 10.1  @ -4.75866227291 -1.53464437978   angle: 3.45355712214  Ekin 
0.148581547944 -0.306928875956
 10.2  @ -4.81426764335 -1.35012112722   angle: 3.41501084502  Ekin 
0.106928875956 -0.270024225444
 10.2  !!!!! reversal
 10.3  @ -4.71574068794 -1.66186334099   angle: 3.48041080709  Ekin  5
-0.332372668198
 10.4  @ -4.22982260274 -2.66619593229   angle: 3.70401760484  Ekin 
0.132372668198 -0.533239186458
 10.5  @ -4.13004039392 -2.81829138745   angle: 3.74040065971  Ekin 
0.333239186458 -0.56365827749
 10.6  @ -3.96056004263 -3.05187878998   angle: 3.79812753269  Ekin 
0.36365827749 -0.610375757997
 10.7  @ -3.76943153815 -3.28502448685   angle: 3.85843161858  Ekin 
0.410375757997 -0.657004897369
 10.8  @ -3.55140310403 -3.51959315727   angle: 3.922492196  Ekin 
0.457004897369 -0.703918631453
 10.9  @ -3.30554031641 -3.75145348053   angle: 3.99009433335  Ekin 
0.503918631453 -0.750290696106
 11.0  @ -3.03113352286 -3.976459426   angle: 4.06108155977  Ekin 
0.550290696106 -0.7952918852
 11.1  @ -2.72808774363 -4.1901715076   angle: 4.13526314078  Ekin 
0.5952918852 -0.838034301519
 11.2  @ -2.39699903275 -4.38798309443   angl

Clarification of Answer by hedgie-ga on 20 Sep 2003 03:21 PDT
erata
 we keep a track if the kinetic energy Ekin = E-m*g*h ) 
 and when it get small

should be
 we keep  track f the kinetic energy Ekin  
 when it gets small, we reverse

Request for Answer Clarification by mxnmatch-ga on 22 Sep 2003 00:04 PDT
I've got it working! Thanks for all your help! I continued with the
previous approach instead of using the alfa= alfa +adot * dt you
mentioned in your most recent message.

However, I was never able to get all the signs working correctly
because there were so many different signs to worry about. (the sign
of h, the sign of the velocity, vx and vy, the sign of alfa, etc. I
was trying to make sure this worked even if I started the swing while
above 0,0 and while having an initial vx and vy (say because I was
jumping and swung the rope to grab something below me).

So, I ended up just taking the absolute value of all the numbers
everywhere. I then just added a sequence of if-then-else statements to
make all the signs work  correctly. It's not pretty, but it solved all
my problems and made the code easier to understand because I don't
need to worry that the wrong sign in one part makes things go really
goofy in another part. Signs were hard to debug because sometimes two
mistakes would cancel each other out if I'm swinging in the lower left
quadrant but then things break when I enter the lower right quadrant.

The only thing that isn't quite right is that if I start swinging from
very near vertical (above 0,0) then it seems to lose a little bit of
total velocity because it swings in between points that are a little
bit to the right and left of the vertical. But it looks good and I
think the problem might just be that I'm putting in the initial
kinetic energy wrongly, but I'll figure that out later on.

I'll close the question in a little bit (I want to keep it open just
in case you have any additional comments). Thanks!

Want to see the final product? Here it is (in Java):

    public void doUpdate(double dt) {
        if(!swinging) {
            swinging = true;
            
            double origVx = 0;
            double origVy = g*dt;
            origV = Math.sqrt(origVx*origVx + origVy*origVy);
            prevV = origV;
            
            double origH = radius + origYOffset;
            origPotentialEnergy = Math.abs( 2*g*origH );
            origKineticEnergy = origV*origV;
            
            if( (origVy < 0) == (origVx < 0)) {
                // going clockwise
                swingingClockwise = true;
            } else {
                // going counterclockwise
                swingingClockwise = false;
            }
            prevKineticEnergy = origKineticEnergy;
        }
        
        
        double h = radius + yOffset;
        
        double curPotentialEnergy = Math.abs(2*g*h);
        double curKineticEnergy = origKineticEnergy +
(origPotentialEnergy - curPotentialEnergy);
        double curV;
        
        assert curKineticEnergy >= 0;
        if(curKineticEnergy < 0)
            throw new
org.g42.exception.RuntimeExceptionCarrier("curKineticEnergy < 0");

        double curKineticEnergyChange = (curKineticEnergy -
prevKineticEnergy);
        if(curKineticEnergyChange < 0) {
            // kinetic energy is decreasing
            if( Math.abs(curKineticEnergy) < 0.0001 ) {
                swingingClockwise = !swingingClockwise;
            }
        }
        
        curV = Math.sqrt( Math.abs(curKineticEnergy) );
        if(curV > maxVelocity*1.10) {
            org.g42.util.logging.Log.stderr().debug("old  
maxVelocity="+ maxVelocity +"   curV="+ curV);
            maxVelocity = curV;
        }
        
        double f;
        f = Math.atan( Math.abs( xOffset / yOffset ) );

        
        double alfa = (Math.PI/2 - f);
        
        vx = Math.abs( curV * Math.cos( alfa - Math.PI/2 ) );
        vy = Math.abs( curV * Math.sin( alfa - Math.PI/2 ) );

        if(xOffset > 0) {
            if(yOffset > 0) {
                // up right
                if(swingingClockwise) {
                    vx = vx;
                    vy = -vy;
                } else {
                    vx = -vx;
                    vy = vy;
                }
            } else if(yOffset < 0) {
                // down right
                if(swingingClockwise) {
                    vx = -vx;
                    vy = -vy;
                } else {
                    vx = vx;
                    vy = vy;
                }
            } else {
                // middle right
                if(swingingClockwise) {
                    vx = 0;
                    vy = -vy;
                } else {
                    vx = 0;
                    vy = vy;
                }
            }
        } else if(xOffset < 0) {
            if(yOffset > 0) {
                // up left
                if(swingingClockwise) {
                    vx = vx;
                    vy = vy;
                } else {
                    vx = -vx;
                    vy = -vy;
                }
            } else if(yOffset < 0) {
                // down left
                if(swingingClockwise) {
                    vx = -vx;
                    vy = vy;
                } else {
                    vx = vx;
                    vy = -vy;
                }
            } else {
                // middle left
                if(swingingClockwise) {
                    vx = 0;
                    vy = vy;
                } else {
                    vx = 0;
                    vy = -vy;
                }
            }
        } else {
            if(yOffset > 0) {
                // up middle
                if(swingingClockwise) {
                    vx = vx;
                    vy = 0;
                } else {
                    vx = -vx;
                    vy = 0;
                }
            } else if(yOffset < 0) {
                // down middle
                if(swingingClockwise) {
                    vx = -vx;
                    vy = 0;
                } else {
                    vx = vx;
                    vy = 0;
                }
            } else {
                // middle middle
                vx = 0;
                vy = 0;
            }
        }
  
        
        yOffset += vy*dt;
        xOffset += vx*dt;

        
        
        //
        // THIS IS A FUDGE THAT ENSURES WE STAY ON THE CORRECT
TRAJECTORY.
        // It's not actually necessary if you only swing a few times,
but if you leave something
        // swinging for minutes or hours or more then this is needed
to keep it on track (unless you up the number of
        // calculations per second much higher in order to keep
greater accuracy. But that's somewhat pointless if
        // this fudge is available. So long as we only want to move
along a circle then this will be fine.
        //
        if(alternate) {
            double xOffsetSign = 1;
            if(xOffset < 0) {
                xOffsetSign = -1;
            } else {
                xOffsetSign = 1;
            }
            xOffset = xOffsetSign * Math.sqrt( Math.abs(radius*radius
- yOffset*yOffset) );
        } else {
            double yOffsetSign = 1;
            if(yOffset < 0) {
                yOffsetSign = -1;
            } else {
                yOffsetSign = 1;
            }
            yOffset = yOffsetSign * Math.sqrt( Math.abs(radius*radius
- xOffset*xOffset) );
        }
        alternate = !alternate;
        
        
        
        
        prevV = curV;
        prevKineticEnergy = curKineticEnergy;
        prevKineticEnergyChange = curKineticEnergyChange;
    }

Clarification of Answer by hedgie-ga on 22 Sep 2003 02:37 PDT
congratulations mxnmatch

  Looks good.  The hack of 'staying on track'
  is not needed if the x,y, is calculated from
  alfa.  The combination of that and the energy
  approach is the most stable method, which
  satisifies constrain and conservation forever,
  for any dt. But - there are many OK ways to
  achieve the same goal.

good luck

hedgie
mxnmatch-ga rated this answer:5 out of 5 stars and gave an additional tip of: $10.00
You kept at it until things worked. Thanks!

Comments  
Subject: Re: swinging on a rope
From: kik-ga on 16 Sep 2003 01:38 PDT
 
Very interesting situation for me, mostly because its been a while
since I thought in terms of laws of physics and their mathematical
expressions. I need to go back to my basics for Simple harmonic
motions and see if I can solve this one. Do you think applying Simple
Harmonic Motions principle's will solve this? May be you have already
tried that. Now, where is my book of physics that I read 11 years
back? Thanks for asking!
Subject: Re: swinging on a rope
From: hfshaw-ga on 17 Sep 2003 15:15 PDT
 
You want the equation of motion of a pendulum.  There are many
websites that give the derivation of this (Google search for [Equation
of motion of pendulum])

In summary, the differential equation that governs the motion of a
mass attached to a rigid (I'm assuming the rope in your case is always
kept taut), fixed length pendulum of length L is:

A'' + g/L*sin(A) = 0

where A (which is understood to be a function of time - A(t)) is the
angular displacement (in radians) of the pendulum from the equilibrium
position (i.e., hanging straight downward), T'' is the second
derivative of A with respect to time (i.e., the angular acceleration),
g is the acceleration due to gravity, and L is the length of the
pendulum (i.e., the distance from the fixed point to the place your
hero is hanging onto the rope).

If you define the origin at the point where the rope is attached, then
x-y coordinates of the guy on the rope are related to L and A by:

x = L*sin(A), y = -L*cos(A)

See (http://www.myphysicslab.com/pendulum1.html)

Unfortunately, this is a nonlinear differential equation that does not
have a simply "closed form" solution.  That is, there is no simple
equation you can write in terms of standard algebraic, trigonometric,
or transcendental functions that will tell you the position of the
pendulum as a function of time.  One has to resort to what are called
"numerical methods" for the solution of the diffential equation. 
There are many approaches for solving differential equations
numerically, and luckily, computers are very good at doing this sort
of thing.  An example of one very commonly used method, known as the
Runge-Kutta method is explained at
http://www.myphysicslab.com/runge_kutta.html

For small deviations of the pendulum from its equilibrium position
(hanging straight down), one can made the approximation that the
sin(A) ~= A.  In this case the differential equation governing the
motion becomes:

A'' + g/L*A = 0

This is called teh "small angle" approximation.  It results in a
*linear* differential equation, and its solution is the well know
equation for simple harmonic motion:

A(t) = A0 * cos(Wt - F)

where W = sqrt(g/L) is the frequency of the pendulum's oscillations,
A0 is the amplitude of the initial angular displacement of the
pendulum, and F is the "phase", or the "time" (relative to t = 0) at
which the pendulum starts its motion.

Unfortunately for your purposes, the small angle approximation is
probably not going to be sufficient because I get the sense that your
hero is swinging vigorously on these ropes!  An example of how the
small angle approximation and the "true" motion (calculatedby
numerical methods) can be see at:
http://www.gmi.edu/~drussell/Demos/Pendulum/Pendula.html
Subject: Re: swinging on a rope
From: askrobin-ga on 25 Sep 2003 14:58 PDT
 
I wish all animators were as serious as you are with getting the
physics right! Animations of flying trajectories in video games are
frequently drawn by eye and as a result are often strikingly
unphysical. Kudos to you for working hard to put the physics in.

Here's a suggestion you might consider. Your modeling approach would
be far easier if you were to treat the rope as a linear spring, with
or without damping and air resistance.

From the game-construction standpoint, a slightly stretchy rope might
be more interesting visually than one that doesn't stretch at all. And
computationally it's a whole lot easier to deal with a pair potential
than with a constraint of the type you have chosen to impose.

If the rope is modeled as a spring with equilibrium length L_0 and
spring constant k, you can simply calculate the force on the mass due
to the spring using Hooke's law, F=-k(L-L_0). I'm assuming the rope
doesn't bend; the rope length L is thus calculated as the distance
between the mass and the anchor point at the top of the rope. This
force must be resolved into x- and y- components and summed with the
gravitational force. Having summed all the forces acting on your mass,
you can then integrate your equations of motion as normal. Once the
mass moves to its next position, recalculate the forces and proceed as
usual.

You get to select L_0, the mass of the swinger m, and the spring
constant k. Ideally k should be adjusted so that the mass only
"bounces" once at the bottom of the swing. (This can be done
analytically or found via trial and error.)

Damping of the spring and air resistance on the swinging mass would
also be relatively easy to implement. The damping force on the spring
is proportional to the rate of change of the spring's length, and
opposite in direction; similarly, the air resistance force is
proportional to the velocity of the swinging mass, and opposite in
direction.

By contrast, if you rely on conservation of energy to determine your
equation of motion then it's not at all easy to include the effects of
any dissipative or frictional forces.

One more advanced suggestion... if you don't mind introducing more
degrees of freedom, you could model the rope as a sequence of small
masses connected by short linear springs. This would allow the rope to
swing realistically like a jointed chain instead of like a rod. If you
allow air resistance to affect the masses along the chain as well as
the swinging mass, you could create a strikingly realistic model.

If you have access to the educational software modeling tool called
"Interactive Physics" you could quickly build such a model and see how
it behaves before you write your own code. It's a very valuable tool
for mechanics modeling and will help you develop intuition about how
to combine elementary mechanical elements (masses, springs, dampers,
actuators, etc.) in clever ways to create realistic models.

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy