2009-08-11 238 views
22

我想從右手系統更改4x4矩陣,其中:
x是左和右,y是正面和背面,z是向上和向下將矩陣從右手改爲左手座標系

到左手系統,其中:
x被左和右,ž是正面和背面和ÿ是向上和向下。

對於一個向量來說很簡單,只需交換y和z值,但是如何爲矩陣做它?

+0

我可能會在這裏感到困惑,爲什麼你不能只交換y和z值?我假設你的意思是一個4x4x4矩陣,因爲4x4不會有z。 – derobert 2009-08-11 21:41:17

+0

只是一個4x4矩陣。 只是翻轉y和z翻譯值似乎並不工作,矩陣也包含一個旋轉操作,所以我認爲問題在那裏。 – cmann 2009-08-11 21:44:34

+0

我認爲你需要在任何人回答你的問題之前確切地說明你想要的東西。對於一個向量'(x,y,z,w)',你已經解釋過,「從右手變爲左手」意味着你將它改爲向量'(x,z,y,w) ',但一點也不清楚這句話對矩陣意味着什麼。例如,假設一個矩陣將向量'(1,2,3,4)'帶到向量'(5,6,7,8)',那麼當你「從右手改爲左手」時, (1,2,3,4)'到'(5,7,6,8)',還是應該用'(1,3,2,4)'到'(5,7,6) ,8)',還是你的意思是它做了別的事情? – 2009-08-11 23:52:58

回答

21

讓我試着解釋它好一點。 我需要從Blender中將z軸向上的模型導出到OpenGL中,y軸朝上。

對於每個座標(x,y,z)都很簡單;只需交換y和z值:(x,z,y)。
因爲我交換了所有的y和z值,所以我使用的任何矩陣也需要翻轉,以便它具有相同的效果。

經過大量搜索,我終於找到了解決辦法,在gamedev的:

如果您的矩陣如下所示:

{ rx, ry, rz, 0 } 
{ ux, uy, uz, 0 } 
{ lx, ly, lz, 0 } 
{ px, py, pz, 1 } 

從左至右或從右到左改變它,翻轉它是這樣的:

{ rx, rz, ry, 0 } 
{ lx, lz, ly, 0 } 
{ ux, uz, uy, 0 } 
{ px, pz, py, 1 } 
+2

您的答案似乎是從左手座標系變爲右手手座標系,但你的問題描述是改變矢量的方向。 – zionpi 2014-09-22 01:26:31

+1

opengl是一個右手系統。如果您選擇y軸向上,只需交換y軸和z軸,就會得到一個不受任何左/右手協調系統影響的座標系。我不認爲這是正確的答案。 – flankechen 2016-08-12 12:05:20

-7

因爲這似乎是一個家庭作業的答案;我會給你一個啓示:你能做些什麼來使矩陣的行列式爲負數?進一步(更好的提示):既然你已經知道如何用單獨的向量來完成這種轉換,你不認爲你可以用跨越矩陣表示的轉換的基向量來做到嗎? (請記住,矩陣可以看作是對單位向量元組執行的線性變換)

+2

謝謝,但實際上它不是功課,我也不知道任何背後的數學,所以我實際上並沒有明白這一點。 – cmann 2009-08-11 21:47:02

+0

好吧,爲了更務實和更少數學,首先您可以分別處理旋轉和平移。 – 2009-08-11 21:53:58

+0

(我假設仿射變換) – 2009-08-11 21:55:49

0

這取決於您是通過將矩陣從左邊還是從右邊相乘來變換點。

如果從左邊乘(例如:Ax = x',其中A是矩陣,x是變換點),則只需交換第二列和第三列。 如果從右邊乘(例如:xA = x'),則需要交換第二行和第三行。

如果你的觀點是列向量,那麼你在第一個場景。

11

我想我明白你的問題,因爲我目前面臨類似的問題。

  • 從一個世界矩陣開始,該世界矩陣在Z向上的空間(如世界矩陣)中轉換一個向量。

  • 現在你有一個空間,Y向上,你想知道如何處理你的舊矩陣。

試試這個:

有一個給定的世界矩陣

Matrix world = ... //space where Z is up 

這個矩陣改變您正在尋找此的矢量

Matrix mToggle_YZ = new Matrix(
{1, 0, 0, 0} 
{0, 0, 1, 0} 
{0, 1, 0, 0} 
{0, 0, 0, 1}) 

的Y和Z分量:

//same world transformation in a space where Y is up 
Matrix world2 = mToggle_YZ * world * mToggle_YZ; 

結果是下面發佈的相同的矩陣cmann。但我認爲這是更容易理解,因爲它結合了以下計算:

1)開關Y和Z

2)做舊改造

3)切換回Z和Y

+3

如果需要鏡像軸,可以通過在您的世界矩陣乘法中添加此矩陣來完成此操作: Matrix mMirror_X =新矩陣( {-1,0,0,0} {0,1,0 ,0} {0,0,1,0} {0,0,0,1}) – Gerrit 2012-09-18 15:20:47

+0

感謝Gerrit,它工作的很棒。 – VivekParamasivam 2013-12-24 08:36:03

0

變化sin因子爲-sin用於調換左右手之間的座標空間

4

我一直在努力將Unity SteamVR_Utils.RigidTransform轉換爲ROS geometry_msgs/Pose,並且需要將Unity左手座標系轉換爲ROS右手座標系。

這是我最終編寫的轉換座標系的代碼。

var device = SteamVR_Controller.Input(index); 
// Modify the unity controller to be in the same coordinate system as ROS. 
Vector3 ros_position = new Vector3(
    device.transform.pos.z, 
    -1 * device.transform.pos.x, 
    device.transform.pos.y); 
Quaternion ros_orientation = new Quaternion(
    -1 * device.transform.rot.z, 
    device.transform.rot.x, 
    -1 * device.transform.rot.y, 
    device.transform.rot.w); 

最初我嘗試使用@bleater的矩陣示例,但似乎無法使其工作。想知道我是否在某個地方犯了錯誤。

HmdMatrix44_t m = device.transform.ToHmdMatrix44(); 
HmdMatrix44_t m2 = new HmdMatrix44_t(); 
m2.m = new float[16]; 
// left -> right 
m2.m[0] = m.m[0]; m2.m[1] = m.m[2]; m2.m[2] = m.m[1]; m2.m[3] = m.m[3]; 
m2.m[4] = m.m[8]; m2.m[5] = m.m[10]; m2.m[6] = m.m[9]; m2.m[7] = m.m[7]; 
m2.m[8] = m.m[4]; m2.m[9] = m.m[6]; m2.m[10] = m.m[5]; m2.m[11] = m.m[11]; 
m2.m[12] = m.m[12]; m2.m[13] = m.m[14]; m2.m[14] = m.m[13]; m2.m[15] = m.m[15]; 

SteamVR_Utils.RigidTransform rt = new SteamVR_Utils.RigidTransform(m2); 

Vector3 ros_position = new Vector3(
    rt.pos.x, 
    rt.pos.y, 
    rt.pos.z); 
Quaternion ros_orientation = new Quaternion(
    rt.rot.x, 
    rt.rot.y, 
    rt.rot.z, 
    rt.rot.w); 
+0

謝謝,這非常有幫助! – davetcoleman 2015-12-19 20:54:44

+0

我看到Steam_Utils.RigidTransform轉換與此處不同。你想在這裏填寫你的答案嗎? – NTj 2016-04-14 07:25:14

2

通常情況下,您希望將矩陣從一組向前/向右/向上約定更改爲另一組向前/向右/向上約定。例如,ROS使用z-up,而Unreal使用y-up。無論你是否需要做手勢翻轉,該過程都可以工作。

請注意,短語「從右手切換到左手」是不明確的。有許多左手前進/右/上手慣例。例如:forward = z,right = x,up = y;和forward = x,right = y,up = z。你應該真的認爲它是「我該如何將ROS的前瞻/正確/虛幻的概念轉化爲虛幻的前瞻/正確/上升的概念」。

因此,創建一個在約定之間轉換的矩陣是一項非常簡單的工作。假設我們做到了這一點,現在我們有

mat4x4 unrealFromRos = /* construct this by hand */; 
mat4x4 rosFromUnreal = unrealFromRos.inverse(); 

比方說,OP有來自ROS矩陣,並且她希望在虛幻中使用它。她的原始矩陣採用ROS風格的矢量,做一些東西,併發出ROS風格的矢量。她需要一個採用虛幻風格向量的矩陣,做相同的事情,併發出虛幻風格的向量。看起來像這樣:

mat4x4 turnLeft10Degrees_ROS = ...; 
mat4x4 turnLeft10Degrees_Unreal = unrealFromRos * turnLeft10Degrees_ROS * rosFromUnreal; 

它應該很清楚爲什麼這會起作用。你需要一個虛幻矢量,將其轉換爲ROS風格,現在你可以使用它的ROS風格矩陣。這給你一個ROS矢量,你可以將它轉換回虛幻風格。

Gerrit的回答並不完全一般,因爲在一般情況下,rosFromUnreal!= unrealFromRos。如果你只是反轉一個單一的軸,這是真的,但如果你正在轉換X-> Y,Y-> Z,Z-> X,那麼這就是真的。我發現它不太容易出錯,總是使用矩陣及其反轉來執行這些約定開關,而不是嘗試編寫只翻轉正確成員的特殊函數。

這種矩陣運算inverse(M) * X * M出現了很多。您可以將其視爲「基礎變更」操作;要了解更多信息,請參閱https://en.wikipedia.org/wiki/Matrix_similarity