user1658296
user1658296

Reputation: 1418

Rotate an image about its centre on a GPU

Assume an image I of dimension (2, 2). Graphical coordinates C are given as:

C = [[0, 0], [1, 0],
     [0, 1], [1, 1]]

Objective: rotate I by 90 degrees about the centre (NOT the origin).

Transformation Matrix:

TRotate(90) = [[0, 1], [-1, 0]]

(Assume each coordinate pair can be transformed in lockstep (i.e. on a GPU).)

Method:

  1. Convert graphical coordinates to mathematical coordinates with the origin as the centre of the image.
  2. Apply the transformation matrix.
  3. Convert back to graphical coordinates.

E.g.:

Convert to graphical coordinates:

tx' = tx - width /2

ty' = ty - width /2

C' =[[-1, -1], [0, -1],
     [-1, 0], [0, 0]]

Apply the transformation matrix:

C" = [[-1, 1], [-1, -0],
      [0, 1], [0, 0]]

Convert back:

C" = [[0, 2], [0, 1],
      [1, 2], [1, 1]]

the conversion back is out of bounds...

I'm really battling to get a proper rotation about a 'centre of gravity' working. I think that my conversion to 'mathematical coordinates is wrong'.

I had better luck by rather converting the coordinates into the following:

C' =[[-1, -1], [1, -1],
     [-1, 1], [1, 1]]

I achieved this transformation by observing that if the origin existed in between the four pixels, with the +ve y-axis pointing down, and the +ve x-axis to the right, then the point (0,0) would be (-1, -1) and so on for the rest. (The resultant rotation and conversion give the desired result).

However, I can't find the right kind of transform to apply to the coordinates to place the origin at the centre. I've tried a transformation matrix using homogenous coordinates but this does not work.

Edit

For Malcolm's advice:

position vector =

[0
 0
 1]

Translate by subtracting width/2 == 1:

[-1
 -1
 0]

Rotate by multiplying the transformation matrix:

|-1|   | 0 1 0|   |-1|
|-1| X |-1 0 0| = | 1|
|0 |   | 0 0 1|   | 0|

Upvotes: 0

Views: 695

Answers (1)

Malcolm McLean
Malcolm McLean

Reputation: 6404

You need an extra row in your matrix, for translation by x and translation by y. You then add an extra column to your position vector, call it w, which is hard-coded to 1. This is a trick to ensure that the translation can be performed with standard matrix multiplication.

Since you need a translation followed by a rotation, you need to set up the translation matrix, then do a multiplication by the rotation matrix (make them both 3x3s with the last column ignored if you're shaky on matrix multiplication). So the translations and rotations will be interweaved with each other.

Upvotes: 1

Related Questions