Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.05.2022, 23:24   #1
Катя93
Пользователь
 
Регистрация: 11.01.2021
Сообщений: 48
По умолчанию Как сделать так чтобы от верхней позиции по таймеру очерчивалась окружность Arc?

Я точно не знаю как работает Arc пыталась сделать собственными силами, чтобы начиная от верхнее точки линия чертилась плавно по окружности (для этого я использовала timer).
Т.е. изначально окружности нет она должна вычерчиваться программно.

Пример на рисунке, что пытаюсь сделать.
img1.jpg
В итоге окружность двигается.
1. Не с точки старта как хотелось бы
2. Не в то направление
3. Слишком быстро
Как исправить, вот мой код?
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls,Math, StdCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Timer1: TTimer;
    Button1: TButton;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  deegres:Integer = 0;
  angle:Integer = 0;
  PrevX:Integer = 0;
  PrevY:Integer = 0;
  R:Integer = 100;

implementation

{$R *.dfm}



procedure TForm1.Timer1Timer(Sender: TObject);
var
 i1, i2 : Integer;
 f0     : Single;
 X,Y,W,H:Integer;

begin
X:= 120;
Y:= 120;
W:=X+90;
H:=Y+90;

f0 := Sqrt(Sqr(W) +Sqr(H));

i1 := (X +(W div 2));
i2 := (Y +(H div 2));

Image1.Canvas.Pen.Color := clWhite;
Image1.Canvas.Brush.Color := clWhite;
Image1.Canvas.Pen.Color := $808080;
Image1.Canvas.Brush.Color := $808080;
deegres := deegres+1;

Image1.Canvas.Arc(X,Y,W,H,
   Round(Cos(-deegres)*f0 +i1),
   Round(Sin(-deegres)*f0 +i2),
   Round(Cos(-deegres+2)*f0 +i1),
   Round(Sin(-deegres+2)*f0 +i2));

end;




end.
Катя93 вне форума Ответить с цитированием
Старый 07.05.2022, 23:54   #2
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

В таймере лучше просто увеличивать переменную обозначающую прирост окружности и вызывать перерисовку окна.
А все рисование производить в OnPaint.
Код:
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private

  public
    ArcX: Integer;
    ArcY: Integer;
    ArcW: Integer;
    ArcH: Integer;
    ArcA: Integer;
  end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  ArcX := 10;
  ArcY := 10;
  ArcW := 100;
  ArcH := 100;
  ArcA := 0;
  Timer1.Interval := 10;
  Timer1.Enabled := True;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  ArcCX, ArcCY, ArcR1, ArcR2: Integer;
  ArcR: Double;
begin
  if ArcA > 5 then begin // 16 = 1 градус
    ArcR1 := ArcW div 2;
    ArcR2 := ArcH div 2;
    ArcCX := ArcX + ArcR1;
    ArcCY := ArcY + ArcR2;
    ArcR  := ( 2 * pi() * ArcA ) / ( 16 * 360 ) - pi();
    Form1.Canvas.Arc(ArcX,                             ArcY,
                     ArcX + ArcW,                      ArcY + ArcH,
                     ArcCX - Round(ArcR1 * sin(ArcR)), ArcCY + Round(ArcR2 * cos(ArcR)),
                     ArcCX,                            ArcY);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (ArcA < 16 * 360) then begin
    inc(ArcA);
    Form1.Repaint;
  end else Timer1.Enabled := False; // или ArcA := 0; для зацикливания
end;
ADD: Забыл про значения в таймере. Для ускорения увеличивайте приращение инкремента. Например: inc(ArcA, 10);

Последний раз редактировалось macomics; 08.05.2022 в 00:29.
macomics вне форума Ответить с цитированием
Старый 08.05.2022, 03:41   #3
Катя93
Пользователь
 
Регистрация: 11.01.2021
Сообщений: 48
По умолчанию

Спасибо работает, а как сделать наоборот, что когда круг(arc) заполнен,чтобы он уменьшался. Пример.
img1.jpg
Катя93 вне форума Ответить с цитированием
Старый 08.05.2022, 04:09   #4
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Код:
  if ( ArcA > 5 ) and (ArcA <= 360 * 16) then begin // заполнение
...
    Form1.Canvas.Arc(ArcX,                             ArcY,
                     ArcX + ArcW,                      ArcY + ArcH,
                     ArcCX - Round(ArcR1 * sin(ArcR)), ArcCY + Round(ArcR2 * cos(ArcR)),
                     ArcCX,                            ArcY); // Эти два параметра поменять с двумя предыдущими местами
  end else if (ArcA > 360 * 16) then begin // стирание
...
    ArcR = (2 * pi() * ( ArcA - 360 * 16 ) / ( 360 * 16 )) - pi();  // -pi .. pi
    Form1.Canvas.Arc(ArcX,                             ArcY,
                     ArcX + ArcW,                      ArcY + ArcH,
                     ArcCX,                            ArcY, // Эти два параметра поменять с двумя предыдущими местами
                     ArcCX - Round(ArcR1 * sin(ArcR)), ArcCY + Round(ArcR2 * cos(ArcR)));
  end;
...
//таймер
if ArcA < 360 * 16 * 2 - 8 then ...

Последний раз редактировалось macomics; 08.05.2022 в 04:31.
macomics вне форума Ответить с цитированием
Старый 08.05.2022, 05:37   #5
Катя93
Пользователь
 
Регистрация: 11.01.2021
Сообщений: 48
По умолчанию

Еще раз спасибо разобралась, выкладываю полностью код:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls,math;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ArcX: Integer;
    ArcY: Integer;
    ArcW: Integer;
    ArcH: Integer;
    ArcA: Integer;
  end;

var
  Form1: TForm1;
  

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ArcX := 10;
  ArcY := 10;
  ArcW := 100;
  ArcH := 100;
  ArcA := 0;
  Timer1.Interval := 33;
  Timer1.Enabled := True;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  ArcCX, ArcCY, ArcR1, ArcR2: Integer;
  ArcR: Double;
begin
 ArcR1 := ArcW div 2;
 ArcR2 := ArcH div 2;
 ArcCX := ArcX + ArcR1;
 ArcCY := ArcY + ArcR2;
if ( ArcA > 5 ) and (ArcA <= 360 * 16) then begin
  ArcR  := ( 2 * pi * ArcA ) / ( 16 * 360 ) - pi;
  Form1.Canvas.Arc(ArcX, ArcY,
                     ArcX + ArcW,ArcY + ArcH,
                     ArcCX, ArcY,
                     ArcCX - Round(ArcR1 * sin(ArcR)), ArcCY + Round(ArcR2 * cos(ArcR)));
  end else if (ArcA > 360 * 16)
  then begin
    ArcR := (2 * pi * ( ArcA - 360 * 16 ) / ( 360 * 16 )) - pi;  // -pi .. pi
    Form1.Canvas.Arc(ArcX,                             ArcY,
                     ArcX + ArcW,                      ArcY + ArcH,
                     ArcCX - Round(ArcR1 * sin(ArcR)), ArcCY + Round(ArcR2 * cos(ArcR)),
                     ArcY, ArcCX);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (ArcA < 16 * 360) then begin
    inc(ArcA,30);
    Form1.Repaint;
  end else
  begin
  Timer1.Enabled := False; 
  end;
end;

end.
Катя93 вне форума Ответить с цитированием
Старый 08.05.2022, 10:23   #6
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от Катя93 Посмотреть сообщение
Код:
  Timer1.Interval := 33;
  Timer1.Enabled := True;
Эти строчки добавлены, чтобы продемонстрировать настройки объекта TTimer в инспекторе объектов. Их можно убрать, но настроить этот компонент соответствующим образом.
Цитата:
Сообщение от Катя93 Посмотреть сообщение
Код:
end else if (ArcA > 360 * 16)
  then begin
Когда координаты точек (SX = EX) and (SY = EY), то отображается целая окружность. Чтобы этого не было, то после стадии стирания стоит убрать кусочек дуги из области рисования, который будет невидимым
Код:
end else if (ArcA > 360 * 16) and (ArcA < 2 * 16 * 360 - 8)
  then begin
именно поэтому начальный участок дуги начинает отрисовку не с 0, а с 5.
Цитата:
Сообщение от Катя93 Посмотреть сообщение
Код:
if ( ArcA > 5 ) and (ArcA <= 360 * 16) then begin
Для замедления работы можно добавить шагов анимации: перейти от 16 * 360 кадров к 60 * 360 или 60 * 60 * 360 кадров. Но последнее слишком медленно, хотя изображает часовую стрелку в соответствии с ходом секундной.

Последний раз редактировалось macomics; 08.05.2022 в 10:41.
macomics вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Минимальное количество шагов шахматного коня, чтобы достигнуть определенной позиции на шахматной доске Programist_r Помощь студентам 1 09.01.2020 19:52
Братья помогите: помогите с кодом VBA чтобы, заполнить диапазон строк названием улицы из верхней строки, до строки с другой улицей vasjaspb Microsoft Office Access 0 08.06.2016 22:17
Как сделать проверку истинности позиции? Андрей Иванов Помощь студентам 0 10.05.2015 15:26
заместить символы так, чтобы ключевое слово начиналось с первой позиции Joistick Паскаль, Turbo Pascal, PascalABC.NET 2 19.06.2013 21:18
как сделать так,чтобы он левой рукой до стены коснулся? и если можно чтобы двери лифта закрылись maxon56 Паскаль, Turbo Pascal, PascalABC.NET 0 07.06.2011 18:46