![]() |
|
|
#1
|
|||
|
|||
|
Всем привет! Пытаюсь написать программу, тема ООП, нужно нарисовать сектор и дугу окружности, чтобы при нажатии клавиш эти фигуры вращались вокруг оси на некоторый угол. Не могу понять, как это осуществить, нашла формулы для поворота сектора и с помощью команды rotate пробую описать поворот, но при нажатии клавиш ничего не происходит, помогите, исправьте,пожалуйста, что не так
|
|
#2
|
|||
|
|||
|
А вокруг какой оси вращаться то должно все это?
Вокруг центра базовой окружности? Или вокруг произвольной точки? |
|
#3
|
|||
|
|||
|
Цитата:
|
|
#4
|
||||
|
||||
|
SetWorldTransform. Примеров по вращению навалом в интернете.
|
|
#5
|
|||
|
|||
|
Цитата:
Походу, нафих не нужно. Если вращение идет вокруг базовой окружности, то достаточно просто посчитать угол и ПЕРЕРИСОВАТЬ картинку. Примерно так: Код:
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 этого модуля. Последний раз редактировалось lmikle, 18.04.2017 в 01:39. |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Lishen (18.04.2017)
| ||
|
#6
|
|||
|
|||
|
Спасибо большое за помощь
|