
Comments and Discussions





hi my dear
tanx for source code very nice
roza





Great problem solving analysis.





Change your code for testing for speed perfomance... Set rotate event on trackbar scrolling... Image was 1280x1024 resolution... work very slow! Is it real to make rotate more fast?





Its not code its GDI and thats normal. If you want fast rotation by your Trackbar you have to reduce the drawing quality and when you get required rotation you can draw with good quality.
You can use following code to set the quality to lower and speed will be high.
g.CompositingQuality= CompositingQuality.HighSpeed;
g.SmoothingMode = SmoothingMode.HighSpeed;
TVMU^P[[IGIOQHG^JSH`A#@`RFJ\c^JPL>;"[,*/+&WLEZGc`AFXc!L
%^]*IRXD#@GKCQ`R\^SF_WcHbORY87֦ʻ6ϣN8ȤBcRAV\Z^&SU~%CSWQ@#2
W_AD`EPABIKRDFVS)EVLQK)JKQUFK[M`UKs*$GwU#QDXBER@CBN%
R0~53%eYrd8mt^7Z6]iTF+(EWfJ9zaKiTV.C\y<pjxsgb$f4ia>

128 bit encrypted signature, crack if you can





Any comments or ideas on this are most welcome
Public Shared Function RotateImage(ByVal image As Bitmap, ByVal angle As Single) As Bitmap
Dim matrix As New Matrix()
matrix.Rotate(angle)
Dim bitmap As New Bitmap(image.Width, image.Height)
bitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution)
Dim graphics As Graphics = graphics.FromImage(bitmap)
graphics.Transform = matrix
graphics.DrawImage(image, New PointF(0, 0))
graphics.Dispose()
matrix.Dispose()
Return bitmap
End Function





I have rotated the image but the output image is of low quality
i have tried bicubic method
smothing etc.But still no improvement





Thanks for this excellent Article.
Two additional annotations:
For rotating in 90 degree steps Image.RotateFlip() may be easier to use.
For C# 3.0 you may use a extension method like:
public static Bitmap Rotate(this Image image, float angle)
{
..
}
thanks!
Tobias





How could you add to your program a saving patern. Like beeing able to save as a new file the modification that you have done. Also, a way to automate the whole process ( I have to take an image and save it multiple times but each time with +X degree. Nice software tho really usefull to learn!





Thanks for this, works perfectly.





I have a text line that each word in this line must be rotated with different angles. I calculated the coordinates of four corners of each word before and after rotation but I do not know how to do it for each pixel? which interpolation is the best for this purpose? ( bilinear, nearest neighbour or bicubic)? my image is binary.
I am writing my codes in VC++ v.8 and I am a bit new in this area.
Thank you





When i rotated the image ,i found the image became much more blur.
Could anyone fix it?





I went in and tuned this persons code so now the image rotation is perfect from i can see. Their was some calls to Math.Cieling in original code, and uses of int when float was acceptable, etc that just messed up the image... so after i fixed all that, the code works really perfectly now :P
In my program, i let the user rotate a image by dragging on a progressbar... so i do low quality rotations and when user releases mouse button, it does one high quality... that's just some advice for people that need a performance boost :P
public static Bitmap RotateImage(Image image, double angle, bool highDetail)
{
if (image == null)
throw new ArgumentNullException("image");
const double pi2 = Math.PI / 2.0D;
double oldWidth = (double)image.Width;
double oldHeight = (double)image.Height;
double theta = angle * Math.PI / 180.0D;
double locked_theta = theta;
while (locked_theta < 0.0D)
locked_theta += 2.0D * Math.PI;
double newWidth, newHeight;
int nWidth, nHeight;
#region Explaination of the calculations
#endregion
double adjacentTop, oppositeTop;
double adjacentBottom, oppositeBottom;
if ((locked_theta >= 0.0D && locked_theta < pi2) 
(locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)))
{
adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
}
else
{
adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
}
newWidth = adjacentTop + oppositeBottom;
newHeight = adjacentBottom + oppositeTop;
nWidth = (int)newWidth;
nHeight = (int)newHeight;
Bitmap rotatedBmp = new Bitmap(nWidth, nHeight);
using (Graphics g = Graphics.FromImage(rotatedBmp))
{
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
if (highDetail)
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
}
else
{
g.SmoothingMode = SmoothingMode.None;
g.InterpolationMode = InterpolationMode.Low;
}
PointF[] points;
if (locked_theta >= 0.0D && locked_theta < pi2)
{
points = new PointF[] {
new PointF( (float)oppositeBottom, 0.0F ),
new PointF( (float)newWidth, (float)oppositeTop ),
new PointF( 0.0F, (float) adjacentBottom )
};
}
else if (locked_theta >= pi2 && locked_theta < Math.PI)
{
points = new PointF[] {
new PointF( (float)newWidth, (float) oppositeTop ),
new PointF( (float) adjacentTop, (float)newHeight ),
new PointF( (float) oppositeBottom, 0.0F )
};
}
else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))
{
points = new PointF[] {
new PointF( (float) adjacentTop, (float)newHeight ),
new PointF( 0.0F, (float) adjacentBottom ),
new PointF( (float)newWidth, (float)oppositeTop )
};
}
else
{
points = new PointF[] {
new PointF( 0.0F, (float) adjacentBottom ),
new PointF( (float) oppositeBottom, 0.0F ),
new PointF( (float) adjacentTop, (float)newHeight )
};
}
g.DrawImage(image, points);
}
return rotatedBmp;
}





I noticed in your example and in the other examples from the comments that the top and left sides of the rotated imaged don't get antialiased like the right and bottom edges do. Anyone found a solution for that??
Isaac Nicolay





I figured out a solution by talking to the author of the article, in your rotation function before you start the rotation, if you put a 1 pixel edge on the top and left sides of the image like:
Bitmap bit = new Bitmap(image.Width + 1, image.Height + 1);
Graphics gr = Graphics.FromImage(bit);
gr.Clear(Color.White);
gr.DrawImage(image, new Point(1, 1));
image = (System.Drawing.Image)bit;
it will antialias correclty. I chose white because I am showing it on a white background on a webpage. I would guess you should be able to use Color.Transparent if you are using it in a windows form or if you are doing a gif file.
Isaac Nicolay





I found this piece of Code very helpful too. Here is the VB.NET version of the main Function: RotateImage. Note that i inserted a line: g.Clear(Color.White) to solve the problem of extra black regions outside the image area (i think this will not be the problem for some situations).
Public Function RotateImage(ByVal image As Image, ByVal angle As Single) As Drawing.Bitmap If image Is Nothing Then Throw New ArgumentNullException("image") End If
Dim pi2 As Single = Math.PI / 2.0 Dim oldWidth As Single = image.Width Dim oldHeight As Single = image.Height
'Convert degrees to radians Dim theta As Single = angle * Math.PI / 180.0 Dim locked_theta As Single = theta
' Ensure theta is now [0, 2pi) If locked_theta < 0.0 Then locked_theta += 2 * Math.PI
Dim newWidth, newHeight As Single Dim nWidth, nHeight As Integer
Dim adjacentTop, oppositeTop As Single Dim adjacentBottom, oppositeBottom As Single
If (locked_theta >= 0.0 And locked_theta < pi2) Or _ (locked_theta >= Math.PI And locked_theta < (Math.PI + pi2)) Then adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth
adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight Else adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight
adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth End If
newWidth = adjacentTop + oppositeBottom newHeight = adjacentBottom + oppositeTop
nWidth = Int(Math.Ceiling(newWidth)) nHeight = Int(Math.Ceiling(newHeight))
Dim rotatedBmp As New Drawing.Bitmap(nWidth, nHeight)
Dim g As Graphics = Graphics.FromImage(rotatedBmp)
g.Clear(Color.White)
'// This array will be used to pass in the three points that '// make up the rotated image Dim points(2) As Point
If (locked_theta >= 0.0 And locked_theta < pi2) Then
points(0) = New Point(Int(oppositeBottom), 0) points(1) = New Point(nWidth, Int(oppositeTop)) points(2) = New Point(0, Int(adjacentBottom))
ElseIf locked_theta >= pi2 And locked_theta < Math.PI Then
points(0) = New Point(nWidth, Int(oppositeTop)) points(1) = New Point(Int(adjacentTop), nHeight) points(2) = New Point(Int(oppositeBottom), 0)
ElseIf locked_theta >= Math.PI And locked_theta < (Math.PI + pi2) Then
points(0) = New Point(Int(adjacentTop), nHeight) points(1) = New Point(0, Int(adjacentBottom)) points(2) = New Point(nWidth, Int(oppositeTop))
Else
points(0) = New Point(0, Int(adjacentBottom)) points(1) = New Point(Int(oppositeBottom), 0) points(2) = New Point(Int(adjacentTop), nHeight) End If
g.DrawImage(image, points)
g.Dispose() image.Dispose()
Return rotatedBmp
End Function





Public Sub Rotate(ByRef imgSrc As Image, ByVal Angle As Single, ByVal BackColor As Color)
Dim dA As Double
Dim iPointsX(3) As Integer
Dim iPointsY(3) As Integer
Dim dR As Double = 0.5 * Math.Sqrt(Math.Pow(imgSrc.Height, 2) + Math.Pow(imgSrc.Width, 2))
Dim dAngleRad As Double = Math.PI * Angle / 180
Dim iK As Integer = 1
For I As Integer = 1 To 4
dA = Math.PI * (I \ 3) + iK * Math.Atan(imgSrc.Height / imgSrc.Width)
iPointsX(I  1) = dR * Math.Cos(dAngleRad + dA) + imgSrc.Width * 0.5
iPointsY(I  1) = dR * Math.Sin(dAngleRad + dA) + imgSrc.Height * 0.5
iK *= 1
Next
Dim pts() As Point = {New Point(iPointsX(3), iPointsY(3)), New Point(iPointsX(0), iPointsY(0)), New Point(iPointsX(2), iPointsY(2))}
Array.Sort(iPointsX)
Array.Sort(iPointsY)
Dim imgNew As Bitmap = New Bitmap(iPointsX(3)  iPointsX(0), iPointsY(3)  iPointsY(0))
Dim graSrc As Graphics = Graphics.FromImage(imgNew)
graSrc.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
graSrc.Clear(BackColor)
For I As Integer = 0 To 2
pts(I).X = iPointsX(0)
pts(I).Y = iPointsY(0)
Next
graSrc.DrawImage(imgSrc, pts)
graSrc.Dispose()
imgSrc = imgNew
End Sub





I tried to do the same thing myself but it is rotating and getting smaller oO
then i tried the two vb.net codes here and a get the same thing....
what can i do that the images is rotating and keeping its size...
i'm using Visual Studio 2010 Ultimate





Why not transform the points of the bounds of the image directly using the matrix? The resulting min/max values will form the new bounds... (ignore the generic function at the bottom, I just use it to get the min/max values out of a series of parameters).
private static Rectangle GetRotatedBounds(Bitmap bmp, Point rotationCenter, float angle) { // Create rotation matrix Matrix newMatrix = new Matrix(); newMatrix.RotateAt(angle, rotationCenter);
// Get bounds of the original unrotated image Rectangle bmpBounds = new Rectangle(new Point(0, 0), new Size(bmp.Width, bmp.Height));
// Construct rectangle with these bounds Point[] points = { new Point(bmpBounds.Left, bmpBounds.Top), new Point(bmpBounds.Right, bmpBounds.Top), new Point(bmpBounds.Right, bmpBounds.Bottom), new Point(bmpBounds.Left, bmpBounds.Bottom)};
// Rotate the points of the bounds newMatrix.TransformPoints(points);
// Get min/max values of the new bounds int maxX = BinaryReduce<int>(Math.Max, points[0].X, points[1].X, points[2].X, points[3].X); int minX = BinaryReduce<int>(Math.Min, points[0].X, points[1].X, points[2].X, points[3].X);
int maxY = BinaryReduce<int>(Math.Max, points[0].Y, points[1].Y, points[2].Y, points[3].Y); int minY = BinaryReduce<int>(Math.Min, points[0].Y, points[1].Y, points[2].Y, points[3].Y);
// Return resulting bounding rectangle return new Rectangle(new Point(minX, minY), new Size(maxX  minX, maxY  minY)); }
private delegate T BinaryFunction<T>(T a, T b);
private static T BinaryReduce<T>(BinaryFunction<T> function, params T[] values) { if (values.Length == 0) return default(T);
if(values.Length == 1) return values[0];
T result = values[0]; for(int i = 1; i < values.Length; i++) result = function(result, values[i]);
return result; }
This works well for me...
You can easily modify my code to get the boundaries of any rotated shape if you pass the pointsarray into the GetRotatedBounds as well instead of getting them from the image.





I really liked this approach to rotating an image using DrawImage. However I think you might have overcomplicated it a bit. You in fact only need to take the starting 3 points, rotate them about the centre, then draw the image between the rotated points
private static Bitmap AlternativeRotateImage( Image image, double angle )
{
/* From MSDN spec
* The destPoints parameter specifies three points of a parallelogram.
* The three PointF structures represent the upperleft, upperright,
* and lowerleft corners of the parallelogram
* */
Bitmap rotatedImage = new Bitmap( image.Width, image.Height );
PointF[] points = new PointF[3];
double radAngle = ( angle * Math.PI ) / 180;
double sin = Math.Sin( radAngle );
double cos = Math.Cos( radAngle );
double halfWidth = image.Width / 2;
double halfHeight = image.Height / 2;
double cosWidth = cos * halfWidth;
double cosHeight = cos * halfHeight;
double sinWidth = sin * halfWidth;
double sinHeight = sin * halfHeight;
points[ 0 ] = new PointF
(
(float)( halfWidth  cosWidth + sinHeight ),
(float)( halfHeight  cosHeight  sinWidth )
);
points[ 1 ] = new PointF
(
(float)( halfWidth + cosWidth + sinHeight ),
(float)( halfHeight  cosHeight + sinWidth )
);
points[ 2 ] = new PointF
(
(float)( halfWidth  cosWidth  sinHeight ),
(float)( halfHeight + cosHeight  sinWidth )
);
Graphics rotatedImageGraphics = Graphics.FromImage( rotatedImage );
rotatedImageGraphics.DrawImage( image, points );
return rotatedImage;
}





Did you test your alternative code?
Try to rotate an image by 30 degrees and see the image edges cropped off. Your code doesn't get the right image bounds.:>





Im rotating pics for a game and the use magenta (255,0,255) for transparent but as the image gets antialised it shows up with magenta borders (as theyre not perfectly magenta)
I tried with
g.SmoothingMode = SmoothingMode.None;
but the result is the same
 thomasa88





I like your article and it lead me in the direction I needed. I reworked your code so that my weak trig skills don't slow me down. I also decided to flip the Bitmap onto an new one and keep a copy of the old one for future rotations. You may want to take a look at your Graphics device. I don't think you call dispose() after you are done with it.
Have you found a way to AntiAlias the sides during the redraw?
public static Bitmap RotateImage2(Bitmap bmp, float angle)
{
Bitmap retbmp = null;
Point[] pts = new Point[]
{
new Point(0, 0),
new Point(bmp.Width, 0),
new Point(bmp.Width, bmp.Height),
new Point(0, bmp.Height)
};
for (int i = 0; i < 4; i++)
{
pts[i].X = bmp.Width / 2;
pts[i].Y = bmp.Height / 2;
}
Matrix m = new Matrix();
m.Rotate(angle);
m.TransformPoints(pts);
m.Dispose();
int maxX = int.MinValue;
int maxY = int.MinValue;
int minX = int.MaxValue;
int minY = int.MaxValue;
for (int i = 0; i < 4; i++)
{
if (maxX < pts[i].X) maxX = pts[i].X;
if (maxY < pts[i].Y) maxY = pts[i].Y;
if (minX > pts[i].X) minX = pts[i].X;
if (minY > pts[i].Y) minY = pts[i].Y;
}
for (int i = 0; i < 4; i++)
{
pts[i].X = minX;
pts[i].Y = minY;
}
retbmp = new Bitmap(maxX  minX, maxY  minY, PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage(retbmp);
Point[] finalPts = new Point[] { pts[0], pts[1], pts[3] };
g.DrawImage(bmp, finalPts);
g.Dispose();
return retbmp;
}





He did dispose of the Graphics object, with the using(Graphics g = Graphics.FromImage(rotatedBmp)) code block, that automatically calls Dispose() on the object inside the using() brackets.





Great stuff, I like this because it also handles negative angles





Hi there...
Good work, but when I'm using it i'm having problem that after rotation i get a black edges, i mean like the empty space is filled with black, any solution to this problem urgently please...
Aws
Aws Al Attar






If you do g.Clear(Color.White); on the line right after Graphics g = Graphics.FromImage(retbmp); you can set the background to whatever color you want!
Isaac Nicolay





Thank You Very Much i am trying this one from so many days.Now it's looking so simple.Thank u again.
Kranthi





Hi James,
I was trying to create a label of Image size but not succeeded. I need a label where I can rotate the Image and after rotation Label should also change the size with respect to image points.
Thanks,
Chandra Prakash





This is all needed in VB.Net to calculate perfect rectangle for all rotations:
Dim sin As Double = Math.Abs(Math.Sin(de_ra(rotation)))
Dim cos As Double = Math.Abs(Math.Cos(de_ra(rotation)))
wid = sin * img.Height + cos * img.Width
hei = sin * img.Width + cos * img.Height
(de_ra is function to convert degrees to radians)
And these three lines of code to place image:
g.RotateTransform(rotation)
g.TranslateTransform(bmp.Width \ 2, bmp.Height \ 2, Drawing2D.MatrixOrder.Append)
g.DrawImage(img, img.Width \ 2, img.Height \ 2)
See complete function at http://johnharald.net/pml/rotatePSC.html[^]
or http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=3510&lngWId=10[^]





Thanks, the full source has crop, which was my issue...
Schneider





Nice work there. You'll need to add this line just after the declaration of the "bmp" variable.
bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution)






I am also finding the same thing but could not find solution yet. here are few of my findings
1 Convert text into Image
2 then rotate image
But there are number of if and buts in it





How can we handle this for windows CE or PPC? As you know there are lots
of limitations for image and bitmap objects. I m trying to do this with a faster algorithm but i can not found any now.
Tayfun (Architect)





Simply put, doing a simple imagine rotation should just be as simple as transposing the X,Y coords in the original image to Y,X in the rotated copy. I can't recall if that rotates right or left but the other direction is (MaxY  Y),(maxX  X).
Just loop over the scanlines in the original image and write into a new Bitmap in tranposed coordinates. This works for the 90deg rotations.
If you still want this degree rotation, then you will have to a calculation intensive pattern like this. There is little that can be done to speed up trig.





below i have written a routine which rotates the given bitmap with a specified angle
public static Bitmap RotateImage(Bitmap image,double angle)
{
int ow = image.Width;
int oh = image.Height;
Point oldMiddle = new Point(ow/2,oh/2);
int newSize = (int)Pythagoras(ow,oh);
Point newMiddle = new Point(newSize/2,newSize/2);
Bitmap newBitmap = new Bitmap(newSize,newSize);
Graphics g = Graphics.FromImage(newBitmap);
double nx,ny;
double pixelDist;
double bearing;
for (int x = 0; x < ow; x++)
{
for (int y = 0; y < oh ; y++)
{
Color c = image.GetPixel(x,y);
pixelDist = Pythagoras(oldMiddle.Xx,oldMiddle.Yy);
/* Pythagoras calculates the sqrt of sqr(param1)+sqr(param2)
bearing = BearingBetween(oldMiddle,new Point(x,y));
/* BearingBetween calculates the angle of the line from Point1 to point2
bearing = bearing + angle;
bearing = 360  bearing + 90;
/* I have done this for compass scaling
nx = newMiddle.X + pixelDist*Math.Cos(DegToRad(bearing));
ny = newMiddle.Y  pixelDist*Math.Sin(DegToRad(bearing));
newBitmap.SetPixel((int)nx, (int)ny,c);
}
}
return newBitmap;
}
this is not an optimal solution. Image boundaries gets larger and the rotated image is distorted why i did not understand. Also it will be slow for large images. Is there anybody who can handle with image distortion?
Tayfun YAĞCI





For Smart Device Application C# does not have the following
Graphics.DrawImage(image,points)
Graphics.Transform
Drawing2D.Matrix
Graphics.Rotate ... etc.
As far as i know we have only
Bitmap.Set(Get)Pixel(x,y)
Grahics.DrawImage(Image,....Some Parameters not relevant to rotation or transposing ...) " We can zoom it but is it important ? "





Thank you so much for such a good example. I'm appreciated your good work. Hope you will have more excellent about GDI+ examples in the future.





Your algoritm may work for rectangles, but I've seen the algorithms for any path and it gets increasingly complex. Fortunately, Microsoft packed a lot of functionality into System.Drawing.Drawing2D.GraphicsPath() . After you transform your Image with a matrix, you should get a series of points or other coordinates. Using these, you can construct a new GraphicsPath and call GraphicsPath.GetBounds() to find the bounding rectangle that encloses all points. There's a lot more it can do, too, and I've found it very handy in many situations.
"Well, I wouldn't say I've been missing it, Bob."  Peter Gibbons





In the old days of the Demoscene we called this technique a rotozoomer, where you conputed a rotation of the visible portion of the screen projected on the image and read all pixels from the image buffer along the scanlines of that rotated/projected screenframe into a new buffer. You then could rotate and zoom into the image, even add rubber effects, without much hassle. The routine is quite simple actually. I wrote this a few years back in java:
http://www.xs4all.nl/~perseus/zoom/zoom.html[^]
which is easily portable to .NET, the only difficulty is the reading of raw pixeldata from the image and the creation of a new image from the newly constructed imagedata (which is stored in an array). The sourcecode is downloadable from the link mentioned above. I'll give it a shot to port it to .NET some day, but perhaps someone can include the logic used there into the code of this article

Only the true wise understand the difference between knowledge and wisdom.





No, this example is different. But yours looks very interesting!
To do that in GDI+ you would probably lock the pixels and use unsafe code. I have heard that GetPixel is too slow for much of anything.
With GDI+ calls you can only do basic affine transforms of images (rotate, scale, translate), I think.
regards,
Frank Hileman





Yeah GetPixel is slow, it's also slow in java, that's why you first transform all pixels to longs (ARGB or RBGA or similar, 1 byte per colorfragment) and you simply read longs from array 1 into array 2. (like in the old days polyfillers were programmed :P) I haven't seen a decent 'image2pixelarray' function but it has to be there. Does anyone know such a function in .NET?

Only the true wise understand the difference between knowledge and wisdom.






thanks! thats indeed how to do it It's however unsafe code, but for a little routine for just a bit of fun it shouldn't matter much :P

Only the true wise understand the difference between knowledge and wisdom.





To rotate a shape (image or anything else) about its center: first translate (move) it such that the center is on 0,0 (origin), then rotate, then translate back to original location by applying the opposite of the first translation. Simpler and you can create a single matrix to do it all in one step.
if
v = vector from origin to center
then order of operations is
v rotate +v





I assumed this is what James is doing ???
Christian
No offense, but I don't really want to encourage the creation of another VB developer.  Larry Antram 22 Oct 2002
C# will attract all comers, where VB is for IT Journalists and managers  Michael P Butler 05122002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not as easily, but it's certainly doable.  Jamie Nordmeyer  15Nov2002





Perhaps in a roundabout way? Actually, RotateAt does exactly what I stated, so I don't understand why he did not use it. If you compute the center point of the image (easy enough, since it is a rectangle), you just do RotateAt with the center point. Internally that composes a matrix the way I described. From msdn, an example of RotateAt (but not about center):
public void RotateAtExample(PaintEventArgs e)
{
Pen myPen = new Pen(Color.Blue, 1);
Pen myPen2 = new Pen(Color.Red, 1);
PointF rotatePoint = new PointF(150.0f, 50.0f);
// Draw the rectangle to the screen before applying the
// transform.
e.Graphics.DrawRectangle(myPen, 150, 50, 200, 100);
// Create a matrix and rotate it 45 degrees.
Matrix myMatrix = new Matrix();
myMatrix.RotateAt(45, rotatePoint, MatrixOrder.Append);
// Draw the rectangle to the screen again after applying the
// transform.
e.Graphics.Transform = myMatrix;
e.Graphics.DrawRectangle(myPen2, 150, 50, 200, 100);
}







General News Suggestion Question Bug Answer Joke Rant Admin Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

