sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [Logic emerged] Articulation in animation

    Scheduled Pinned Locked Moved Developers' Forum
    10 Posts 2 Posters 671 Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • chrisglasierC Offline
      chrisglasier
      last edited by chrisglasier

      I am trying to figure out how to sequence the train animation so I can offset and rotate each wagon in turn around curves. I am developing it using KineticJS in 2d with the intention of using the same data and functionality via an .rb bridge to make a more dramatic display in Sketchup.

      trainset.png

      If you have Chrome or another fully HTML5 compatible browser you can see on Route_51 all the wagons follow the black loco at the same time. I just cannot figure out yet how to create the stagger. Here is a zoom screenshot to show the situation:

      non articulated.png

      Here is my code for running the straight sections:

      
      function animate(nr,path,incr,train,dirX,dirY){
        var steps,offsetX,offsetY,count,a;
        steps = Math.round(path[nr][2] / incr);
        offsetX = path[nr][2]/steps;
        offsetY = path[nr][3]/steps;
        count = 0;
        stage.onFrame(function(frame){
          layer = train[0].getLayer();
          if(count < steps){
              for(a=0; a<train.length; a+=1){ 
                  incrX = train[a].getX() + offsetX * -dirX;
                  incrY = train[a].getY() - offsetY * -dirY;
                  train[a].setX(incrX);
                  train[a].setY(incrY);
              }
              layer.draw();
              count += 1;
          }
          else{
              stage.stop();
              nr += 1;
              if(path[nr]){
                  animate(nr,path,incr,train,dirX,dirY);
              }
          }
        });
        stage.start();
      }
      
      

      I don't seem to be able to grasp the logic (getting too old).

      Any help appreciated. Thanks.

      With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

      1 Reply Last reply Reply Quote 0
      • Dan RathbunD Offline
        Dan Rathbun
        last edited by

        Don't know the exact logic, but each wagon needs to follow the car in front of it (be it loco or wagon.)

        How about logically, moving the loco, then iterating the train's members ??

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          EDIT: Ok, I know you are already iterating the train...

          .. I mean specifically that you must pass the preceeding car's position, to the next car.

          If you wish to get more "real", each car actually has two pivot points, under the front and rear carriage assembly.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • chrisglasierC Offline
            chrisglasier
            last edited by

            @dan rathbun said:

            Don't know the exact logic, but each wagon needs to follow the car in front of it (be it loco or wagon.)

            How about logically, moving the loco, then iterating the train's members ??

            The straight runs do this - rather in each frame each wagon's x value is properly spaced behind the loco; the Y value is the same. The way I have it when the Y-value needs to be offset to take up the curve it gets applied to all. Here is where I get stuck;

            Each wagon needs its own animation to follow the same path, the stagger being set by its starting position,

            or

            Somehow each wagon needs to know when to apply the Y offset (and rotation)

            With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

            1 Reply Last reply Reply Quote 0
            • chrisglasierC Offline
              chrisglasier
              last edited by

              @dan rathbun said:

              EDIT: Ok, I know you are already iterating the train...

              .. I mean specifically that you must pass the preceeding car's position, to the next car.

              I don't think the relationship is between wagons but between wagon and path.

              @dan rathbun said:

              If you wish to get more "real", each car actually has two pivot points, under the front and rear carriage assembly.

              The wagons are fixed axle coal wagons 6 x 2.5m on plan; the curves are 60m radius. One purpose of the animation is analytical so the calcs have to be real even though the display maybe a bit squiffy due to the radical scaling.

              With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                I thought about this tonight whilst sitting on the porch watching a thunderstorm.

                It seems that a track would need to be an object, with an Array inside it, whose members are vertices, representing the possible positions of cars. The number and distance between vertices would depend upon your chosen resolution.

                This track object would also have a function that returns the next positional vertex for a car. The arguments to this function would be the car's current position, and a velocity. If the train was slow, the next vertex might be returned, or as the speed increases, more and more vertices would be skipped.

                Think of the vertices of the track (looking down from above,) as the plotting of a mathematical function on the XY plane. The rotational direction of each car, would be the derivative of it's position. Now if they are perfect curves, that will likely simplify the math. If you know the center point of the curve, the slope of the car (it's longitudinal axis,) will be perpendicular, to the line between the position and the curve's center point.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • chrisglasierC Offline
                  chrisglasier
                  last edited by

                  As we seem to be thinking in parallel let me set out what I am doing right now to help define options.

                  All the x values of both straights and curves are accumulated as the path array is assembled. When the type is a curve it stores [start,finish,max Y offset] in a curve array. Later the rotIncr (horizontal rotation) will be added.

                  
                  function createPath(){
                  	var cp,t,radian,distX,distY;
                  	cp = config.pass;
                  	path = [];
                  	accX = cp.locoXYR[0];
                  	cp.carray = []
                  	for(a=0; a<cp.tracks.length; a+=1){
                  		rotIncr = null;
                  		t = nset[cp.tracks[a]];
                  		radian = t.Rotation * Math.PI / 180;
                  		distX = Math.cos(radian) * t.Length;
                  		lastAccX = accX;
                  		accX += distX;
                  		distY = 0;
                  //curves
                  		if(t.Category === "Curve"){
                  			switch(t.Direction){
                  				case "Rightup";	x = -1; break;
                  				case "Leftdown"; x = -1; break;
                  				case "Rightdown"; x = 1; break;
                  				case "Leftup"; x = 1; break;
                  			}
                  			distY += t.OffsetY * x;
                  			rotIncr = t.Arc / t.Length * x;
                  			//rotIncr = incr * t.OffsetY / t.Length;
                  			cp.carray.push([Math.round(lastAccX),Math.round(accX),Math.round(distY)]);
                  		}
                  		distY += Math.sin(radian) * t.Length;	
                  		distX = Math.abs(Math.round(distX));
                  		distY = Math.abs(Math.round(distY));
                  		path.push([t.Entry,t.Category,distX,distY,rotIncr]);
                  	}
                  	lert(cp.carray.join("<br>"));
                  	return path;
                  }
                  
                  

                  Now doing ...

                  In the animator ...

                  Each loco/wagon's getX() is compared to the carray. If within any of the array elements start/finish, the Y incr is interpolated, the running Y value updated and the rotIncr applied.

                  Here is the code before doing this:

                  
                  function animate(nr){
                  	var cp,steps,offsetX,offsetY,count,a;
                  	cp = config.pass;
                  	steps = Math.round(cp.path[nr][2] / cp.incr);
                  	offsetX = cp.path[nr][2]/steps;
                  	offsetY = cp.path[nr][3]/steps;
                  	count = 0;
                  	stage = coreKJSStage();
                  	stage.onFrame(function(frame){
                  		if(count < steps){
                  			for(a=0; a<cp.train.length; a+=1){
                  				car = coreKJSShape(cp.train[a]);
                  				incrX = car.getX() + offsetX * -cp.dir[0];
                  				incrY = car.getY() - offsetY * -cp.dir[1];
                  				car.setX(incrX);
                  				car.setY(incrY);
                  			}
                  			KJSLayer("Trains");
                  			count += 1;
                  		}
                  		else{
                  			stage.stop();
                  			nr += 1;
                  			if(cp.path[nr]){
                  				animate(nr);
                  			}
                  		}
                  	});
                  	stage.start();
                  }
                  
                  

                  I understand what you are saying about rotation, speed (increments), zooming and so on, but I just wanted to see first how to offset the cars individually.

                  Interested to hear what you think.

                  Back to the animater!

                  Edit GMT 10.30 + 8: doesn't work! Trying another tack on same basic idea

                  With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

                  1 Reply Last reply Reply Quote 0
                  • chrisglasierC Offline
                    chrisglasier
                    last edited by

                    Another version, which better fits with what you say Dan (maybe), is to interpolate the real starts and finishes of path sections so that the path provides coordinates at fixed increments. The getX() of each car finds the nearest x increment and reads off its Y value.

                    The 14 deg (0.1 radian) arcs (curves) use 51 frames at the current settings. I cannot change the milliseconds, only the increments. Here is a nameset record showing typical data.

                    
                    "10";{
                    		"Entry";"10",
                    		"Label";"T10",
                    		"Class";"Track",
                    		"Category";"Curve",
                    		"Backlink";["Tracks"],
                    		"Keyset";"KS01",
                    		"X";72855,
                    		"Y";159891,
                    		"Radius";60000,
                    		"Rotation";-20,
                    		"Direction";"Leftdown",
                    		"Arc";0.1,
                    		"Length";18818,
                    		"OffsetY";3027
                    	},
                    
                    

                    I am not sure and hungry!

                    With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

                    1 Reply Last reply Reply Quote 0
                    • chrisglasierC Offline
                      chrisglasier
                      last edited by

                      It seems a certain amount of time has to pass before some kind of logic emerges.

                      In this case it was that each loco/wagon needed its own fully incremented path for the starts and optionally finishes to be staggered. Here is a screenshot of the train in motion with the "normal" scale view inset. Room for improvement of course especially with curve coordinates.

                      Articulation.png

                      For the animation click New machines and follow the train link.

                      Thanks Dan for the background inspiration.

                      With TBA interfaces we can analyse what is to be achieved so that IT can help with automation to achieve it.

                      1 Reply Last reply Reply Quote 0
                      • Dan RathbunD Offline
                        Dan Rathbun
                        last edited by

                        NO problem.

                        Chewin' on it helps. Sleeping on it helps. Brainstormin' helps.

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • 1 / 1
                        • First post
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement