2012-08-02 88 views
1

如何發現旋轉/縮放值?例如,在我發出以下命令之後:後記:發現旋轉/縮放值

90 rotate 

當前旋轉設置爲90.如何發現旋轉設置爲?

+1

您似乎認爲PostScript存儲了旋轉和縮放的值。實際上,它存儲了一個完整的轉換矩陣。 「旋轉」和「縮放」操作符是將當前變換矩陣乘以與旋轉和縮放相對應的適當矩陣的簡寫。 – lhf 2012-08-22 01:10:41

+0

我建議2種方法來做到這一點。沒有人向下滾動? – 2012-08-27 02:40:38

+0

另請參閱[此問題]的答案(http://stackoverflow.com/a/15263897/733077)。 – 2013-03-16 10:24:23

回答

2

旋轉(也稱爲縮放和剪切)沒有單獨的值。所有這些轉換都彙總到當前轉換矩陣(CTM)中。

您可以在PostScript語言參考手冊中找到關於CTM和轉換的極好描述,尤其是4.3.1至4.3.3節。它是瞭解PostScript作爲CTM支持所有繪圖操作的重要領域。它真的太複雜,我不認爲在這個論壇上解釋。

簡短的回答是,沒有簡單的解決方案,你必須做一些矩陣代數來找出點映射到哪裏。一個常見的訣竅是將單位正方形的座標通過CTM(點0,0和1,1),並查看變換點在哪裏結束。

0

執行此操作的一種可能方法是將rotate過載,以使其確實以便利的形式跟蹤該值。

/oldrotate /rotate load def 
/rotate { dup oldrotate 
    /currentrotation dup load 3 2 roll add 360 mod store 
} 
/currentrotation 0 def 

不幸的是,如果你使用setmatrixgsave ... grestore這是不夠的。

0

如果你真的一直在做什麼,但旋轉,平移,並均勻縮放,那麼你可以分解仿射變換矩陣(3×2)爲平移向量(1×2)和線性變換矩陣(2×2) 。然後,實際上,一個小三角可以給你旋轉。

所以這裏有一種方法可以在postscript中做到這一點。它執行一些矩陣操作而不是在CTM上操作,而是在矩陣上操作,如果乘以默認矩陣,將產生CTM。它將按順序返回旋轉角度,縮放因子和平移偏移量。將運算符序列translate scale rotate應用於這些值 - 如果默認矩陣生效 - 將生成當前矩陣。

而且我有一點遺憾,試圖通過使用PS錯誤機制來優雅地拒絕它無法處理的矩陣(在解釋器中沒有完全標準化,因爲它在標準中基本沒有記載)。爲了測試它,我從別處引入了一些隨機種子代碼。但隱藏在中間是一個相對簡單的公式b a atan,它產生角度(其中[a b c d e f]是矩陣值的名稱,以及a == d和b == -c)。

%! 
%make Adobe-style interpreters mimic ghostscript's error call 
/.error where { pop /signalerror {.error} def } if 

%"Safe" seed randomizer 
{ 0 4{ 8 bitshift (/dev/random)(r)file read pop add }repeat srand } stopped 
{ usertime 10 { %can't open file, chop some vegetables 
    save 128 string 99 2 getinterval 1 vmreclaim pop restore 
       } repeat usertime 8 bitshift add srand } if 

%translate, scale, rotate 
% extracts rotation, scaling and translation parameters 
% from the CTM (assuming it's "easy" to do) 
% 
%eg. 
% PS> rand 100 mod   %get random number 0..99 
% PS> { 1 rotate } repeat %rotate 
% PS> tsr 4 pop =   %print rotation angle 
% 
% - tsr theta Sx Sy Tx Ty 
/tsr { { 
    6 dict begin 
    matrix currentmatrix % get CTM 
    matrix defaultmatrix % get Default 
    matrix invertmatrix % get the "undo" of the Default 
    matrix concatmatrix % CTM * Default^-1 = Default-->CTM 
    aload pop % dump the matrix components 
    {/ty/tx/d/c/b/a}{exch def}forall % name the components 
     a d ne 
     b neg c ne or %ie. not "Jacobian", not "conformal" 
     { [ a b c d tx ty ] /tsr cvx /undefinedresult signalerror } if 

     b a atan % theta 
     a a mul b b mul add sqrt dup % Sx Sy (uniform scaling factors) 
     tx ty % translation 
    end 
exit } loop } def 

%1 2 scale resolve %test error trigger 
rand 100 mod 
{ 1 rotate } repeat 
rand 100 mod 
{ rand 3 mod .5 add dup scale } repeat 
tsr pstack