News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

are there any rotate udg routines out there that rotate say 8 degrees at a time?

Started by the777, 08:14, 14 August 25

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

lightforce6128

@the777 : Did you use the listing from the magazine or own code?

How do you do the rotation?

I also did some experiments, but the math is a bit complicated for a small assembler program. On a PC and with a modern programming language one does not have to think about how many bits are available in a data type or how a multiplication or division can be performed fast. On a CPC this is another thing ...

The following was done with Maxima and a bit of help from the Mistral AI (although I'm not 100% convinced of the result).

;; Variables:
;;     c,s   : cos(rotation_angle) , sin(rotation_angle)
;;     rx,ry : rotation_center_x , rotation_center_y
;;     sx,sy : scaling_factor_x , scaling_factor_y
;;     tx,ty : translation_offset_x , translation_offset_y
;;     ax,ay : aspect_ratio_x , aspect_ratio_y (e.g. (2,1) for mode 0)
;;
;; Single transformation matrices:
;;     m1 : matrix( [    1,  0, +rx ] , [  0,    1, +ry ] , [ 0, 0, 1 ] );   /* inverse rotation center */
;;     m2 : matrix( [ 1/ax,  0,   0 ] , [  0, 1/ay,   0 ] , [ 0, 0, 1 ] );   /* inverse aspect ratio */
;;     m3 : matrix( [ 1/sx,  0,   0 ] , [  0, 1/sy,   0 ] , [ 0, 0, 1 ] );   /* scaling */
;;     m4 : matrix( [   +c, -s,   0 ] , [ +s,   +c,   0 ] , [ 0, 0, 1 ] );   /* rotation */
;;     m5 : matrix( [   ax,  0,   0 ] , [  0,   ay,   0 ] , [ 0, 0, 1 ] );   /* aspect ratio */
;;     m6 : matrix( [    1,  0, -rx ] , [  0,    1, -ry ] , [ 0, 0, 1 ] );   /* rotation center */
;;     m7 : matrix( [    1,  0,  tx ] , [  0,    1,  ty ] , [ 0, 0, 1 ] );   /* translation */
;;
;; Combined transformation matrix:
;;     combined : m1.m2.m3.m4.m5.m6.m7;
;;     combined = [
;;         [           c/sx , -(ay*s)/(ax*sx) , (ax*c*(tx-rx)-ay*s*(ty-ry))/(ax*sx)+rx ],
;;         [ (ax*s)/(ay*sy) ,            c/sy , (ay*c*(ty-ry)+ax*s*(tx-rx))/(ay*sy)+ry ],
;;         [              0 ,               0 ,                                      1 ]
;;     ]
;;
;; Split into smaller terms:
;;
;;     k1 : c * (1/sx);
;;     k2 : s * (1/sx);
;;     k3 : s * (1/sy);
;;     k4 : c * (1/sy);
;;    
;;     dx : tx - rx;
;;     dy : ty - ry;
;;    
;;     mx : ax*c*dx - ay*s*dy ;
;;     my : ay*c*dy + ax*s*dx ;
;;    
;;     transformation : matrix([
;;         [         k1 , -(ay/ax)*k2 , mx*(1/ax)*(1/sx) + rx ],
;;         [ (ax/ay)*k3 ,          k4 , my*(1/ay)*(1/sy) + ry ]
;;     ]);

From the six numbers in the transformation matrix the rotated, scaled, and translated/moved symbol can be created. With fix point arithmetic this should be acceptably fast. But this is not of big help if the calculation of the six numbers takes longer than interpolating the rotated symbol ...

the777

Quote from: lightforce6128 on 06:19, 26 August 25@the777 : Did you use the listing from the magazine or own code?

How do you do the rotation?

I also did some experiments, but the math is a bit complicated for a small assembler program. On a PC and with a modern programming language one does not have to think about how many bits are available in a data type or how a multiplication or division can be performed fast. On a CPC this is another thing ...

The following was done with Maxima and a bit of help from the Mistral AI (although I'm not 100% convinced of the result).

;; Variables:
;;     c,s   : cos(rotation_angle) , sin(rotation_angle)
;;     rx,ry : rotation_center_x , rotation_center_y
;;     sx,sy : scaling_factor_x , scaling_factor_y
;;     tx,ty : translation_offset_x , translation_offset_y
;;     ax,ay : aspect_ratio_x , aspect_ratio_y (e.g. (2,1) for mode 0)
;;
;; Single transformation matrices:
;;     m1 : matrix( [    1,  0, +rx ] , [  0,    1, +ry ] , [ 0, 0, 1 ] );   /* inverse rotation center */
;;     m2 : matrix( [ 1/ax,  0,   0 ] , [  0, 1/ay,   0 ] , [ 0, 0, 1 ] );   /* inverse aspect ratio */
;;     m3 : matrix( [ 1/sx,  0,   0 ] , [  0, 1/sy,   0 ] , [ 0, 0, 1 ] );   /* scaling */
;;     m4 : matrix( [   +c, -s,   0 ] , [ +s,   +c,   0 ] , [ 0, 0, 1 ] );   /* rotation */
;;     m5 : matrix( [   ax,  0,   0 ] , [  0,   ay,   0 ] , [ 0, 0, 1 ] );   /* aspect ratio */
;;     m6 : matrix( [    1,  0, -rx ] , [  0,    1, -ry ] , [ 0, 0, 1 ] );   /* rotation center */
;;     m7 : matrix( [    1,  0,  tx ] , [  0,    1,  ty ] , [ 0, 0, 1 ] );   /* translation */
;;
;; Combined transformation matrix:
;;     combined : m1.m2.m3.m4.m5.m6.m7;
;;     combined = [
;;         [           c/sx , -(ay*s)/(ax*sx) , (ax*c*(tx-rx)-ay*s*(ty-ry))/(ax*sx)+rx ],
;;         [ (ax*s)/(ay*sy) ,            c/sy , (ay*c*(ty-ry)+ax*s*(tx-rx))/(ay*sy)+ry ],
;;         [              0 ,               0 ,                                      1 ]
;;     ]
;;
;; Split into smaller terms:
;;
;;     k1 : c * (1/sx);
;;     k2 : s * (1/sx);
;;     k3 : s * (1/sy);
;;     k4 : c * (1/sy);
;;    
;;     dx : tx - rx;
;;     dy : ty - ry;
;;    
;;     mx : ax*c*dx - ay*s*dy ;
;;     my : ay*c*dy + ax*s*dx ;
;;    
;;     transformation : matrix([
;;         [         k1 , -(ay/ax)*k2 , mx*(1/ax)*(1/sx) + rx ],
;;         [ (ax/ay)*k3 ,          k4 , my*(1/ay)*(1/sy) + ry ]
;;     ]);

From the six numbers in the transformation matrix the rotated, scaled, and translated/moved symbol can be created. With fix point arithmetic this should be acceptably fast. But this is not of big help if the calculation of the six numbers takes longer than interpolating the rotated symbol ...
i used the code from the book


eto

Sorry, I still don't fully get what the code should do.

Is it for characters only? So 8x8? Or should it rotate any graphics of any size?

Does speed matter or could it be slow, e.g. in BASIC?

the777

Quote from: eto on 11:19, 26 August 25Sorry, I still don't fully get what the code should do.

Is it for characters only? So 8x8? Or should it rotate any graphics of any size?

Does speed matter or could it be slow, e.g. in BASIC?
it rotates a character or a string by reading it off screen memory at the top left hand corner. it will rotate up to 12 or so characters in length. so it wont rotate graphics of any size. its a machine code routine that is called from basic. i.e an rsx enxtension

the777

i just checked and it can rotate graphics of any size but you have to change the parameters in the added basic commands

Powered by SMFPacks Menu Editor Mod