Math Question

Hello,

I have a math question. If anyone could help me it would be appreciated.

Lets say I have a forward, up and right vector and frame 1. At frame 2 the forward vector has changed a little (in any direction). How can I recalculate up and right?

I originally tried

v3Forward = m_pISplineSteps[i+1].v3Position - m_pISplineSteps[i].v3Position;
Normalize(v3Forward, v3Forward);
v3Right = m_pISplineSteps[i].v3Forward;
v3Right.y = 0;
Normalize(m_pISplineSteps[i].v3Right, m_pISplineSteps[i].v3Right);
MatrixRotationAxis(&matRotation, Vector3(0,1,0), oaPI/2.0f);
TransformNormal(m_pISplineSteps[i].v3Right, m_pISplineSteps[i].v3Right, matRotation);
Vec3Cross(v3Up, v3Forward, v3Right);

But of course it does not allow the vector to be flipped upside down, which is what I want if the spline goes in a loop.

Any help?? Thanks in advance
I am not sure I understand what is your goal. Correct me if I am wrong:

1. You are simulating motion in 3D.
2. Your character/spaceship is located at point (x,y,z). The point (x,y,z) doest change, your spaceship rotates around it.
3. His head (or body or whatever) is oriented according to an orthogonal coordinate system located at the point (x,y,z).
4. The orthogonal system itself is given by 3 vectors, f, r and u (for forward, up and right). Each of f,r and u has three coordinates. The vectors are all of unit length and are pairwise perpendicular.
5. You want to perturb the vector f and be able to figure how to change vectors r and u.

Well, perturbing the vector f doesnt uniquely determine what happens to vectors r and u. Imagine for example rotation around the f axis. The vector f doesnt change at all (but the vectors r and u do), and your spaceship is rotating in place. If you want to describe rotation around the point (x,y,z), you need three parameters. One such choice is called "Euler angles" (http://en.wikipedia.org/wiki/Euler_angles ).

The small change in vector f gives you only two parameters - yes, you change all three of its coordinates, but then you normalize, so you lose one "degree of freedom". This is where you lose precisely one parameter - that of the rotation around the f vector.

I would suggest you generate a random small motion of the vector f, and then another random small motion parametrizing the angle of rotation around f.

Until the goal is clear doesn't make sense to try the formulas, but I can try to help with that as well.
Thank you for the reply. I should further explain I do have a starting forward, up, and right vectors, as well as an ending forward, up and right vectors. Imaging a spline loop where the first node is at f 0,0,1 and u = 0,1,0 and r = 1,0,0 then the next spline node is f 0,0,-1 u = 0,-1,0 r = 1,0,0. The third node is a duplicate of the 1st.

Linear interpolation wont work because of varying tensions of the spline.

The camera would move along the spline but stay facing forward. I can get the forward vector from the difference between the current and next spline step positions. But still need to recalculate the right and up vectors. I want the camera to flip on its back as it goes through the loop. At the end of the spline it should end matching node 2's f,r,u vectors.

Does that help explain further?
I do not know what a spline loop is, but I presume that it is some closed curve, which you have in explicit form. Is that correct?

I am going to assume you have the curve in form (x_1(t), x_2(t), x_3(t)). If that is not the case, you can either try to put your curve in this form, or you can ignore completely the rest of my post.

The best way to then form a coordinate system moving along the curve is Frenet frame, http://en.wikipedia.org/wiki/Frenet%E2%80%93Serret_formulas . The precise formulas you need to apply are located in the paragraph "Other expressions of the frame". WARNING: the formulas in the first part of the wikipedia article are valid only if your curve is parametrized with respect to something called "natural parameter", or "curve length parametrization". The formulas under the paragraph "Other expressions of the frame" are valid for an arbitrary parametrization of your curve.

[Edit]: The vectors you want, f, r and u are denoted by T(t),(for tangent), N(t) (for normal) and B(t) (for binormal).
Last edited on
Unfortunately my math skills are not strong enough to implement this from the site's description. Do you know of any c++ implementations I can use?

Thank you.
What is the formula for a spline loop? Could you type it? The only thing I remember about splines is in one variable, not in three (a spline of degree n, starting at point a is, as I have studied it, the function f_a(t):= max(0, (t-a)^n) ).
Not sure what the formula is. Just some cut and paste code for interpolating a bezier spline. When I say a spline loop, I simply mean I have a bezier spline with 3 control points that make a loop (like a roller coaster loop).
Umm, can you then paste that Bezier curve interpolation code? I have seen Bezier curves before (the LaTeX environment uses them for some out-of-the-box graphics), but those were only in two dimensions, and I somehow can't work it in my mind how it should be like in 3D. If you use planar Bezier curves (but located in different planes), then the computation you are asking for is very simple.
Here is the implementation.

for(int i=0; i<iSteps; i++)
{
float fT = (float)i/(float)(m_iSteps-1);
v4Time_Vector.x = fT*fT*fT;
v4Time_Vector.y = fT*fT;
v4Time_Vector.z = fT;
v4Time_Vector.w = 1;
v4Control_Points_X.x = m_v3Position.x;
v4Control_Points_X.y = fTangent_N1_X;
v4Control_Points_X.z = fTangent_N2_X;
v4Control_Points_X.w = v3NextPosition.x;
v4Control_Points_Y.x = m_v3Position.y;
v4Control_Points_Y.y = fTangent_N1_Y;
v4Control_Points_Y.z = fTangent_N2_Y;
v4Control_Points_Y.w = v3NextPosition.y;
v4Control_Points_Z.x = m_v3Position.z;
v4Control_Points_Z.y = fTangent_N1_Z;
v4Control_Points_Z.z = fTangent_N2_Z;
v4Control_Points_Z.w = v3NextPosition.z;
oaMath::Vec4TransformCoord(v4Result, v4Time_Vector, oaSplineManager::GetInstance().GetBezierMatrix());
m_pISplineSteps[i].v3Position.x = oaMath::Vec4Dot(v4Control_Points_X, v4Result);
m_pISplineSteps[i].v3Position.y = oaMath::Vec4Dot(v4Control_Points_Y, v4Result);
m_pISplineSteps[i].v3Position.z = oaMath::Vec4Dot(v4Control_Points_Z, v4Result);
}
Topic archived. No new replies allowed.