ErnieDingo 613 Posted August 6, 2017 (edited) I think my brain is a little fried at the moment and I'm having a hard time expressing some of the maths around angular velocity and calculating a vector in code. I have roll, pitch, yaw and the magnitude of each, I know how far an item is from the centre of rotation. The basics, the further away I am from the centre, the larger the angular velocity vector. So I think that's fine in terms of calculation. I have the position Vector of the point I want to calculate in relation to the centre of rotation. Am I missing anything else I need to do the calculation? If anyone can give me some pointers on approaching this problem. Not solve, happy to walk through it. I'm guessing at the moment, but I assume I should solve vectors for roll pitch and yaw and combine these to create a an unnormalised vector (as the 3 axis in question have a magnitude also) multiplied by magnitude of the distance from the centre. The vector will be obviously in the plane perpendicular to the offset vector? Thanks in advance for you thoughts. Edited August 6, 2017 by ErnieDingo 0 Share this post Link to post Share on other sites
JoeJ 2795 Posted August 6, 2017 (edited) So, you define the orientation of objects by roll, pitch and yaw, so using euler angles. But this alone has no information about angular velocity, similar to like you can't get lienar velocity only from position. But assuming you have orientation for current and next frame (or last and current), you can calculate angvel e.g. like this: mat3x3 curOrn = mat3x3::RollMatrix(cur.roll) * mat3x3::PitchMatrix(cur.pitch) * mat3x3::YawMatrix(cur.yaw); // be sure you use the same order of rotation as anywhere else mat3x3 nextOrn = ... same by using angles from the next frame quaternion q0 = curOrn.ToQaut(); quaternion q1 = nextOrn.ToQaut(); quaternion qDiff = q0.Inversed() * q1; // rotation that rotates q0 to q1 // multiplication order may differ in your math lib! vec3 axis; float angle; qDiff.ToAxisAndAngle(&axis, &angle); vec3 angularVelovity = axis * angle / timestep; // timestep is duration between cur and next Basically we want to get the rotation that rotates beteen the two given orientations, convert it to axis and angle and multiply by timestep. I use quats because they are fine to extract axis and angle. Be warned that calculating angvel directly from eulers is wrong, you always need to work with the final resulting orientation (Euler angles are 3 rotations in specified order). There is even a book out that integrates euler angles, which is total nonsense. (I remember you make a game with ships and tanks, so maybe you made a similar mistake without intention, because the error is small if objects rotate mostly abround up vector.) Edited August 6, 2017 by JoeJ 1 Share this post Link to post Share on other sites
ErnieDingo 613 Posted August 7, 2017 On 06/08/2017 at 1:31 PM, JoeJ said: So, you define the orientation of objects by roll, pitch and yaw, so using euler angles. But this alone has no information about angular velocity, similar to like you can't get lienar velocity only from position. But assuming you have orientation for current and next frame (or last and current), you can calculate angvel e.g. like this: mat3x3 curOrn = mat3x3::RollMatrix(cur.roll) * mat3x3::PitchMatrix(cur.pitch) * mat3x3::YawMatrix(cur.yaw); // be sure you use the same order of rotation as anywhere else mat3x3 nextOrn = ... same by using angles from the next frame quaternion q0 = curOrn.ToQaut(); quaternion q1 = nextOrn.ToQaut(); quaternion qDiff = q0.Inversed() * q1; // rotation that rotates q0 to q1 // multiplication order may differ in your math lib! vec3 axis; float angle; qDiff.ToAxisAndAngle(&axis, &angle); vec3 angularVelovity = axis * angle / timestep; // timestep is duration between cur and next Basically we want to get the rotation that rotates beteen the two given orientations, convert it to axis and angle and multiply by timestep. I use quats because they are fine to extract axis and angle. Be warned that calculating angvel directly from eulers is wrong, you always need to work with the final resulting orientation (Euler angles are 3 rotations in specified order). There is even a book out that integrates euler angles, which is total nonsense. (I remember you make a game with ships and tanks, so maybe you made a similar mistake without intention, because the error is small if objects rotate mostly abround up vector.) Cheers. It occurred to me reading through the code that is similar to what I'm doing for rotating my model. As you mentioned, the order is also crucial. Im doing this for my spinning out of control plane so the order im using is: Roll pitch yaw It occurred to me in your suggestion to retain the previous position from the last frame, create a delta and divide by the time delta which will give me the best approximate angular velocity. That added to the velocity of the plane should give me am ejection vector of the fragment breaking off. I need to then just simulate air resistance and gravity. Thanks for helping me through this. 0 Share this post Link to post Share on other sites
JoeJ 2795 Posted August 7, 2017 9 minutes ago, ErnieDingo said: It occurred to me in your suggestion to retain the previous position from the last frame, create a delta and divide by the time delta which will give me the best approximate angular velocity. That added to the velocity of the plane should give me am ejection vector of the fragment breaking off. You could handle this case more accurate: Think of a spinning wheel with a stone glued to it. If the glue breaks, the stone would fly away in a straight line perpendiculr to the axle, and the stone would NOT spin. (Thats physics but it might look better to keep a bit of spin and/or add some small random spin, which is not unrealisic and would depend on how exactly the glue breaks.) So to get the ejection vector, you would calculate the linear velocity of the stone before the break: vec3 stoneLinvel = wheelLinvel + wheelAngvel.Cross (stoneCOM - wheelCOM); // wheelCOM == axle position This assumes the wheel has infinite mass and the stone has zero mass, which might be what you want. (if both parts have similar mass the exact COM would not be in the center of the wheel but somehere between wheel and stone, and you would use above formula to change velocity of both bodies). 0 Share this post Link to post Share on other sites
ErnieDingo 613 Posted August 8, 2017 3 hours ago, JoeJ said: You could handle this case more accurate: Think of a spinning wheel with a stone glued to it. If the glue breaks, the stone would fly away in a straight line perpendiculr to the axle, and the stone would NOT spin. (Thats physics but it might look better to keep a bit of spin and/or add some small random spin, which is not unrealisic and would depend on how exactly the glue breaks.) So to get the ejection vector, you would calculate the linear velocity of the stone before the break: vec3 stoneLinvel = wheelLinvel + wheelAngvel.Cross (stoneCOM - wheelCOM); // wheelCOM == axle position This assumes the wheel has infinite mass and the stone has zero mass, which might be what you want. (if both parts have similar mass the exact COM would not be in the center of the wheel but somehere between wheel and stone, and you would use above formula to change velocity of both bodies). This is is effectively what im going to do. Will have to make the assumptions on mass although I have some volume calculations I can add to improve the simulation. I should leverage physics APIs if I really want to simulate this correctly, but I don't think for such a small part of the game its an investment that is really worthwhile. I feel a bunch of rough approximate simulations will do. I have a good estimation of the centre of mass as each component (ala fragment) due to bounding boxes (that will do). Cheers. 0 Share this post Link to post Share on other sites
ErnieDingo 613 Posted August 9, 2017 @joej - thanks for the help, i an effective mechanism for ejection working now. Really happy with the result. 1 Share this post Link to post Share on other sites