矩阵旋转一个角度, 会关联到 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;
观察一个点的旋转效果(从蓝色旋转 90 度到红色):
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;