! Routines for the EDWIN transformation stack. %external %routine %spec SIGNAL (%integer E, SE, EI) !%external %long %real %fn %spec SQRT (%long %real X) %const %integer MAX T STACK = 25 %record %format POINTF (%integer X, Y) %record %format TRANSF (%real %array A(0:8)) %own %record(TRANSF) %array T STACK (0:MAX T STACK) %own %real %array %name CUR, OLD %own %real %array UNITY (0:8) = 1, 0, 0, 0, 1, 0, 0, 0, 1 %own %integer STACK PTR = -1 %external %routine M TRANSLATE (%integer X, Y, %real %array %name T) %integer I T(I) = UNITY(I) %for I = 0, 1, 8 T(6) = X T(7) = Y %end %external %routine MMX (%real %array %name T) %integer I T(I) = UNITY(I) %for I = 0, 1, 8 T(0) = -1 %end %external %routine MMY (%real %array %name T) %integer I T(I) = UNITY(I) %for I = 0, 1, 8 T(4) = -1 %end %external %routine M ROTATE (%integer A, B, %real %array %name T) %integer I %real SQRT AA BB, DIR AB, DIR BA T(I) = UNITY(I) %for I = 0,1,8 A = 1 %IF A = 0 %AND B = 0 SQRT AA BB = SQRT (A*A + B*B) DIR AB = A/SQRT AA BB; DIR BA = B/SQRT AA BB T(0) = DIR AB T(4) = DIR AB T(1) = DIR BA T(3) = -DIR BA %end %external %routine MAT MUL (%real %array %name A, B, C) ! Performs the matrix multiplication C = A*B on the arrays in parameters. %integer I, J, K %real %name R %for I = 0,3,6 %cycle %for J = 0,1,2 %cycle R == C(I+J); R = 0 %for K = 0, 1, 2 %cycle R = R + A(I+K) * B(K*3+J) %repeat %repeat %repeat %end %external %routine POP TRANS signal (14, 9, 0) %if STACK PTR < 0; ! Stack not initialised. STACK PTR = STACK PTR - 1 signal (14, 11, STACK PTR) %if STACK PTR<0 CUR == OLD OLD == TSTACK(STACK PTR-1)_A %if STACK PTR>0 %end %external %routine INIT TRANS %integer I ! Initialise the transformation stack. STACK PTR = 0 CUR == T STACK (0)_A CUR(I) = UNITY(I) %for I=0,1,8 %end %external %routine PUSH TRANS (%real %array %name T) INIT TRANS %if STACK PTR < 0 OLD == CUR STACK PTR = STACK PTR + 1 signal (14, 10, STACK PTR) %if STACK PTR > MAX T STACK CUR == T STACK(STACK PTR)_A MAT MUL (T, OLD, CUR); ! CUR = T * OLD gives new transformation to be done. %end %external %routine TRANSFORM POINT {%alias "ED$TP"} ( %c %record (POINTF) %name P, NP) ! Transforms a point P to NP under the current transformation. NP_X = INT(P_X*CUR(0) + P_Y*CUR(3) + CUR(6)) NP_Y = INT(P_X*CUR(1) + P_Y*CUR(4) + CUR(7)) %end %external %routine TRANSFORM VECTOR {%alias "ED$TV"} (%record (POINTF) %name V, NV) ! Transforms a vector V to NV under the current transformation. NV_X = INT(V_X*CUR(0) + V_Y*CUR(3)) NV_Y = INT(V_X*CUR(1) + V_Y*CUR(4)) %end %external %routine INQUIRE TRANSFORM {%alias "ED$ITX"} (%real %array %name TX) %integer I TX(I) = CUR(I) %for I=0,1,8 %end %external %routine PRINT MAT (%real %array %name T) ! PRINT MAT is only required if debugging. PRINT (T(0),3,1); PRINT (T(1),3,1); PRINT (T(2),3,1) NEWLINE PRINT (T(3),3,1); PRINT (T(4),3,1); PRINT (T(5),3,1) NEWLINE PRINT (T(6),3,1); PRINT (T(7),3,1); PRINT (T(8),3,1) NEWLINE %end %end %of %file