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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.01.2010, 15:49   #1
Sianessa
Форумчанин
 
Регистрация: 18.01.2009
Сообщений: 144
По умолчанию Delphi: траектория движения круга

Написала программу движения круга (Shape1), но нужно теперь переделать, чтобы она двигалась по кромке экрана, (по границам Image1).

Подскажите пожалуйста, что нужно изменить в уравнениях, чтобы круг двигался по периметру?

Вот код:

Код:
unit Unit1;

interface

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

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

var
  Form1: TForm1;
  xmin,xmax,ymin,ymax,canvasXmax,canvasYmax:integer;// границы отрисовки графика
  kx,ky:double;// коэффициенты для перевода
  x,y:double;//текущие координаты

implementation

{$R *.dfm}
procedure getParams; // считывание параметров с формы
begin
with Form1 do
begin
xmin:=-25;
xmax:=25;
ymin:=-25;
ymax:=25;
canvasXmax:=Form1.Image1.Width;
canvasYmax:=Form1.Image1.Height;
kx:=(xmax-xmin)/canvasXmax;
ky:=(ymax-ymin)/canvasYmax;
end;
end;

function Get_X_px(X_ed:double):integer;// превращаю единицы в пикселы
begin
result:=round(abs(xmin-X_ed)/kx);
end;

function Get_Y_px(Y_ed:double):integer;// превращаю единицы в пикселы
begin
result:=canvasYmax+round((ymin-Y_ed)/ky);
end;

function Get_X_ed(X_px:integer):double; // превращаю пикселы в единицы
begin
result:=X_px*kx+xmin;
end;

function Get_Y_ed(Y_px:integer):double;// превращаю пикселы в единицы
begin
result:=(canvasYmax-Y_px)*ky+ymin;
end;

function f(x:double):double;
begin
  Result:=2*sin(x);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
getParams;
Shape1.Left:=0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Shape1.Left>Image1.Width-17 then
  begin
    Shape1.Left:=0;
  end;

Shape1.Left:=Shape1.Left+1;
x:=Get_X_ed(Shape1.Left);
y:=f(x);
Shape1.Top:=Get_Y_px(y)+round(Image1.Height/2)-Shape1.Left;
end;
end.
Sianessa вне форума Ответить с цитированием
Старый 25.01.2010, 16:06   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А что из себя периметр представляет? Какую фигуру?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.01.2010, 16:09   #3
Sianessa
Форумчанин
 
Регистрация: 18.01.2009
Сообщений: 144
По умолчанию

Stilet квадрат размером 505 х 505
Sianessa вне форума Ответить с цитированием
Старый 25.01.2010, 16:43   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Смотри, я предлагаю тебе изменять направление движения квадрата изменив угол, вот так как в примере:
Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Shape1: TShape;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

 var x,y:integer;ang:double;
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin

 x:=x+round(10*cos(ang));
 y:=y+round(10*sin(ang));
 if (x in [0,200])or(y in [0,200]) then tag:=1;
 if tag=1 then
   ang:=ang+pi/2;
 tag:=0;

 Shape1.Top:=y;
 Shape1.Left:=x;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 x:=0;y:=0;ang:=0;
end;

end.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.01.2010, 16:56   #5
Sianessa
Форумчанин
 
Регистрация: 18.01.2009
Сообщений: 144
По умолчанию

Stilet, у меня ваш пример вообще не работает. Квадрат не двигается, но и ошибок не выдаёт
Sianessa вне форума Ответить с цитированием
Старый 25.01.2010, 17:05   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Sianessa
Дак потому что тупое копипасте кода не поможет. Нужно тебе подключать обработчики в моем примере на нужные события (см. учебник по Делфи), а так же расположить на форме компонент TShape
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.01.2010, 17:11   #7
Sianessa
Форумчанин
 
Регистрация: 18.01.2009
Сообщений: 144
По умолчанию

Все компоненты, включая TShape на форме я расположила ещё изначально.
Не надо так плохо обо мне думать.

Видимо свойства не те поставила или код не до конца вставила - первый раз у меня не работало, теперь всё работает, спасибо.

Но он почему-то как-то "петляет" на поворотах... как это исправить можно?

Последний раз редактировалось Sianessa; 25.01.2010 в 17:13.
Sianessa вне форума Ответить с цитированием
Старый 25.01.2010, 17:13   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Не надо так плохо обо мне думать.
Я никак не думаю. Я просто знаю что неподключение обработчиков - типичная ошибка тех кто из интернета код берет.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 25.01.2010, 17:18   #9
Скандербег
Форумчанин
 
Регистрация: 04.04.2009
Сообщений: 438
По умолчанию

А если так сделать.
Код:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (sx <= Image1.Left) and (sy <= Image1.Top) then begin
    dx := 1;
    dy := 0;
  end;
  if (sy <= Image1.Top) and (sx + Shape1.Width >= Image1.BoundsRect.Right) then begin
    dx := 0;
    dy := 1;
  end;
  if (sy + Shape1.Height >= Image1.BoundsRect.Bottom) and
     (sx + Shape1.Width >= Image1.BoundsRect.Right)
  then begin
    dx := -1;
    dy := 0;
  end;
  if (sy + Shape1.Height >= Image1.BoundsRect.Bottom) and (sx <= Image1.Left) then begin
    dx := 0;
    dy := -1;
  end;

  Inc(sx, dx);
  Inc(sy, dy);

  Shape1.Left := sx;
  Shape1.Top := sy;

{
  if Shape1.Left>Image1.Width-17 then
  begin
    Shape1.Left:=0;
  end;

  Shape1.Left:=Shape1.Left+1;
  x:=Get_X_ed(Shape1.Left);
  y:=f(x);
  Shape1.Top:=Get_Y_px(y)+round(Image1.Height/2)-Shape1.Left;
}
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//  getParams;
  sx := Image1.Left;
  sy := Image1.Top;
end;
Фигура (Shape1) движется по периметру внутри прямоугольника, который занимает на форме область Image1.
Скандербег вне форума Ответить с цитированием
Старый 25.01.2010, 17:23   #10
Sianessa
Форумчанин
 
Регистрация: 18.01.2009
Сообщений: 144
По умолчанию

Скандербег, всё, я сама разобралась, всё работает, спасибо! Так намного лучше!

Последний раз редактировалось Sianessa; 25.01.2010 в 17:29.
Sianessa вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В справочной автовокзала хранится расписание движения автобусов [Delphi] StudeHt Помощь студентам 10 28.05.2013 00:37
Движение круга (Помогите пожалуйста) Lifefine Общие вопросы C/C++ 5 25.11.2009 23:57
Отрисовка круга в OpenGl Oburec Мультимедиа в Delphi 1 04.07.2009 15:22
Рисование дуги круга по координатам(С++) Olya90 Помощь студентам 0 07.05.2009 13:52
Пересечение прямой и круга CoGnaC Паскаль, Turbo Pascal, PascalABC.NET 8 11.03.2008 17:01