make a "train follow a track" kind of pattern

EDIT: Update Although not finnished, I made some progress on this project, and got an account on open processing so I can share sketches without you having to copy paste code, yay.
train example on openprocessing.org left click = pull train, right click = make new road

....

I have an idea, that is a bit hard to explain exactly but I will try..
Evenly distributed points along the outline of a shape is travelling around the shape.
Think of a train moving along a track the same length as the train...
and when a wagon go out of the track the whole train "teleport one wagon-length back" and all wagons add +1 to their wagon number.
You can kind of understand that that if you would only watch a subsection of the whole track that it would create the illusion that the train is much longer than it actually is as the numbers go up and up.
What do you call this kind of behavior so I know what to even search for?

I have a sketch, not for you to review the code, but to show kind of what I mean ,because I can not program exactly what I mean...

horisontal slider example on openprocessing.org

Answers

  • There should be useful information about this concept online. But what do I search for?

  • It has like a slider motion. For example, when you are browsing photos in your smartphone in thumbnail views (or even browsing files), you can flick your finger on the page and it will gives you the illusion that you are sliding to the bottom of the view to access other photos.

    Neat effect.

    Kf

  • edited February 2017

    It has like a slider motion.

    If the track is straight yes, but what if its S-shaped or any arbitrary path? ... I don't know what you would call it then

  • edited February 2017

    woah, found something...
    https://www.openprocessing.org/sketch/204357
    EDIT:
    seems I can't use beizerPoint method since the points "compresses" in the turn and don't stay evenly distributed, still cool though

    float x,y,t;
    void setup(){
     size(600, 400);
     smooth();
    }
    void draw(){
     background(187, 187, 187);
     noFill();
     stroke(80);
     bezier(600, 100, 0, 0, 0, 0, 100, 400);
     t+=0.01; t=t%1;
     for(float i=0.0; i<0.5; i+=0.1){
     x = bezierPoint(600, 0, 0, 100, t-i);
     y = bezierPoint( 100, 0, 0, 400, t-i);
     fill(68,136,170,200);
     stroke(80);
     ellipse(x, y, 20, 20);
     }
    }
    

    and unrelated to processing but same concept
    http://ltunlimited.typepad.com/my_weblog/2008/11/space-points-equally-along-a-path.html
    so "path following" and "path arrays" seems to be relevant terms that I'll read up on

  • edited February 2017

    I have a grasp on how to solve it now.
    Made the sketch draw an even track after the mouse,
    or from a semi-random-beizer-curve when clicking.

    boolean mpa,mr,mpnr,bw;
    float t,x,y,lx,ly,nx,ny,angle;
    float d=20.0;
    //road xtrack = new road(50,50,200,4);
    void setup() {
      size(600,600);
    }
    void draw() {
      if (!mpa && mousePressed){mpnr=true;}else{mpnr=false;}
      if (mpa && !mousePressed){mr=true;}else{mr=false;}
    
      strokeWeight(3);
      t=0;
      x=mouseX; y=mouseY;
      drawnode();
      if (mpnr){
        background(128);
      while(t<1.0){
      t+=0.01; 
      x = bezierPoint(mouseX, 0, 100, 300, t);
      y = bezierPoint( 300, 200, 400, mouseY, t);
      drawnode();
      }
      }
      if (mousePressed) {mpa=true;}else{mpa=false;}
    }
    void drawnode(){
      if(dist(x,y,lx,ly)>=d){
          angle=atan2(x-lx,y-ly);
          if(bw){bw=false;}else{bw=true;}
          stroke(int(bw)*255);
          nx=lx+sin(angle)*d;ny=ly+cos(angle)*d;
          line(lx,ly,nx,ny);
          lx=nx; ly=ny;
      }
    }
    

    I believe I can realize my idea using this method.
    I'll store the generated path as an Array-list of nodes at a fixed distance from each-other.
    Then I can place the "train wagons" on those nodes (or lerp between nodes).
    I am not going to make a train game but I like to think of the concept as a long train and I believe the solution could be useful for many things, including that kind of thing.

    EDIT: no point being no secretive
    I got the idea by designing a phone-friendly ui based on a circular pattern, and thought how people have different size hands, different size phones and different preferences and might not want a circular shape, so I figured the best possible solution would be to have the user draw the shape themself.
    I just realized it would just be confusing for the user and solve a non existent problem. But doing it in a general way that can be used for other purposes "like train tracks" or whatever would be worthwhile.

  • Update,

    I'll store the generated path as an Array-list of nodes at a fixed distance from each-other. Then I can place the "train wagons" on those nodes (or lerp between nodes).

    I tested this with the checkered-line thing and it seems to work, threw away beizers, much easier to make straight lines that looks smooth from a distance.
    This is just 10% finished though, there is so much more that needs to be done to make this useful
    Move mouse to draw path, click to reset path

    boolean mpa,mr,mpnr,bw;
    float t,x,y,lx,ly,nx,ny,nl,angle;
    float d=8.0;
    ArrayList<node> path = new ArrayList<node>();
    void setup() {
      size(600,600);
    }
    void draw() {
      if (!mpa && mousePressed){mpnr=true;}else{mpnr=false;}
      if (mpa && !mousePressed){mr=true;}else{mr=false;}
      strokeWeight(3);
      x=mouseX; y=mouseY;
      background(128);
      if (mpnr){path.clear();}
      go();
      if (mousePressed) {mpa=true;}else{mpa=false;}
    }
    void go() {
        if(dist(x,y,lx,ly)>=d){
          angle=atan2(x-lx,y-ly);
          nx=lx+sin(angle)*d;ny=ly+cos(angle)*d;
          path.add(new node(nx,ny));
          lx=nx; ly=ny;
        }
        if(path.size()>=2){drawpath();}
        }
        void drawpath(){
        node n0,n1,n2;
        nl+=0.05; if(nl>1){nl=0;if(bw){bw=false;}else{bw=true;}}
        for(int i=0;i<int(path.size()-2)/2*2;i++){
          n0=path.get(i); n1=path.get(i+1); n2=path.get(i+2);
          if(bw){bw=false;}else{bw=true;}stroke(int(bw)*255);
          line(lerp(n0.x,n1.x,nl),lerp(n0.y,n1.y,nl),lerp(n1.x,n2.x,nl),lerp(n1.y,n2.y,nl));
        }
      }
    class node{float x,y;node(float X,float Y){x=X;y=Y;}}
    
Sign In or Register to comment.