Page 1 of 1

Rotating a bit map image

Posted: Wed Sep 19, 2007 7:14 pm
by Raspberrypicker
Is it possible to rotate a bit map image?

If I draw a car using a bit map, and then the car wants to go left. I need the front part of the car to face left then. So essentially, this would just be rotating the image.

Ex.

Code: Select all

DATA 1,2,3,4
DATA 1,2,3,4
DATA 1,2,3,4
DATA 1,2,3,4
turns into:

Code: Select all

DATA 4,4,4,4
DATA 3,3,3,3
DATA 2,2,2,2
DATA 1,1,1,1
Quite boring to re-type all this out, especially which bigger bitmaps, eh?
But if I must I must.

Posted: Thu Sep 20, 2007 2:12 am
by Anonymous

Posted: Thu Sep 20, 2007 6:13 am
by Mentat
QB #24 has a tutorial on rotation. It's in the wireframe article.

Code: Select all

LET X=OX+(X-OX)*COS(A) ? (Y-OY)*SIN(A)
LET Y=OY+(Y-OY)*COS(A)+(X-OX)*SIN(A)
This will rotate point(X,Y) around the point(OX,OY) by a counterclockwise angle of A (in radians)

Posted: Fri Sep 21, 2007 3:42 pm
by Raspberrypicker
alright cool, and I thought there was no such thing in what I was asking :o

thanx guys...if it doesn't work I'll come back to complain, hee-hee j/p

Posted: Fri Sep 21, 2007 4:12 pm
by Mentat
Well, Bitmaps are really nothing more than fancy PSETing (or POKEing). So, operations on points/lines and bitmaps should work the same.

But if all else fails, do it by hand. :)

Posted: Sat Sep 22, 2007 11:38 am
by Codemss
Their should be a simpler way, I think. When you only want to rotate in angles that are multiplies of 90 degrees, it has to be be possible to do that with swapping x and y axis and inverting them. mmm. I found it here is the code a bit messy and in textmode but else you couldnt see it:

CLS
SCREEN 12
DEFINT A-Z
DIM map(3, 3)
DATA 2, 0, 0, 1
DATA 0, 177, 177, 0
DATA 0, 177, 177, 0
DATA 0, 4, 5, 0
FOR y = 0 TO 3
FOR x = 0 TO 3
READ map(x, y)
NEXT
NEXT

PRINT "Rotation = 0 degrees"
FOR x = 0 TO 3
FOR y = 0 TO 3
LOCATE y + 3, x + 1
PRINT CHR$(map(x, y))
NEXT
NEXT
PRINT

PRINT "Rotation = 90 degrees clockwise"
FOR x = 0 TO 3
FOR y = 0 TO 3
LOCATE y + 9, x + 1
PRINT CHR$(map(y, 3 - x))
NEXT
NEXT
PRINT

PRINT "Rotation = 180 degrees clockwise"
FOR x = 0 TO 3
FOR y = 0 TO 3
LOCATE y + 15, x + 1
PRINT CHR$(map(3 - x, 3 - y))
NEXT
NEXT
PRINT

PRINT "Rotation = 270 degrees clockwise"
FOR x = 0 TO 3
FOR y = 0 TO 3
LOCATE y + 21, x + 1
PRINT CHR$(map(3 - y, x))
NEXT
NEXT
PRINT

Posted: Sat Sep 22, 2007 12:47 pm
by Raspberrypicker
thanx codemss
this looks a lot simpler, something that I can actually understand. YAY!

yea, i haven't been through trig yet...actually i'm taking it this year, so maybe i'll understand it then.

Posted: Sat Sep 22, 2007 12:56 pm
by Mentat
Trig is EXTREMELY useful for graphics. I forgot about flipping the For loops. That's more efficient.

Posted: Tue Nov 20, 2007 11:32 am
by D.S
umm... the trig code doesn't seem to work...

Posted: Tue Nov 20, 2007 4:22 pm
by Mac
Codemss wrote:Their should be a simpler way, I think. When you only want to rotate in angles that are multiplies of 90 degrees
Yes! It would be incredibly inefficient to use rotation via angles when all you want to do is reverse bits.

as Codemss demo aludes, you take bits

a b c d e
f g h i j
k l m n o

and simply do
e d c b a
j i h g f
o n m l k

Fast and perfect. Angles give approximations. They are when you actually want to rotate, say, 15 degrees.

Mac

Posted: Tue Nov 20, 2007 6:40 pm
by Mentat
Or, you can load the main image into a compiler such as BlitzBASIC that can easily rotate, save the turned images, and then just load them.
Mac wrote:Yes! It would be incredibly inefficient to use rotation via angles when all you want to do is reverse bits
Yes, but using angles is more flexible. Angles can handle all rotations, while the flip/rotate loops can only handle eight directions. It's nice to say "rotate P(x1,y1) Φ? around P(x2,y2)." :)

Well

Posted: Fri Nov 23, 2007 12:59 pm
by burger2227
Once an image is BLOADed or gotten with GET, all of the data is in the array including the dimensions. Each piece of data can be manipulated using trig or just by reading the data differently.

Some people index the RGB color settings for the bitmap first, so you have to find the start of the image data and remember where to start and finish. The color data usually ends at index 47 in SCREEN 12. 767 in 13. So the width is at 48 and the height is at 49. Or 0 and 1 with the default colors like you are probably using.

To find the end of the data, you have to read the array backwards until you find the first value above 0. To do that and be sure it is not just black, PSET(width, Height), 15 and GET the image again. You could also use POINT to find the lower right corner color attribute. I hope you only BSAVEd the image and not black parts of the screen. The original bitmap header gave you the width and height to GET.

Code: Select all

IF POINT(width&, height&) = 0 THEN 
      PSET(width&, height&), 1
      GET (width&, height&), Array(48)   '0 if no RGB values indexed
END IF
Then use a reverse loop to find values that are greater than 0.

Code: Select all

FOR I = UBOUND(Array) to 0 STEP -1
       IF Array(I) > 0 THEN maxindex = I : EXIT FOR
NEXT
Now you know the exact parts of the array that hold the data. You can then flip it, rotate it, whatever. To flip it, just read the array backwards.

Ted