How to rotate an image

1. Mar 23, 2005

eNathan

I am using the Delphi language, and I want to learn how to use the Cosine function to rotate an image. Can somebody please explain how and why the math works. I know what cosine is, I just don't know how to use it in any real situations, can somebody please tell me how to do this?

Delphi = VB + C++

2. Mar 23, 2005

gnome

I don't know that you can rotate an image using cosine alone, and I don't know how your image is coded, but maybe you can translate this into something you can use.

Suppose a given point of your image is coded as a row vector [x y], if you want to rotate that point through an angle of $\theta$ radians clockwise about the origin, you can multiply
$$[x \; y] \times \left [ \begin{array}{lr} cos(\theta) \quad &-sin(\theta) \\ sin(\theta) &cos(\theta) \end{array} \right ]$$

to get the new coordinates for that point. For example, the point [1 2] rotated $90^o$ ($\frac{\pi}{2} \, radians$:

$$[ 1\quad 2] \times \left [ \begin{array}{lr} cos(\frac{\pi}{2}) \quad &-sin(\frac{\pi}{2}) \\ sin(\frac{\pi}{2}) &cos(\frac{\pi}{2}) \end{array} \right ] = [2 \;-1]$$

So you can multiply each point of your image by the same matrix and the entire image will be rotated.

3. Mar 23, 2005

eNathan

Sorry for my lack of understanding mathematical signs, but can you make 2 equations (1 for the X, 1 for the Y) that will give the "new" position of each pixel? And from there, I can just loop through every pixel and set its new position on the Bitmap.

thx :)

4. Mar 24, 2005

faust9

Sure, lets say you want to rotate some angle theta then do the following:

x_new=(x_old)*cos(theta)+(y_old)*sin(theta);
y_new=(y_old)*cos(theta)-(x_old)*sin(theta);

5. Mar 24, 2005

eNathan

For i:= 0 to Image1.Width Do
For p:= 0 to Image1.Height do begin
x:=Round((i)*cos(45)+(p)*sin(45));
y:=Round((p)*cos(45)-(i)*sin(45));
SetPixel(GetDC(Image2.Picture.Bitmap.Canvas.Handle), x, y, GetPixel(GetDC(Image1.Picture.Bitmap.Canvas.Handle), i, p))
End;

Well that didn't work :P Thanks for the math though, I am sure I will get it sooner or later :)

6. Mar 24, 2005

gnome

What did the result of that look like? Did you end up with any image at all?

A couple of thoughts: you expressed the angle in degrees. I don't know about Delphi, but I'm guessing you should use radians. Test it by printing the value of cos(45). If you get .707107, fine. If you get .525322, that's a problem. Then you have to use cos(pi/4) to get the cosine of 45 degrees. And you may not have a built-in pi constant. In C++ you could declare
Code (Text):
[b]const double[/b] pi = acos(-1);
Maybe you can do something equivalent in Delphi. Or you can just approximate it with 3.14159.

Also, the image may be rotating off your screen. Are you allowed negative coordinates for the pixels? I'm just starting to learn about this myself, but I think I saw someplace that the origin for the screen is either in the upper left corner (with the positive y-axis pointing down) or the lower left corner (with the positive y-axis going up). There seems to be no place in that system for negative numbers, so you probably have to translate your points laterally and vertically after you rotate them, to get back on the screen.

Does any of that make sense?

7. Mar 24, 2005

eNathan

yes, when I do Cos(45) I get .525322 :( What I see on the screen is nothing, it does not even draw an pixels anywhere. Am I using the SetPixel and GetPixel right? I am pretty sure I am. And in Delphi, the X and Y cords start at the upper left corner of the screen starting with 0, and increasing by +1 for every pixel. And yes, delphi has a built in pi Const. I am going to work with it some more, please respond with any coments.

8. Mar 24, 2005

gnome

As I said, I don't know Delphi so I have no idea how the syntax of SetPixel and GetPixel is supposed to work. But your code looks strange to me: it seems you have an inner loop and an outer loop (which makes sense), but only one begin/end. Is that right?

If you post code, use code tags. Put your code between [co de]put code here[/co de] (without the spaces in "code") to preserve indentation & make it easier to read.

9. Mar 24, 2005

eNathan

You only use the begin statment when it is a "Code block" for isntance

For i:= 1 to 10 do
x:=i;
//There is no need for the "Begin" keyword because there is just one line of code after the for

For i:= 1 to 10 do begin
x:=i;
y:=i*10;
End;
//Because I have 2 lines of code, it is a requirment to use the "Begin" statment.

Anyway, I think the problem is that I am not using the GetPixel and SetPixed API's right. I am going to google for graphics in Delphi and see what I can figure out.

10. Mar 24, 2005

eNathan

You said "Then you have to use cos(pi/4) to get the cosine of 45 degrees." Can you changethe equation to get this?

11. Mar 24, 2005