We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Question about Acceleration/Friction/Inertia...
Page Index Toggle Pages: 1
Question about Acceleration/Friction/Inertia... (Read 899 times)
Question about Acceleration/Friction/Inertia...
Mar 17th, 2010, 9:12am
 
Hi,

I am working on a simple text reader that loads some long text and enables the user to scroll up or down (just like Acrobat reader for example), it should also enable zooming.

The problem with Acrobat reader (as well as most other eBook readers) is that their scrolling method is really ugly. It is not smooth like the iPhone ( it doesn't have acceleration/friction scrolling [inertial scrolling]).

So here is the idea behind my project:
When the user holds the "DOWN" button, the text starts scrolling downwards with an increasing acceleration until it reaches a max value and keeps scrolling as long as the user is still holding the "DOWN" button. Once the user releases the "DOWN" button, I want it to keep scrolling but it should be resisted by FRICTION until it stops. It's pretty similar to iPhone's scrolling, except it uses regular keyboard buttons, not mouse or fingers. I want the "UP" key to do the same thing, but upwards.
I am also planning to add a zooming function that enables the user to zoom in/out very smoothly (with acceleration and friction).

MY PROBLEM:
I spent several hours trying to find a proper way to scroll. I managed to get some acceleration, but it is not smooth at all. I also got good smooth friction but it behaves in a weird way once the user releases the button. I guess this is because the keyPressed() and keyReleased() functions are pretty weird for me [I used to code similar stuff in ActionScript, which seems to handle things differently]

I tried searching alot in Google and OpenProcessing examples, but found nothing similar to my problem Sad

Please help!
Thanks alot,
Re: Question about Acceleration/Friction/Inertia...
Reply #1 - Mar 17th, 2010, 9:42am
 
Quote:
boolean upPressed;
boolean downPressed;
float pos;
float ver;
float acc;

void setup(){
 size(200,600);
 noStroke();
 pos = height/2.0;
 ver = 0;
}

void draw(){
 background(255);
 acc = 0;
 if( upPressed ){
   acc+=0.1;
 }
 if( downPressed ){
   acc-=0.1;
 }
 ver+=acc;
 if( !upPressed && !downPressed ){ ver*=.95; }
 pos+=ver;
 pos = constrain(pos,0,height);
 fill(0);
 rect(0,pos-4,width,2);
 rect(0,pos,width,2);
 rect(0,pos+4,width,2);
}

void keyPressed(){
  if( key == CODED ){
    if( keyCode == UP ){ upPressed = true; }
    if( keyCode == DOWN ){ downPressed = true; }
  }
}
void keyReleased(){
  if( key == CODED ){
    if( keyCode == UP ){ upPressed = false; }
    if( keyCode == DOWN ){ downPressed = false; }
  }
}



Grin

EDIT: Added some friction. This doesn't limit the velocity at all, but you can add that with a call to constrain, much like the one being done for position.
Re: Question about Acceleration/Friction/Inertia...
Reply #2 - Mar 17th, 2010, 9:56am
 
It depends a lot on what kind of dynamics you want, i.e., how you want it to "feel".

The following is a simple example of "viscous" friction -- friction proportional to the current scrolling speed.  Acceleration provided by the user is constant, and the limit on scrolling speed is when the friction matches the user-provided acceleration.

The nice thing about it is that it doesn't require you to track any boolean states or anything.  The bad side of it is that acceleration is sharp when the users first hits a key and then tapers off, which is the opposite of what you usually want in a scrolling UI, but you can twiddle that by adjusting how acceleration is applied.
Code:

float scrollSpeed = 0;
float scrollAccel = 10;
float scrollViscosity = 0.1;

void draw() {

 scrollSpeed -= scrollViscosity*scrollSpeed;
if (abs(scrollSpeed) < 5) scrollSpeed = 0;

 if (keyPressed) {
   if (key==CODED && keyCode==DOWN) {
scrollSpeed += scrollAccel;
   }
   else if (key==CODED && keyCode==UP) {
scrollSpeed -= scrollAccel;
   }
 }
}
Re: Question about Acceleration/Friction/Inertia...
Reply #3 - Mar 18th, 2010, 5:26am
 
@TfGuy44: Very nice piece of example-code. I'd vote to include that into the "examples" of the package.
Re: Question about Acceleration/Friction/Inertia...
Reply #4 - Mar 18th, 2010, 8:52am
 
TfGuy44's code worked really well!

But I did a slight modification (I think it is quite important):
When I release the button, friction works really well, but I noticed that the lines lag while slowing down just before completely stopping [scrolling becomes non smooth just before stopping], and this would have an unpleasant effect when scrolling readable text.

So I added one line of code that eliminates this problem:
Code:
 if( !upPressed && !downPressed )
{
  if (abs(ver) < 0.22) ver = 0; // <---- This is the modification
  ver*=.95;  
}


I actually got the idea from Smitty's code [Thanks by the way :) ]

the value 0.22 seems good to me in this case.

Now, here is the text scrolling code I have now:

Code:
boolean upPressed;
boolean downPressed;
float pos;
float ver;
float acc;
PFont font;
String s = "The quick brown fox jumped over the lazy dog.";


void setup(){
size(600,600);
pos = height/2.0;
ver = 0;

font = loadFont("Consolas-48.vlw");
textFont(font);
}

void draw(){
background(100);
acc = 0;
if( upPressed ){
  acc+=0.1;
}
if( downPressed ){
  acc-=0.1;
}
ver+=acc;
if( !upPressed && !downPressed )
{
  if (abs(ver) < 0.22) ver = 0;
  ver*=.95;  
}
pos+=ver;
pos = constrain(pos,0,height);

text(s, 20, pos, 500, 500);
}

void keyPressed(){
 if( key == CODED ){
   if( keyCode == UP ){ upPressed = true; }
   if( keyCode == DOWN ){ downPressed = true; }
 }
}
void keyReleased(){
 if( key == CODED ){
   if( keyCode == UP ){ upPressed = false; }
   if( keyCode == DOWN ){ downPressed = false; }
 }
}

I guess I now have to modify the scrolling boundaries because the current ones won't work on long texts.

Thank you all!


Page Index Toggle Pages: 1