Recent

Author Topic: Rotating a simple bitmap matrix  (Read 282 times)

TBMan

  • Full Member
  • ***
  • Posts: 105
Rotating a simple bitmap matrix
« on: March 23, 2025, 03:27:43 am »
So, I've been thinking about how to rotate a bitmap the in between degrees. (Doing 90, 180, 270 is pretty simple ). My example does produce skipped pixels in the placement of the bitmap pixels due to the rounding of the real numbers used. This works though. If you have a tile you want to rotate 45 degrees, 30 degrees, this works fairly well. What I'm doing is copying the bitmap colors from the 32x32 tile to a 32x32 rotation matrix that has a tsinglepoint type for each location in the matrix, as well as the color of the tile. The tank is one I made for a simple tank battle/capture cities game I recently started on.

Code: Pascal  [Select][+][-]
  1. program rotatetank;
  2. {
  3.  Rotates a 32x32 tile
  4. }
  5.  
  6.  
  7. uses
  8.   ptccrt,
  9.   ptcgraph,
  10.   Math;
  11.  
  12. const
  13.   MAXCOL = 31;
  14.  
  15.   blueNorth: array [0..MAXCOL, 0..MAXCOL] of byte =
  16.     ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  17.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  18.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  19.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  20.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  21.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  22.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  23.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 26, 26, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  24.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 190, 190, 190, 26, 26, 190, 190, 190, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  25.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 190, 26, 26, 190, 190, 190, 190, 190,20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  26.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 190, 26, 26, 190, 190, 190, 190, 190,20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  27.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 190, 26, 26, 190, 190, 190, 190, 190,20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  28.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 21, 26, 26, 21, 190, 190, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  29.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 21, 23, 23, 23, 23, 21, 190, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  30.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 21, 23, 23, 23, 23, 23, 23, 21, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  31.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 21, 23, 1, 1, 1, 1, 23, 21, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  32.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 21, 23, 1, 1, 1, 1, 23, 21, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  33.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 21, 23, 1, 1, 1, 1, 23, 21, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  34.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 21, 23, 1, 1, 1, 1, 23, 21, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  35.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 21, 23, 23, 23, 23, 23, 23, 21, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  36.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 21, 21, 21, 21, 21, 21, 190, 190, 190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  37.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  38.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  39.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,190, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  40.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  41.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  42.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  43.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  44.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  45.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  46.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  47.     (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
  48.  
  49.  
  50. type
  51.  
  52.   TSinglePoint = record
  53.     x, y: single;
  54.   end;
  55.  
  56.   linedata = record
  57.     P: Tsinglepoint;
  58.     color: byte;
  59.   end;
  60.  
  61. var
  62.   x, y: integer;
  63.   r, c: integer;
  64.   b: array[0..MAXCOL, 0..MAXCOL] of linedata;
  65.   gmode, gdriver: smallint;
  66.  
  67.  
  68.   procedure rotatepoint(var P: Tsinglepoint; degrees, centerx, centerY: float);
  69.   var
  70.     rr: integer;
  71.     w, d, newx, newy, angle: float;
  72.     cx, cy, y, x: single;
  73.   begin
  74.     angle := degTorad(degrees);
  75.     cx := centerx;
  76.     cy := centery;
  77.     x := p.x;
  78.     y := p.y;
  79.     x := x - cx;
  80.     Y := y - cy;
  81.     newx := (x * cos(angle)) - (y * sin(angle));
  82.     newy := (x * sin(angle)) + (y * cos(angle));
  83.     newx := newx + cx;
  84.     newy := newy + cy;
  85.     p.x := newx;
  86.     p.y := newy;
  87.   end;
  88.  
  89.  
  90.  
  91. begin
  92.   clrscr;
  93.   gdriver := vesa;
  94.   Gmode := installusermode(640,480, 256, 1, 8000, 6000);
  95.   WindowTitle := 'Rotation';
  96.   initgraph(gdriver, gmode, '');
  97. // display the original while assigning x,y locations
  98.   y := 200;
  99.   for r := 0 to MAXCOL do
  100.   begin
  101.     x := 200;
  102.     for c := 0 to MAXCOL do
  103.     begin
  104.       b[r, c].color := bluenorth[r, c];
  105.       b[r, c].p.x := x + c;
  106.       b[r, c].p.y := y + r;
  107.       putpixel(round(b[r, c].p.x), round(b[r, c].p.y), b[r, c].color);
  108.     end;
  109.   end;
  110.  
  111. // rotate and display in new location
  112.   for r := 0 to MAXCOL do
  113.   begin
  114.     for c := 0 to MAXCOL do
  115.     begin
  116. // rotate 80 degrees
  117.       rotatepoint(b[r, c].p, 80, 200, 200);
  118.       putpixel(round(b[r, c].p.x) + 100, round(b[r, c].p.y), b[r, c].color);
  119.     end;
  120.   end;
  121.  
  122.   readkey;
  123.  
  124.   closegraph;
  125. end.                  
  126.  
  127.  
  128.  
« Last Edit: March 23, 2025, 02:05:04 pm by TBMan »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12142
  • FPC developer.
Re: Rotating a simple bitmap matrix
« Reply #1 on: March 23, 2025, 11:50:07 am »
(Doing 90 or 270 in speedy way is also a bit more complicated).  180 is not a rotation but just flipping a boolean that changes the way of traversing the pixel data from bottomup to topdown.

 

TinyPortal © 2005-2018