矩陣旋轉一個角度, 會關聯到 M11、M12、M21、M22 四個數據, 計算公式如下:
┏ ┓
┃ cos(r) sin(r) 0 ┃
┃-sin(r) cos(r) 0 ┃
┃ DX DY 1 ┃
┗ ┛
//其中的 r 不是角度是弧度; 弧度的計算方法是: r = 角度 * Pi / 180.
下面兩段程序對上面的公式進行了對比測試:
//
var
m: IGPMatrix;
begin
m := TGPMatrix.Create;
m.Rotate(90);
ShowMessageFmt('%f %f', [m.Elements.M11, m.Elements.M12]); // 0.00 1.00
ShowMessageFmt('%f %f', [m.Elements.M21, m.Elements.M22]); //-1.00 0.00
m.Reset;
m.Rotate(-30);
ShowMessageFmt('%f %f', [m.Elements.M11, m.Elements.M12]); //0.87 -0.50
ShowMessageFmt('%f %f', [m.Elements.M21, m.Elements.M22]); //0.50 0.87
end;
//
var
r: Single;
M11,M12,M21,M22: Single;
begin
r := 90 * Pi/180;
M11 := Cos(r); M12 := Sin(r);
M21 := -Sin(r); M22 := Cos(r);
ShowMessageFmt('%f %f', [M11, M12]); // 0.00 1.00
ShowMessageFmt('%f %f', [M21, M22]); //-1.00 0.00
r := -30 * Pi/180;
M11 := Cos(r); M12 := Sin(r);
M21 := -Sin(r); M22 := Cos(r);
ShowMessageFmt('%f %f', [M11, M12]); //0.87 -0.50
ShowMessageFmt('%f %f', [M21, M22]); //0.50 0.87
end;
觀察一個點的旋轉效果(從藍色到紅色):
uses GdiPlus;
procedure TForm1.FormPaint(Sender: TObject);
var
Graphics: IGPGraphics;
Pen: IGPPen;
Brush: IGPSolidBrush;
Matrix: IGPMatrix;
i: Integer;
Pt: TGPPointF;
begin
ClIEntWidth := 300;
ClIEntHeight := 200;
Pen := TGPPen.Create($FFE0E0E0);
Brush := TGPSolidBrush.Create($FF0000FF);
Graphics := TGPGraphics.Create(Handle);
//繪制坐標系
Graphics.Clear($FFFFFFFF);
for i := 1 to ClIEntWidth div 10 do
Graphics.DrawLine(Pen, TGPPoint.Create(i*10, 0), TGPPoint.Create(i*10, ClIEntHeight));
for i := 1 to ClIEntHeight div 10 do
Graphics.DrawLine(Pen, TGPPoint.Create(0, i*10), TGPPoint.Create(ClIEntWidth, i*10));
Pen.Color := $FFB0B0B0;
Graphics.DrawLine(Pen, TGPPoint.Create(ClIEntWidth div 2, 0),
TGPPoint.Create(ClientWidth div 2, ClIEntHeight));
Graphics.DrawLine(Pen, TGPPoint.Create(0, ClIEntHeight div 2),
TGPPoint.Create(ClientWidth, ClIEntHeight div 2));
//平移坐標系
Graphics.TranslateTransform(ClientWidth div 2, ClIEntHeight div 2);
Graphics.PixelOffsetMode := PixelOffsetModeHalf;
Graphics.DrawEllipse(Pen, -2, -2, 5, 5);
//假如有個點是 (80, -40), 用藍色繪制此點
Pt.Initialize(80, -40);
Graphics.DrawLine(Pen, TGPPointF.Create(0, 0), Pt);
Graphics.FillRectangle(Brush, Pt.X-2, Pt.Y-2, 5, 5);
//旋轉 90 度, 用紅色重新繪制這個點
Graphics.RotateTransform(90);
Graphics.PixelOffsetMode := PixelOffsetModeHalf;
Brush.Color := $FFFF0000;
Graphics.DrawLine(Pen, TGPPointF.Create(0, 0), Pt);
Graphics.FillRectangle(Brush, Pt.X-2, Pt.Y-2, 5, 5);
end;
旋轉變換 IGPMatrix.Rotate() 或 IGPGraphics.RotateTransform 都有繞著 (0,0) 點的;
IGPMatrix.RotateAt() 可繞指定點旋轉, 如:
uses GdiPlus;
procedure TForm1.FormPaint(Sender: TObject);
var
Graphics: IGPGraphics;
Matrix: IGPMatrix;
Pen: IGPPen;
Rect: TGPRect;
begin
Graphics := TGPGraphics.Create(Handle);
Pen := TGPPen.Create($FFD0D0D0, 2);
Rect.Initialize(50, 30, 80, 80);
Graphics.Clear($FFFFFFFF);
Graphics.DrawRectangle(Pen, Rect);
Matrix := TGPMatrix.Create;
Matrix.RotateAt(45, TGPPointF.Create(Rect.X + Rect.Width/2, Rect.Y + Rect.Height/2));
Graphics.MultiplyTransform(Matrix);
Pen.Color := $80FF0000;
Graphics.DrawRectangle(Pen, Rect);
end;