Page 1 of 1

Rotating a squared matrix

Posted: Sun Jan 06, 2008 3:44 pm
by Clay
First I want to say hi to everyone and I want to say that I watch Pete's QBasic Site almost every day since a few years and I really like it!

Here we go, I want to rotate a squared matrix by 90 degrees right or left selected first by the user within a bigger matrix.

How can I achieve this in QBasic? I'm asking this because I have this small program I made to edit images and I have a fonction included in this program that allow to do such rotations. However, it doesn't work very well. Here is the part of the code that does the "capture" of the selection in order to flip it or rotate it:

x% / 3 and y% / 3 are the upper left corner of the selection
mx% / 3 and my% / 3 are the bottom right of the selection
xmax% / 3 and ymax% / 3 are the bottom right of the image it self

The variables are divided by 3 because of the image is seen through a big grid where each pixel is 200% bigger than normal.

Code: Select all

flip.rotate:
IF x% = xmax% - 3 OR y% = ymax% - 3 THEN GOTO 11
COLOR 10
LOCATE 23, 1
SELECT CASE A$
 CASE "H": PRINT "Define area for horizontal flip..."
 CASE "V": PRINT "Define area for vertical flip..."
 CASE "R": PRINT "Define area for rotation..."
END SELECT
COLOR 15
B$ = "": mx% = x%: my% = y%: x% = x% + 6: y% = y% + 6
DO
 LOCATE 23, 36: PRINT "     ": LOCATE 23, 36
 IF A$ = "H" OR A$ = "V" THEN
  PRINT LTRIM$(STR$((x% - mx%) / 3)) + "x" + LTRIM$(STR$((y% - my%) / 3))
 ELSE
  PRINT LTRIM$(STR$((x% - mx%) / 3)) + CHR$(253)
 END IF
 GET (mx% + (x% - mx%) / 2 - 2, my% + (y% - my%) / 2 - 2)-(mx% + (x% - mx%) / 2 + 2, my% + (y% - my%) / 2 + 2), buffer
 DO WHILE B$ = ""
  FOR i% = 0 TO 1
   LINE (mx%, my%)-(x%, y%), 15 * i%, B
   LINE (mx% + (x% - mx%) / 2, my% + (y% - my%) / 2 - 2)-(mx% + (x% - mx%) / 2, my% + (y% - my%) / 2 + 2), 15 * i%, B
   LINE (mx% + (x% - mx%) / 2 - 2, my% + (y% - my%) / 2)-(mx% + (x% - mx%) / 2 + 2, my% + (y% - my%) / 2), 15 * i%, B
   FOR j% = 1 TO 300
    B$ = INKEY$
    IF B$ <> "" THEN EXIT FOR
   NEXT j%
   IF B$ <> "" THEN EXIT FOR
  NEXT i%
 LOOP
 LINE (mx%, my%)-(x%, y%), 19, B
 PUT (mx% + (x% - mx%) / 2 - 2, my% + (y% - my%) / 2 - 2), buffer, PSET
 B$ = UCASE$(B$)
 SELECT CASE B$
  CASE CHR$(0) + CHR$(72): GOSUB check.up: IF A$ = "R" THEN GOSUB check.left
  CASE CHR$(0) + CHR$(80):
   GOSUB check.down
   IF A$ = "R" THEN
    GOSUB check.right
    IF mx% - my% <> x% - y% THEN x% = mx% + 6: y% = my% + 6
   END IF
  CASE CHR$(0) + CHR$(77):
   GOSUB check.right
   IF A$ = "R" THEN
    GOSUB check.down
    IF mx% - my% <> x% - y% THEN x% = mx% + 6: y% = my% + 6
   END IF
  CASE CHR$(0) + CHR$(75): GOSUB check.left: IF A$ = "R" THEN GOSUB check.up
  CASE CHR$(13): EXIT DO
  CASE CHR$(27): x% = mx%: y% = my%: GOTO 10
 END SELECT
 B$ = ""
LOOP
LINE (mx%, my%)-(x%, y%), 15, B
IF A$ = "H" OR A$ = "V" THEN
 COLOR 10
 LOCATE 23, 1
 PRINT "Mirror effect (Y/N)?                    "
 B$ = ""
 DO WHILE B$ = ""
  B$ = UCASE$(INKEY$)
  IF B$ <> "" THEN IF B$ <> "Y" AND B$ <> "N" THEN B$ = ""
 LOOP
 LOCATE 23, 22: PRINT B$
 mirror% = ASC(B$) \ 89
END IF
IF A$ = "R" THEN
 COLOR 10
 LOCATE 23, 1
 PRINT "Rotate which way: (R)ight or (L)eft?    "
 B$ = ""
 DO WHILE B$ = ""
  B$ = UCASE$(INKEY$)
  IF B$ <> "" THEN IF B$ <> "R" AND B$ <> "L" THEN B$ = ""
 LOOP
 LOCATE 23, 38: PRINT B$
END IF
COLOR 15
LINE (mx% + (x% - mx%) / 2, my% + (y% - my%) / 2 - 2)-(mx% + (x% - mx%) / 2, my% + (y% - my%) / 2 + 2), 19, B
LINE (mx% + (x% - mx%) / 2 - 2, my% + (y% - my%) / 2)-(mx% + (x% - mx%) / 2 + 2, my% + (y% - my%) / 2), 19, B
LINE (mx%, my%)-(x%, y%), 19, B
FOR j% = mx% / 3 TO x% / 3 - 1
 FOR i% = my% / 3 TO y% / 3 - 1
  buffer(j%, i%) = POINT(171 + j%, 1 + i%)
 NEXT i%
NEXT j%
FOR j% = mx% / 3 TO x% / 3 - 1
 FOR i% = my% / 3 TO y% / 3 - 1
  SELECT CASE A$
   CASE "H":
    IF i% < (my% / 3 + y% / 3) / (mirror% + 1) THEN
     LINE (1 + j% * 3, 1 + ((my% / 3 + y% / 3) - i% - 1) * 3)-(2 + j% * 3, 2 + ((my% / 3 + y% / 3) - i% - 1) * 3), buffer(j%, i%), BF
     PSET (171 + j%, 1 + (my% / 3 + y% / 3) - i% - 1), buffer(j%, i%)
    END IF
   CASE "V":
    IF j% < (mx% / 3 + x% / 3) / (mirror% + 1) THEN
     LINE (1 + ((mx% / 3 + x% / 3) - j% - 1) * 3, 1 + i% * 3)-(2 + ((mx% / 3 + x% / 3) - j% - 1) * 3, 2 + i% * 3), buffer(j%, i%), BF
     PSET (171 + (mx% / 3 + x% / 3 - j% - 1), 1 + i%), buffer(j%, i%)
    END IF
   CASE "R":
    IF B$ = "R" THEN
     LINE (1 + (i% * 3), 1 + (j% * 3))-(2 + (i% * 3), 2 + (j% * 3)), buffer(j%, y% / 3 - i% - 1), BF
     PSET (171 + i%, 1 + j%), buffer(j%, y% / 3 - i% - 1)
    ELSE
     LINE (1 + (i% * 3), 1 + (j% * 3))-(2 + (i% * 3), 2 + (j% * 3)), buffer(x% / 3 - j% - 1, i%), BF
     PSET (171 + i%, 1 + j%), buffer(x% / 3 - j% - 1, i%)
    END IF
  END SELECT
 NEXT i%
NEXT j%
x% = mx%: y% = my%
GOTO 10
Thank you for reading! :)

Edit 2: I've decided to post my old version of the code, the one that actually works better than the new one.

Posted: Sun Jan 06, 2008 11:09 pm
by Clay
Well lets forget the code and do it in a more simple way:

We have this matrix and the selection I made and I wish to rotate it 90 degrees clockwise:

Before the rotation:
Image

After the rotation:
Image

How can I do this in a QBasic way?

Please help me!

Regards,
Clay

Posted: Mon Jan 07, 2008 9:13 am
by Codemss
You can do some easy rotations by just swapping the x and y parameters, or replacing x by size - x and y by size - y.(I know this sounds vague :s) Example: you have a 5x5 matrix and you want to rotate a little piece out of it. First it's (i think) necessary to have a 'buffer' matrix. To store the variables before you place them in the first matrix. A little piece of code will come soon.

Posted: Mon Jan 07, 2008 4:34 pm
by Clay
It looks so simple to you! I shall wait for your piece of code!

Thanks! :D

Posted: Thu Sep 17, 2009 11:37 pm
by Clay
Problem solved! I found a way to do it by reducing the problem to its simpliest expression!

Thanks!