First to avoid missunderstand, I'd like to tell you my version of math notation.

DotProduct: Is Sum of all X+Y+Z exponentiated by 2
Magnitude: W^2=X^2+Y^2+Z^2
Normalize: X/magnitude,Y/magnitude,Z/magnitude


So my question is. How to obtain the euler angle from 2 vertex?
Posted on 2012-01-23 06:02:54 by Farabi
I think you are missing the significance of what a dot product between two vectors means?
What you are describing is a dot product of a vector with itself (hence X, Y and Z squared).
But when you have two different vectors, there's more to a dotproduct:
http://mathworld.wolfram.com/DotProduct.html

Which expains why a dotproduct of a vector with itself gives you its magnitude squared: The angle between a vector and itself is always 0, and cos(0) == 1.
Hence it's 1*magnitude*magnitude.
Posted on 2012-01-23 07:04:19 by Scali

I think you are missing the significance of what a dot product between two vectors means?
What you are describing is a dot product of a vector with itself (hence X, Y and Z squared).
But when you have two different vectors, there's more to a dotproduct:
http://mathworld.wolfram.com/DotProduct.html

Which expains why a dotproduct of a vector with itself gives you its magnitude squared: The angle between a vector and itself is always 0, and cos(0) == 1.
Hence it's 1*magnitude*magnitude.


Oh, hell, Now Im regreting why I never go to school more. I found on this website a formula like this,


phi = arctan(y/x)

theta = arccos(z)

psi = alpha - phi

if x = y = 0, then phi = 0 deg. (theta = 0 or 180 deg.)


And it seems to contradict with this,

Vector3 AngleTo(Vector3 from, Vector3 location)
{
    Vector3 angle = new Vector3();
    Vector3 v3 = Vector3.Normalize(location - from);

    angle.X = (float)Math.Asin(v3.Y);
    angle.Y = (float)Math.Atan2((double)-v3.X, (double)-v3.Z);

    return angle;
}


The first use z for theta, and the other is use y. Anyone ever got it to work?
Posted on 2012-01-23 20:09:31 by Farabi
Ah finally I got a new words to describe what I want, I need to know the camera orientation from 2 vertex so I can make the shadow texture.

Anyway, I just understand that euler cause a gimbal lock, where sometime a set of euler could be generated by another set. So I need to use quaternions. So, i I use quaternions, I can convert it back to euler right?
Posted on 2012-01-23 21:01:29 by Farabi
Yes that is correct Scali, I will attempt to explain.
Quaternion can be thought of as scribing an arc on a half of a sphere. Mapping a quaternion to a full sphere shows a small problem:
It has only one singularity, at exactly the polar opposite at 180 degrees regardless of the axis of rotation.

This is still 6 times better than using a rotation matrix, who has six similar polar singularities, without even talking about axis switching.
Posted on 2012-01-24 07:08:54 by Homer
Yes you can convert from quaternion back to a set of euler angles, but the question is, should you ? euler has been dead for 400 years, and there are better options now. Perhaps what you need is to change the way you think, and perhaps the education system in general needs to update the curriculum.
Posted on 2012-01-24 07:10:26 by Homer

Yes you can convert from quaternion back to a set of euler angles, but the question is, should you ?


Yes, that's what I thought.
I suppose you want to have a matrix, as that is what the OpenGL API takes as input in this case, if I'm not mistaken (a texture matrix used as part of the texture generation fixed function stuff).
You can generate a rotation matrix directly from a quaternion (or from many other data for that matter, Euler angles are just one (limited) way).
Posted on 2012-01-24 08:52:52 by Scali
I appologize for my stupidity, yes scali youre right, I was going to find a euler from a vector against it self. It need for me 3 days to translate english to my language and understanding it.

Anyway, is the conclution is, I better forget about euler angles? Since I really need it for my shadow system. I want to make something like GluLookAt.
Posted on 2012-01-24 20:05:34 by Farabi
Here is the c++ code for a LookAt function to directly create a view matrix.
You should not have too much trouble with this code.


void Camera::lookAt(const Vector3 &eye, const Vector3 &target, const Vector3 &up)
{
    m_eye = eye;

    m_zAxis = m_eye - target;
    m_zAxis.Normalize();

    m_viewDir = -m_zAxis;

m_xAxis.CrossProduct(up, m_zAxis);
    m_xAxis.Normalize();

    m_yAxis.CrossProduct(m_zAxis, m_xAxis);
    m_yAxis.Normalize();
    m_xAxis.Normalize();

    m_viewMatrix.m00 = m_xAxis.x;
    m_viewMatrix.m10 = m_xAxis.y;
    m_viewMatrix.m20 = m_xAxis.z;
    m_viewMatrix.m30 = -Vector3::DotProduct(m_xAxis, eye);

    m_viewMatrix.m01 = m_yAxis.x;
    m_viewMatrix.m11= m_yAxis.y;
    m_viewMatrix.m21 = m_yAxis.z;
    m_viewMatrix.m31 = -Vector3::DotProduct(m_yAxis, eye);

    m_viewMatrix.m02 = m_zAxis.x;
    m_viewMatrix.m12 = m_zAxis.y;
    m_viewMatrix.m22 = m_zAxis.z;   
    m_viewMatrix.m32 = -Vector3::DotProduct(m_zAxis, eye);
}

Posted on 2012-01-24 22:34:55 by Homer
It seems the second m_xAxis.Normalize(); is there for no reason.
It's already normalized a few lines up, and it hasn't been changed since.
Posted on 2012-01-25 04:13:52 by Scali
Yeah, its not in my source either, weird, php bug here?
Posted on 2012-01-26 23:36:07 by Homer
Thanks for the nice answer for you two. Im still figuring it out and understanding the original idea.
Posted on 2012-01-31 17:09:03 by Farabi

Here is the c++ code for a LookAt function to directly create a view matrix.
You should not have too much trouble with this code.


void Camera::lookAt(const Vector3 &eye, const Vector3 &target, const Vector3 &up)
{
    m_eye = eye;

    m_zAxis = m_eye - target;
    m_zAxis.Normalize();

    m_viewDir = -m_zAxis;

m_xAxis.CrossProduct(up, m_zAxis);
    m_xAxis.Normalize();

    m_yAxis.CrossProduct(m_zAxis, m_xAxis);
    m_yAxis.Normalize();
    m_xAxis.Normalize();

    m_viewMatrix.m00 = m_xAxis.x;
    m_viewMatrix.m10 = m_xAxis.y;
    m_viewMatrix.m20 = m_xAxis.z;
    m_viewMatrix.m30 = -Vector3::DotProduct(m_xAxis, eye);

    m_viewMatrix.m01 = m_yAxis.x;
    m_viewMatrix.m11= m_yAxis.y;
    m_viewMatrix.m21 = m_yAxis.z;
    m_viewMatrix.m31 = -Vector3::DotProduct(m_yAxis, eye);

    m_viewMatrix.m02 = m_zAxis.x;
    m_viewMatrix.m12 = m_zAxis.y;
    m_viewMatrix.m22 = m_zAxis.z;   
    m_viewMatrix.m32 = -Vector3::DotProduct(m_zAxis, eye);
}



Thanks for the code, can I also have for the euler angle too? I mean, I need to know the camera orientation from only the distance of 2 vertex. Thanks.
Posted on 2012-01-31 17:25:05 by Farabi
Oh, you want a YawPitchRoll version?
The camera View Matrix is just a regular 4x4 transform matrix, here is code to convert a set of euler angles. If this still isn't what you want, try to describe your inputs and I'll tell you if there is a way to do it that I know about.
Please forgive my C++ source here, as I don't want to make it TOO easy, you can do the conversion to ASM yourself I think?


void Matrix4::from_YawPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees)
{
    // Constructs a rotation matrix based on a Euler Transform.
    // I use the popular NASA standard airplane convention of
    // heading-pitch-roll (i.e., RzRxRy).

    headDegrees = Math::degreesToRadians(headDegrees);
    pitchDegrees = Math::degreesToRadians(pitchDegrees);
    rollDegrees = Math::degreesToRadians(rollDegrees);

    float cosH = cosf(headDegrees);
    float cosP = cosf(pitchDegrees);
    float cosR = cosf(rollDegrees);
    float sinH = sinf(headDegrees);
    float sinP = sinf(pitchDegrees);
    float sinR = sinf(rollDegrees);

    m00 = cosR * cosH - sinR * sinP * sinH;
    m01 = sinR * cosH + cosR * sinP * sinH;
    m02 = -cosP * sinH;
    m03 = 0.0f;

    m10 = -sinR * cosP;
    m11 = cosR * cosP;
    m12 = sinP;
    m13 = 0.0f;

    m20 = cosR * sinH + sinR * sinP * cosH;
    m21 = sinR * sinH - cosR * sinP * cosH;
    m22 = cosP * cosH;
    m23 = 0.0f;

    m30 = 0.0f;
    m31 = 0.0f;
    m32 = 0.0f;
    m33 = 1.0f;
}


There you go :)
Posted on 2012-02-01 08:28:48 by Homer
Thanks for your time sir. Unfortunately my lack of english make me unable to describe it as good as it should.

I had 2 vertex. A and B. so the input is the delta of each of the vertex which mean

VDelta=VFrom-VOrigin.

So from the VDelta alone, I want to know the euler angle. I see that the above code is not Im looking for, but I am sorry my lack of matrix made me unable to understand it. Is the above code is what I mean? Thanks, and sorry for my stupidity, 10 years ago on hi-school I hate math  :lol: That is why Im so stupid.
Posted on 2012-02-05 01:52:01 by Farabi
This one is close to what I want


Fld FP4(0.0)
fstp lamp.Position.x
Fld FP4(100.0)
fstp lamp.Position.y
Fld FP4(0.0)
fstp lamp.Position.z
Fld FP4(0.0)
fstp lamp.Rotation.x
Fld FP4(0.0)
fstp lamp.Rotation.y
Fld FP4(0.0)
fstp lamp.Rotation.z
invoke Vec_Normalize,addr lamp,addr lamp

fld lamp.Position.y
invoke FpuArcsin,0,0,129
fstp lamp.Rotation.x
fld lamp.Rotation.x
fstp q
invoke FloatToStr,q,addr buff
invoke fShowText,100,10+15*1,addr buff

fld lamp.Position.x
invoke FpuArccos,0,0,129
fstp lamp.Rotation.y
fld lamp.Rotation.y
fstp q
invoke FloatToStr,q,addr buff
invoke fShowText,100,10+15*2,addr buff

fld lamp.Position.z
invoke FpuArctan,0,0,129
fstp lamp.Rotation.x
fld lamp.Rotation.z
fstp q
invoke FloatToStr,q,addr buff
invoke fShowText,100,10+15*3,addr buff
Posted on 2012-02-05 02:31:55 by Farabi
Finally I found how to retrieve X and Y euler angle. I just need to find out how to retrieve the Z rotation degree.


FPGetDegree proc uses esi edi lpPos:dword,lpRotation:dword
LOCAL signX,signY:dword
LOCAL rslt:VERTEX

;++ = 0-90
;+- = 91-180
;-- = 181=270
;-+ = 271-360

mov esi,lpPos
mov edi,lpRotation
; X = Y,Z
; Y = X,Z
; Z = X,Y
invoke Vec_Normalize,addr rslt,lpPos
fld rslt.y
invoke FpuArcsin,0,0,129
fstp .VERTEX.x
FCMP .VERTEX.x,FP4(0.)
.if !ZERO?
fld .VERTEX.x
FMUL FP4(-1.)
fstp .VERTEX.x
.endif

fld rslt.x
invoke FpuArcsin,0,0,129
fstp .VERTEX.y

; fld rslt.z
; invoke FpuArctan,0,0,129
; fstp .VERTEX.z

ret
FPGetDegree endp
Posted on 2012-02-07 02:51:24 by Farabi
There are 12 possible euler sets, you will need to decide which ordered set you wish to retrieve. After that, you can start looking at solutions for extracting those. Again I am willing to help you but you need to define your query properly!
Posted on 2012-02-08 23:19:25 by Homer

There are 12 possible euler sets, you will need to decide which ordered set you wish to retrieve. After that, you can start looking at solutions for extracting those. Again I am willing to help you but you need to define your query properly!


My Order is Z-Front, Y-Up and X-horizontal

I tried this

FPGetAngles proc uses esi edi lpPos:dword,lpRotation:dword
LOCAL signX,signY:dword
LOCAL rslt:VERTEX
LOCAL q:dword
;++ = 0-90
;+- = 91-180
;-- = 181=270
;-+ = 271-360

mov esi,lpPos
mov edi,lpRotation
; X = Y,Z
; Y = X,Z
; Z = X,Y
invoke Vec_Normalize,addr rslt,lpPos

fld rslt.x
fld rslt.z
fpatan
fstp q
invoke Vec_RadToDeg,q
fstp .VERTEX.x

fld rslt.y
fld rslt.z
fpatan
fstp q
invoke Vec_RadToDeg,q
fstp .VERTEX.y

fld rslt.x
fld rslt.y
fpatan
fstp q
invoke Vec_RadToDeg,q
fstp .VERTEX.z


ret
FPGetAngles endp


But it seems to point into a wrong direction. Z should always be zero.
Posted on 2012-02-22 17:23:49 by Farabi
OK so you have described a Left Handed coordinate system.
This eliminates half of the problems you might have.
What is the Position ? I would expect a Direction, given that you are Normalizing it.
If it was a target position, the vector would be target-source position, normalized.
Posted on 2012-02-23 07:59:04 by Homer