Roller coaster animation - move TO and angle of edge
-
Hi all,
I am trying to make a model to animate a kind of roller coaster.
Step 1: Select the cart and the path (loose edges) and define which is the cart and what are the edges.
Step 2: Put the edges in order and put them in a array
Step 3: Depending on the time, calculate where the cart should be on the track
Step 4: Move the cart TO the start of the edge it should be
Step 5: Move the cart BY the amount it has already travelled on the edge
Step 6: Rotate the cart TO rotx,y,z = 0
Step 7: Rotate the cart to match rotx, roty and rotz of the edge
My problems start at step 5. I only know how to move by a certain amount, but not how to move to a certain point, whatever the start position was. I thought to do this using a Point3D instead of vector3d object, but this does not work.
The same I have to solve for the rotation.
Then the last question is whether you can get the angles of an edge in an easy way, so without calculating them from the coordinated of start and end point.
Can you guys help me out here?
See below the test code I wrote for the move TO and move BY
model = Sketchup.active_model ents = model.entities face= ents.add_face [0,0,0],[5,0,0],[5,5,0], [0,5,0] face_group = ents.add_group face clock = 0 timer_id = UI.start_timer(0.1, true) { if clock <= 100 vvMoveToPoint = [0,0,0] point = Geom;;Point3d.new vvMoveToPoint t1 = Geom;;Transformation.new point vvMoveByVector = [clock/10,clock/10,0] vector= Geom;;Vector3d.new vvMoveByVector t2 = Geom;;Transformation.new vector t_all = t1 * t2 face_group = face_group.transform! t_all else UI.stop_timer timer_id puts "clock is larger than 5 " + clock.to_s end clock = clock + 1 }
Here I laready tried things like changing the order of t1 and t2...
EDIT: I now also tried to get the coordinates of the group with position, but that doesnt work, I have tried to make a bound for the group and get the position of the bound box, but that doesnt work neither. Maybe I have to save in a variable which tranlations and rotations I have done with the group, but that seems strange.. SU should have some information of where the group is, no??
EDIT 2: I got the thing working, but with the method where I store the performed transformation in variables, to transform it back later. I supose there are better ways to do this, so I am open for suggestions... The challenge I have now is to introduce several carts that travel together, so I will be busy for a while..
model = Sketchup.active_model ents2 = model.entities ents = model.selection # selection in future viNumberOfEdges = ents.count-1 puts "NumberOfEdges" + viNumberOfEdges.to_s cart = ents.find { |ent| ent.typename.to_s == "ComponentInstance"} path = [] path = ents path.remove [cart] vesPath = [] path.each {|item| if item.typename=="Edge" vesPath = vesPath + [item] end } puts "First element of vesPath" + vesPath[4].to_s vesOrderedPath = [] vesOrderedPath = vesOrderedPath + [vesPath[0]] #First element has to be filled, but not used vesOrderedPath = vesOrderedPath + [vesPath[0]] vesPath = vesPath - [vesOrderedPath[1]] i = 1 veLast = vesOrderedPath[1] while i <= viNumberOfEdges vvEnd = veLast.end veNext = vesPath.find {|edge| edge.start == vvEnd || edge.end == vvEnd } vesOrderedPath = vesOrderedPath + [veNext] vesPath = vesPath - [veNext] veLast = veNext i = i + 1 end i = 1 ents2 = model.entities vrsLength = [0] vrsLengthAcc = [0] vrTotalLength = 0.0 vrLength = 0.0 while i <= vesOrderedPath.size-2 vrLength = vesOrderedPath[i].length vrsLength = vrsLength + [vrLength] vrTotalLength = vrTotalLength + vrLength vrsLengthAcc = vrsLengthAcc + [vrTotalLength] i = i + 1 end vrSpeed = 0.1 posCartx = 0.0 posCarty = 0.0 posCartz = 0.0 rotx = 0.0 roty = 0.0 rotz = 0.0 clock = 0.0 timer_id = UI.start_timer(0.5, true) { if clock <= 500 # define vector to get back to origin vvMoveToPoint = [-posCartx ,-posCarty ,-posCartz ] point = Geom;;Point3d.new vvMoveToPoint t0 = Geom;;Transformation.new point # define rotation back trb_x = Geom;;Transformation.rotation [posCartx ,posCarty ,posCartz], [1, 0, 0],-rotx trb_z = Geom;;Transformation.rotation [posCartx ,posCarty ,posCartz], [0, 0, 1],-rotz # define starting point vrDistInLap = clock*vrSpeed%vrTotalLength vrTemp = vrsLengthAcc.find {|acc| acc>vrDistInLap} viEdgeID = vrsLengthAcc.index vrTemp vrTravelledOnOtherEdges = vrsLengthAcc[viEdgeID -1] vrTravelOnEdge = vrDistInLap - vrTravelledOnOtherEdges veCurrentEdge = vesOrderedPath[viEdgeID] px = veCurrentEdge.start.position.x py = veCurrentEdge.start.position.y pz = veCurrentEdge.start.position.z vvMoveToPoint = [px,py,pz] point = Geom;;Point3d.new vvMoveToPoint t1 = Geom;;Transformation.new point # update location posCartx = px posCarty = py posCartz = pz # define vector factor = ( vrTravelOnEdge/ veCurrentEdge.length.to_inch) vx_tot = veCurrentEdge.end.position.x.to_inch - veCurrentEdge.start.position.x.to_inch vy_tot = veCurrentEdge.end.position.y.to_inch - veCurrentEdge.start.position.y.to_inch vz_tot = veCurrentEdge.end.position.z.to_inch - veCurrentEdge.start.position.z.to_inch vx = vx_tot * factor vy = vy_tot * factor vz = vz_tot * factor vvMoveByVector = [vx,vy,vz] vector= Geom;;Vector3d.new vvMoveByVector t2 = Geom;;Transformation.new vector posCartx = posCartx + vx posCarty = posCarty + vy posCartz = posCartz + vz rotx = Math.asin(vz_tot/veCurrentEdge.length.to_inch) tr_x = Geom;;Transformation.rotation [posCartx ,posCarty ,posCartz], [1, 0, 0],rotx rotz = Math.asin(vx_tot/veCurrentEdge.length.to_inch) if vy > 0 rotz = -rotz end tr_z = Geom;;Transformation.rotation [posCartx ,posCarty ,posCartz], [0, 0, 1],rotz t_all = tr_z * tr_x * t2 * t1 * t0 * trb_x * trb_z cart = cart.transform! t_all else UI.stop_timer timer_id puts "clock is larger than 5 " + clock.to_s end clock = clock + 1 }
Code only works when you select one group (block that is centered on the origin) and a loop of edges before executing it
-
My tutorial, Chapter 16 has library code to handle this. You may be able to go straight to Chapter 16 and get your work done. But as TIG points out (reincarnated as the wise old one at the fairytale SketchUCation tavern) that has its drawbacks.
Advertisement