2017-07-01 45 views
2

M是一個可逆2x2矩陣。讓C爲以(0,0)爲中心的半徑1的圓。令E爲橢圓M*C,其中半長軸s1和半短軸s2。 (然後s1 >= s2。)我需要找到sx,水平範圍應用於C,Msy,垂直範圍應用於C,M如何確定一個2x2矩陣在x軸上的縮放比y軸多嗎?

我可以通過在M上執行奇異值分解來測量s1s2。 (我使用的算法是基於Pedro Gimeno對Robust algorithm for 2x2 SVD的回答,s1是更大的奇異值,而s2是更小的奇異值。)我知道<sx,sy>等於<s1,s2><s2,s1>,但我不知道哪一個;但是,如果我可以確定sx > sy(通過執行下面的scalesMoreInXAxis(mat2)函數),那麼我可以得出結論<sx,sy> = <s1,s2>(反之亦然,如果sx <= sy)。

這裏是我的GLSL代碼:

bool scalesMoreInXAxis(mat2 m){ 
    // TODO: implement 
    return false; 
} 

void main(){ 

    float a = M[0][0]; 
    float b = M[1][0]; 
    float c = M[0][1]; 
    float d = M[1][1]; 

    float e = (a + d)/2.0; 
    float f = (a - d)/2.0; 
    float g = (c + b)/2.0; 
    float h = (c - b)/2.0; 

    float q = sqrt(e*e + h*h); 
    float r = sqrt(f*f + g*g); 

    float s1 = q + r;  // Semi major axis 
    float s2 = abs(q - r); // Semi minor axis 

    vec2 s = scalesMoreInXAxis(M) ? vec2(s1,s2) : vec2 (s2,s1); 
} 
+0

你的's1'和's2'似乎是'M'的SVD分解的奇異值,'s1> s2'。因此,'s1'和's2'是'E'的長軸和短軸的長度(可以這麼說)。但是,我不明白你的'sx'和'sy'是什麼。謹慎解釋? –

+0

'sx'是'M'應用於'C'的水平刻度,'sy'是'M'應用於'C'的垂直刻度。我知道'sx'等於's1'或's2',但我不知道哪一個;然而,如果我可以確定'sx> sy',(通過實現scalesMoreInXAxis函數),那麼我可以得出結論:'sx = s1'和'sy = s2'。 –

+1

對於任意矩陣來說,'sx'和'sy'的這種定義沒有什麼意義。假設「M」旋轉了90度,然後將「x」軸縮放了2倍。這相當於首先將「y」軸縮放2,然後旋轉90度。這些將是兩個不同但等價的「SVD」分解。如果你在'E'的主軸和副軸之後,那麼它們的方向是'U'的列,並且相應的比例因子是'M = U * S * V'中'S'的對角線元素。 –

回答

0

你想實現什麼?我不明白你的意思是什麼半x軸。

然而,這裏是我的想法,你怎麼能計算出半軸系:

讓M = U * S * V(SVD分解)

V * C的溫度將是C,爲V僅僅是一個旋轉(旋轉一圈不會改變它)。

所以,我們留下了U * s。這種轉換是角度保存。 U * s將首先縮放該圓(因此它變成一個具有半軸s * [1 0]'和s * [0 1]'的橢圓),然後旋轉它。因此,最後的半軸是U * s的列,U * s * [1 0]'和U * s * [0 1]'。

注意:對於一般的矩陣,沒有這樣的問題:「它如何在水平方向上縮放」。所有人都可以說原始x軸(我的意思是轉換後原來的x軸有多久)發生了多少規模,這只是M * [1 0]'的長度,長度第一列。

+0

請參閱'sx'和'sy'的更新定義。關於你的答案,U也是一個旋轉矩陣,那它怎麼能包含我的橢圓的軸呢? –

+0

@WilliamHeesen:我已經編輯了我的答案,我希望現在很清楚 – geza

+0

你是正確的'V * C = C',但在我的情況下,我需要考慮頂點着色器中的'V',因爲我的圓圈被表示由一個正方形。功能代碼可在我的[GitHub repo](https://github.com/wjheesen/vector-art/blob/master/src/res/src/shader/ellipse.glslx)中找到。 –