GdiPlus[48]: IGPMatrix 矩阵(三) 关于矩阵的旋转


矩阵旋转一个角度, 会关联到 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 度到红色):

GdiPlus[48]: IGPMatrix 矩阵(三) 关于矩阵的旋转


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() 可绕指定点旋转, 如:

GdiPlus[48]: IGPMatrix 矩阵(三) 关于矩阵的旋转


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;


 
   

你可能感兴趣的:(Matrix)