   Funfair ride multiple angles problem
  Hello, as you see I'm new here. I registered because I have and a question and ofcourse help other people on the forums whenever possible.I'm working on a funfair ride simulation which requires more math than I thouht at first.The movement is based on this ride: (see from 1:00 for a clear view)Mine however will have free-swinging vehicles (like http://www.kermisworld.nl/snowjet4.jpg)In a 3d program i made a quick simulation of the movements and the moving parts, this will help alot. http://www.jefrome.nl/01.avi.I loaded the seperate models into a 3d engine and now the position of those models has to be defined by some math.So the situation of the moving parts is this: (see video)Arm01 is the main arm. (the bottom yellow one)-it is positioned at zeropoint-length=400Arm02 is the lifting arm (the red arm that can angle to 55 degrees)-it is attached to the end of Arm01-can angle up to 55 degrees-lenght=600Cross01 is the circular frame where the vehicles are attached to-attached to the end of Arm02-radius = 560Vehicle01 is one of the swinging vehicles (colored cubes in the video)-It is attached to Cross01Until the point of lifting up arm02, things went very well:---//mechanics//arm02 tot arm01Arm02Position.X = Arm01Position.X - (float)(Math.Cos(Arm01RotationY) * 400);Arm02Position.Z = Arm01Position.Z + (float)(Math.Sin(Arm01RotationY) * 400);Arm02Position.Y = Arm01Position.Y + 50;Arm02RotationY = Arm01RotationY;   //move along with arm01Arm02RotationZ = MathHelper.ToRadians(Arm02Angle); //lifting angle//kcross01 tot arm01Cross01Position.X = Arm02Position.X + ((float)(Math.Cos(Arm02RotationY)*600))));Cross01Position.Z = Arm02Position.Z - ((float)(Math.Sin(Arm02RotationY)*600))));Vehicle01RotationY = Cross01RotationY + Arm01RotationY;Vehicle01Position.X = Cross01Position.X - (float)(Math.Cos(Vehicle01RotationY) * 560); Vehicle01Position.Z = Cross01Position.Z + (float)(Math.Sin(Vehicle01RotationY) * 560);--When the ride lifts up(arm02angle increases) things get difficult. For example the Vehicle01 follows a 'horizontal' radius of 560(radius of the cross01). When the Cross01 is under for example 45 degrees, this horizontal radius is smaller, and a 'vertical' radius is added. Maybe hard to explain, but I'm trying. What it comes down to:What combination of formulas do I need to use, to let met Vehicle follow the Cross?Thanks for any help!Jeroen   
  Maybe this is an easier approach which illustrates my problem too:http://www.jefrome.nl/02.jpgThe red box follow the black circle using this code:box_pos.X -= (float)(Math.Cos(rotation_angle) * circle_radius);box_pos.Z += (float)(Math.Sin(rotation_angle) * circle_radius);The grey circles are in fact the black circle under a certain angle.What should my coding be like to let the box follow the circle when it's under an angle?Thanks for your time,Jeroen   ;  This would be a terrible system to have to write out in longhand. As a product of transformations, however, it's not that difficult. Assuming:* a right-handed Z-up coordinate system, * the center-bottom of your ride is at the origin, * a base elevation hinge at a radius b, located by default in the positive X axis, * a hinge angle of φ, * a bottom rotation angle of θ1, and* a top rotation angle of θ2, the transformation from world space to the top gimbal (around which all the cars are spinning at a fixed radius) can be given as G = Rz(θ1)T(b,0,0)Ry(-φ)T(-b,0,0)Rz(θ2). From there, given that cars are at a radius r from the top gimbal, an individual car at base angle θ3 and current swing angle γ will have world transformation G*Rz(θ3)T(r,0,0)Ry(γ).Building up these transformations piece-by-piece is much easier than deriving the equivalent trigonometric equations, and has the additional advantage of having the math done for you by any 3D graphics library out there.[Edited by - Sneftel on August 25, 2009 11:37:53 AM];  if you have a square (centered on the origin) with vertices v1, v2, v3, v4 then you can rotate them about the y axis (y bein g up) like so:Matrix rotation1;rotation1.LoadFromAxisAngle(0, 1, 0, angle);v1 = rotation1 * v1;v2 = rotation1 * v2;v3 = rotation1 * v3;v4 = rotation1 * v4;Now what if you wanted to rotate it 90 degrees about the z axis (so its its side) and still have it keep rotating.First you rotate it as before, then you rotate in 90 degrees about the z axisMatrix rotation2;rotation2.LoadFromAxisAngle(0, 0, 0, 90);finalRotation = rotation2*rotation1;v1 = finalRotation*v1v2 = finalRotation*v2v3 = finalRotation*v3v4 = finalRotation*v4That would rotate about the y axis then rotate onto its side (only work once thoguh).I think that was probably a bit confusing :P. Again, a square lies flat, it spins around its y axis then the entire thing rotates on its z axis[/source]Matrix spin, zAxisRot, final;zAxisRot.CreateFromAxisAngle(0, 0, 1, 45);float spinAngle = 0;loop:spin.LoadFromAxisAngle(0, 1, 0, spinAngle);final = zAxisRot*spin;Apply matrixdraw squarespinAngle+=;[/source]If you coded that you should get a square spinning around at a 45 degree angle.You need to do your rotations as either quaternions or matrices and you need to do a hierachial thing. Base is parent of the armarm is parent of the spinning disc on topspinning disc on top has a local rotation (as if it was flat)arm has a slight rotation (relative to it being flat)Base also has its own rotationWhat are you using to render? Apply Base rotationDraw BaseApply arm rotation (which should multiply by the current transform)Draw ArmApply disc rotation (which should multiply by previous transforms)Draw TopIt should be fairly straight forward once you get some transformations sorted.First I suggest you use a nicer way to represent your rotations (and translations). I'd suggest you make a matrix class. It will make everything so much easier.   ;  Ok I found this idea kinda interesting and had a quick go myself. Nothing fancy but perhaps it'll give you some ideas. Its opengl:http://www.scurvy-sea-dog.com/Fair.wmvclassTransform{public:Transform(){m_Transform.LoadIdentity();}void Update(){m_Transform.LoadFromTransRot(m_Position, m_Rotation);// need tot ranspose the matrix for openglm_Transform.Transpose();}Engine::Vectorm_Position;Engine::Quaternionm_Rotation;Engine::Matrix4x4m_Transform;};class Model{Transformm_Base;Transformm_Arm;Transformm_Top;floatm_ArmAngle;bool Model::Initialise(){m_Base.m_Position.Set(0, 0, 0.25, 1);m_Base.Update();m_Arm.m_Position.Set(0, 0.05f, -1, 1);m_Arm.Update();m_Top.m_Position.Set(0, 0.05f, 1, 1);m_Top.Update();return true;}void Model::Render(){// rotate base positionQuaternion r;r.CreateFromAxisAngle(0, 1, 0, DegToRad(-2));m_Base.m_Position = r*m_Base.m_Position;// rotate baser.CreateFromAxisAngle(0, 1, 0, DegToRad(1));m_Base.m_Rotation = r*m_Base.m_Rotation;m_Base.Update();// move arm up and downstatic float angle = 0;angle+= 0.05f;m_ArmAngle = 0.75f*(sin(angle)+1)*0.5f;m_Arm.m_Rotation.CreateFromAxisAngle(-1, 0, 0, m_ArmAngle);m_Arm.Update();// rotate topr.CreateFromAxisAngle(0, 1, 0, DegToRad(-5.0f));m_Top.m_Rotation = r*m_Top.m_Rotation;m_Top.Update();m_Camera->SetPosition(m_Center);Vector position = m_Camera->GetPosition();Vector target = position + m_Camera->GetView();Vector up = m_Camera->GetUp();glPushMatrix();// scale so near plane doens't clip so easilyglScalef(10, 10, 10);gluLookAt(VectorSplit3(position), VectorSplit3(target), VectorSplit3(up));glColor3f(1, 0, 0);glPushMatrix();glMultMatrixf(m_Base.m_Transform[0]);DrawSquare(2, 2);glColor3f(0, 0, 1);glMultMatrixf(m_Arm.m_Transform[0]);DrawRect(0.2f, 1);glColor3f(0, 1, 0);glMultMatrixf(m_Top.m_Transform[0]);DrawSquare(0.5, 0.5);glPopMatrix();DrawAxis();glPopMatrix();}};void DrawSquare(float x, float y){x /= 2;y /= 2;glBegin(GL_QUADS);glVertex3f(-x, 0, -y);glVertex3f(-x, 0, y);glVertex3f(x, 0, y);glVertex3f(x, 0, -y);glEnd();}void DrawRect(float w, float l){w /= 2;glBegin(GL_QUADS);glVertex3f(-w, 0, 0);glVertex3f(-w, 0, l);glVertex3f(w, 0, l);glVertex3f(w, 0, 0);glEnd();}Obviously is a rushed job :P   ;  Thank you all for your suggestions! I managed to get it work properly now with the matrix translations. I should have thought of this myself before.The only thing left now is the swing of the vehicles. Lot of gravity math is included with that.The angle increases when the disc rotates faster. But when the main arm(arm01) rotates there's some kind of exenter so the vehicles angle changes a bit.Also ofcourse when the disc tilts there should be change, and also when the disc is tilt and the rest of the arms is still. I'm trying to figure out how to implement all these movements in a formula but it's hard.Maybe someone hass a suggestion for this?   