ورود

View Full Version : گرفتن چرخش از ماتریس



UfnCod3r
پنج شنبه 02 خرداد 1392, 10:48 صبح
سلام من می خوام چرخش رو ب صورت Quaternion, EulerAngle بگیرم .
هر کدی تاحالا پیدا کردم همش مشکل داره . :گریه:
مثلا این نمی دونم چشه .

void XMat4x4::getRotationQuat(XQuat& outRotation) const
{
// This is simply the length of each axis (row/column) in the matrix.
XVec3 xaxis(m[0], m[1], m[2]);
float scaleX = xaxis.length();

XVec3 yaxis(m[4], m[5], m[6]);
float scaleY = yaxis.length();

XVec3 zaxis(m[8], m[9], m[10]);
float scaleZ = zaxis.length();

// Determine if we have a negative scale (true if determinant is less than zero).
// In this case, we simply negate a single axis of the scale.
float det = determinant();
if (det < 0.0f)
scaleZ = -scaleZ;


// Scale too close to zero, can't decompose rotation.
if (scaleX < 0.000001f || scaleY < 0.000001f || fabs(scaleZ) < 0.000001f)
{
outRotation.setIdentity(); //return false;
return;
}

flt rn;

// Factor the scale out of the matrix axes.
rn = 1.0 / scaleX;
xaxis.x *= rn;
xaxis.y *= rn;
xaxis.z *= rn;

rn = 1.0 / scaleY;
yaxis.x *= rn;
yaxis.y *= rn;
yaxis.z *= rn;

rn = 1.0 / scaleZ;
zaxis.x *= rn;
zaxis.y *= rn;
zaxis.z *= rn;

// Now calculate the rotation from the resulting matrix (axes).
float trace = xaxis.x + yaxis.y + zaxis.z + 1.0f;

if (trace > 0.000001f)
{
float s = 0.5f / XSqrt(trace);
outRotation.w = 0.25f / s;
outRotation.x = (yaxis.z - zaxis.y) * s;
outRotation.y = (zaxis.x - xaxis.z) * s;
outRotation.z = (xaxis.y - yaxis.x) * s;
}
else
{
// Note: since xaxis, yaxis, and zaxis are normalized,
// we will never divide by zero in the code below.
if (xaxis.x > yaxis.y && xaxis.x > zaxis.z)
{
float s = 0.5f / XSqrt(1.0f + xaxis.x - yaxis.y - zaxis.z);
outRotation.w = (yaxis.z - zaxis.y) * s;
outRotation.x = 0.25f / s;
outRotation.y = (yaxis.x + xaxis.y) * s;
outRotation.z = (zaxis.x + xaxis.z) * s;
}
else if (yaxis.y > zaxis.z)
{
float s = 0.5f / XSqrt(1.0f + yaxis.y - xaxis.x - zaxis.z);
outRotation.w = (zaxis.x - xaxis.z) * s;
outRotation.x = (yaxis.x + xaxis.y) * s;
outRotation.y = 0.25f / s;
outRotation.z = (zaxis.y + yaxis.z) * s;
}
else
{
float s = 0.5f / XSqrt(1.0f + zaxis.z - xaxis.x - yaxis.y );
outRotation.w = (xaxis.y - yaxis.x ) * s;
outRotation.x = (zaxis.x + xaxis.z ) * s;
outRotation.y = (zaxis.y + yaxis.z ) * s;
outRotation.z = 0.25f / s;
}
}
}

این ک کلا خیلی وقتا اشتباه بر می گردونه :متفکر:

void XMat4x4::getRotationXYZ(XVec3& outAngle) const
{
float cy = XSqrt(m[0] * m[0] + m[1] * m[1]);
if(cy > 0.000001f)
{
XVec3 euler1;
XVec3 euler2;

euler1.x = atan2f(m[6], m[10]);
euler1.y = atan2f(- m[2], cy);
euler1.z = atan2f(m[1], m[0]);

euler2.x = atan2f(- m[6], - m[10]);
euler2.y = atan2f(- m[2], - cy);
euler2.z = atan2f(- m[1], - m[0]);

if( (fabs(euler1.x) + fabs(euler1.y) + fabs(euler1.z)) >
(fabs(euler2.x) + fabs(euler2.y) + fabs(euler2.z)))
{
outAngle = euler2 * X_RAD2DEG;
}
else
{
outAngle = euler1 * X_RAD2DEG;
}
}
else
{
outAngle.x = atan2f(- m[9], m[5]) * X_RAD2DEG;
outAngle.y = atan2f(- m[2], cy) * X_RAD2DEG;
outAngle.z = 0.0f;
}
}

اینم بعضی وقتا مشکل داره یهو تو ی نقطه ای می مونه و مدل دیگه نمی چرخه حی زاویه رو زیاد می کنم باز کم مشه:متفکر:

در ضمن سیستم مختصاتم راست دسته + ماتریسم ستونیه .:لبخندساده:

اگه کسی ی کتاب خونه داره که ماتری و .. برای OpenGL داره بده . کامل هم باشه ن فقط ضرب و ..
البته ب غیر از GLM اشغال

اخه چرا اپن ج ال اینقدر بد بخته حتی ی API درست درمون هم نداره ک باهاش کار کرد :قهقهه:

orache
پنج شنبه 02 خرداد 1392, 14:15 عصر
ببین من منظورتو دقیق نفهمیدم میخای ضرب و تقسیم جمع تفریق ماتریس ها بردار ها و ... رو میخای انجام بدی ؟؟ خوب میتونی از DIRECTX استفاده کنی نه به عنوان رندر و... ها فقط فرض کن یک کتابخونست برای همین کار ها یه نگاه به کد زیر بنداز


#include <d3dx10.h>
#include <iostream>
using namespace std;
// Overload the "<<" operators so that we can use cout to
// output D3DXVECTOR3 objects.
ostream& operator<<(ostream& os, D3DXVECTOR3& v)
{
os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
return os;
}
int main()
{
// Using constructor, D3DXVECTOR3(FLOAT x, FLOAT y, FLOAT z);
D3DXVECTOR3 u(1.0f, 2.0f, 3.0f);
// Using constructor, D3DXVECTOR3(CONST FLOAT *);
float x[3] = {-2.0f, 1.0f, -3.0f};
D3DXVECTOR3 v(x);
// Using constructor, D3DXVECTOR3() {};
D3DXVECTOR3 a, b, c, d, e;
// Vector addition: D3DXVECTOR3 operator +
a = u + v;
// Vector subtraction: D3DXVECTOR3 operator -
b = u - v;
// Scalar multiplication: D3DXVECTOR3 operator *
c = u * 10;
// ||u||
float L = D3DXVec3Length(&u);
// d = u / ||u||
D3DXVec3Normalize(&d, &u);
// s = u dot v
float s = D3DXVec3Dot(&u, &v);
// e = u x v
D3DXVec3Cross(&e, &u, &v);
cout << "u = " << u << endl;
cout << "v = " << v << endl;
cout << "a = u + v = " << a << endl;
cout << "b = u - v = " << b << endl;
cout << "c = u * 10 = " << c << endl;
cout << "d = u / ||u|| = " << d << endl;
cout << "e = u x v = " << e << endl;
cout << "L = ||u|| = " << L << endl;
cout << "s = u.v = " << s << endl;
return 0;
}

اینم عکس خروجیش خروجیش به صورت زیره تازه کلی کارا دیگه هم میشه باهاش کرد فقط ماتریس 1 بعدی نیست خیلی چیزا دیگه هم هست که تو یک کتابی همه رو گفته
http://s4.picofile.com/file/7774816876/aaaaaaaaaaaaaaa.png

UfnCod3r
پنج شنبه 02 خرداد 1392, 14:20 عصر
نمی خوام از DX استفاده کنم . از هیچیزیش :لبخند:
درضمن سیستم DX چپ دسته من راست دست می خوام .
الان دارم از Bullet ی چیزایی پیدا می کنم ببینم چی میشه :لبخندساده:

orache
پنج شنبه 02 خرداد 1392, 14:23 عصر
ببین یعنی نمیخای از DX اصلا استفاده کنی :متفکر: نمیشه بالاخره باید یه جا ازش استفاده کنی چون خیلی بهتر از بقیه هست تاحالا هر مشکلی که داشتیم و تو هم داشتی تو DX به طور آماده هست مثلا همون View Port که دوربین دور خودش میچرخه تو dx الگوریتمهاش هست
راستی چپ دست راست دست نمیدونم چیه در هرصورت تو میتونی مانیتورت رو برعکس کنی :لبخند:

SeganX
جمعه 03 خرداد 1392, 13:11 عصر
این رو یه نگاه بنداز
http://bullet.svn.sourceforge.net/viewvc/bullet/trunk/Extras/vectormathlibrary

UfnCod3r
جمعه 03 خرداد 1392, 16:04 عصر
هرچی کار کردم درست نشد نمی دونم چه مرگشه . فعلا تبدیل می کنم به Euler و بعد Quat
:متفکر: