17.04.2017, 21:58
|
Модератор
|
|
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
|
|
Цитата:
Сообщение от NumLock
SetWorldTransform. Примеров по вращению навалом в интернете.
|
Походу, нафих не нужно. Если вращение идет вокруг базовой окружности, то достаточно просто посчитать угол и ПЕРЕРИСОВАТЬ картинку.
Примерно так:
Код:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TShapeType = (stArc, stSector);
TCircleShape = class
private
fShapeType : TShapeType; // Type of the shape - arc or sector
fX0, fY0 : Integer; // Center of the circle
fR : Integer; // Radius of the circle
fAA : Integer; // Angle of sector/arc
fAR : Integer; // Angle of rotation, by default = 0
public
constructor Create(X0,Y0,R : Integer; ArcAngle : Integer; ShapeType : TShapeType = stArc);
function ToRadian(Angle : Integer) : Double;
procedure PaintTo(ACanvas : TCanvas); // draw on provided canvas
procedure Rotate(Angle : Integer); // Rotate to the angle
property ShapeType : TShapeType read fShapeType write fShapeType;
end;
TForm1 = class(TForm)
PaintBox1: TPaintBox;
Button1: TButton;
Button2: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
private
{ Private declarations }
FShape : TCircleShape;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{TCircleShape}
constructor TCircleShape.Create(X0,Y0,R : Integer; ArcAngle : Integer; ShapeType : TShapeType = stArc);
begin
fX0 := X0;
fY0 := Y0;
fR := R;
fAA := ArcAngle;
fShapeType := ShapeType;
fAR := 0;
end;
function TCircleShape.ToRadian(Angle : Integer) : Double;
begin
Result := (Angle * 2 * PI) / 360;
end;
procedure TCircleShape.PaintTo(ACanvas : TCanvas); // draw on provided canvas
var
X1, Y1 : Integer;
X2, Y2 : Integer;
begin
X1 := fX0 + Round(fR*Cos(fAR*2*PI/340));
Y1 := fY0 - Round(fR*Sin(fAR*2*PI/340));
X2 := fX0 + Round(fR*Cos((fAR-fAA)*2*PI/340));
Y2 := fY0 - Round(fR*Sin((fAR-fAA)*2*PI/340));
ACanvas.Arc(fX0-fR,fY0-fR,fX0+fR,fY0+fR,X2,Y2,X1,Y1);
If fShapeType = stSector Then
Begin
ACanvas.MoveTo(fX0,fY0);
ACanvas.LineTo(X1,Y1);
ACanvas.MoveTo(fX0,fY0);
ACanvas.LineTo(X2,Y2);
End;
end;
procedure TCircleShape.Rotate(Angle : Integer); // Rotate to the angle
begin
fAR := fAR + Angle;
end;
{TForm1}
procedure TForm1.Button1Click(Sender: TObject);
begin
FShape.Rotate(5);
PaintBox1.Repaint;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FShape.Rotate(-5);
PaintBox1.Repaint;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FShape := TCircleShape.Create(100,100,50,20);
PaintBox1.Repaint;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(FShape);
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.FillRect(Rect(0,0,PaintBox1.Width,PaintBox1.Height));
FShape.PaintTo(PaintBox1.Canvas);
end;
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
If RadioButton1.Checked
Then FShape.ShapeType := stArc
Else FShape.ShapeType := stSector;
PaintBox1.Repaint;
end;
end.
Проект в аттаче.
В принципе, класс можно переместить в отдельный модуль. Он никак не связан с формой, только тогда в форме указать uses этого модуля.
|