Postscript: discover rotate/scale value

青春壹個敷衍的年華 提交于 2019-12-11 12:07:25

问题


How can I discover the values of rotate/scale? For example, after I issue the following command:

90 rotate

the current rotation is set to 90. How do I discover what rotate is set to?


回答1:


Rotation (also scaling and shearing) do not have individual values. All such transformations are rolled up into the Current Transformation Matrix (CTM).

You can find an excellent description of the CTM and the transformations in the PostScript Language Reference Manual, especially sections 4.3.1 to 4.3.3. Its an important area to understand for PostScript as the CTM underpins all drawing operations. Its really too complex to explain in this forum I think.

The short answer is that there is no simple solution, you have to do some matrix algebra to find out where points map to. A common trick is to pass the co-ordinates of the unit square through the CTM (points 0,0 and 1,1) and see where the transformed points end up.




回答2:


If you really have been doing nothing but rotations, translations, and uniform scaling, then you can decompose the affine transformation matrix (3x2) into a translation vector (1x2) and a linear transformation matrix (2x2). Then, a little trig can, in fact, give you the rotation.

So here's one way to do this in postscript. It does some matrix manipulations to operate not on the CTM, but on a matrix which would yield the CTM if multiplied by the Default Matrix. It returns the rotation angle, scaling factors, and translation offsets, in that order. Applying the operator sequence translate scale rotate to these values -- if the Default Matrix were in effect -- would produce the Current Matrix.

And I got a little carried away trying to make it elegantly reject matrices it can't handle by using the PS error mechanism (not completely standardized across interpreters because it was largely undocumented in the standard). And to test it, I brought in some random-seed code from elsewhere. But hidden in the middle is a relatively simple formula b a atan which yields the angle (where [a b c d e f] are names of the matrix values, and a == d, and 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



回答3:


One possible way to do this would be to overload rotate so that it does track the value in a convenient form.

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

Unfortunately, this isn't sufficient if you're using setmatrix or gsave ... grestore.



来源:https://stackoverflow.com/questions/11777305/postscript-discover-rotate-scale-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!