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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 16.06.2014, 15:11   #1
Armageddets
Форумчанин
 
Регистрация: 30.06.2012
Сообщений: 145
По умолчанию Движение обьекта на заданный угол

Добрый день, уважаемые эксперты. Прошк вашей помощи. У меня есть картинка, которая должна смещаться относительно координат х и у, в зависимости от угла поворота изображения. Я сделал следующие формулы подсчета передвижения:

Car.Y:=Car.Y+Sin(DegToRad(Car.Angle ))*round(Car.speed);
Car.X:=Car.X-Cos(DegToRad(Car.Angle))*round(Car. speed);

Но при данных формулах картинка праивльно двигается только на углы +-45 градусов (0, 45, 90, 135, 180, 225, 270, 315, 360); А вот движение на промежуточные углы происходит неправильно. Как сделать правильное движение на любой угол? например на 1, 5, 15 градусов. Насколько я понимаю у меня из-за округлений могут быть неточности... или угол нужно сделать тип single?

Car:Tpoint;
Car.Angle:integer;
Car.speed:real;

Заранее спасибо за ответ.
Armageddets вне форума Ответить с цитированием
Старый 16.06.2014, 16:15   #2
XE5
Заблокирован
 
Регистрация: 02.03.2014
Сообщений: 439
По умолчанию

Код где???

Последний раз редактировалось XE5; 16.06.2014 в 16:20.
XE5 вне форума Ответить с цитированием
Старый 16.06.2014, 16:35   #3
Armageddets
Форумчанин
 
Регистрация: 30.06.2012
Сообщений: 145
По умолчанию

Код:
type

  
  TCar=record
  X,Y,Angle:integer;
  Speed,Ves,Power,SpeedLimit:real;
  qGo,qBack:boolean;
  end;

 
var
  Form1: TForm1;
  Buf,CarIMG,OuthCarIMG:TBitmap;
  path:string;
  Car:TCar;
  procedure IMGRotate(IMG:TBitmap; Angle:single);



procedure TForm1.FormCreate(Sender: TObject);
begin

path:=ExtractFileDir(Application.ExeName);
Buf:=TBitmap.Create;
Buf.Width:=640;
Buf.Height:=480;

CarIMG:=Tbitmap.Create;
CarIMG.Transparent:=true;
CarIMG.LoadFromFile(path+'\0.bmp');
//povernutiy variant kartinki
OuthCarIMG:=Tbitmap.Create;
OuthCarIMG.Transparent:=true;
OuthCarIMG.LoadFromFile(path+'\0.bmp');

Car.X:=320;
Car.Y:=240;
Car.Speed:=0;
Car.qGo:=false;
Car.qBack:=false;
Car.Ves:=1.1;
Car.Power:=2.4;
Car.Angle:=0;
Car.SpeedLimit:=Car.Power-Car.Ves;
if Car.SpeedLimit<0 then Car.SpeedLimit:=0;


end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

  buf.Canvas.Brush.Color:=clGreen;
  buf.Canvas.Rectangle(0,0,640,480);

  Buf.Canvas.Draw(Car.X,Car.Y,OuthCarIMG);

  form1.Canvas.Draw(0,0,Buf);

  //razgon
  if (Car.qGo=true) and (Car.SpeedLimit>=(Car.Speed+Car.Power-Car.Ves) ) then
  Car.Speed:=Car.Speed+(Car.Power-Car.Ves);
  //zadniy hod
  if (Car.qBack=true) and (Car.SpeedLimit>=-(Car.Speed-Car.Power+Car.Ves) ) then
  Car.Speed:=Car.Speed-(Car.Power-Car.Ves);

  //konets razgona
  if (Car.Speed-Car.Power+Car.Ves>=0) and (Car.qGo=false) then
  Car.Speed:=Car.Speed-Car.Power+Car.Ves;
  //konets zadnego hoda
  if (Car.Speed+Car.Power-Car.Ves<=0) and (Car.qBack=false) then
  Car.Speed:=Car.Speed+Car.Power-Car.Ves;

  //itogovaya skorost
  //esli oboroti skorosti pozvolyayut sdvinut mashinu
  if (Car.Speed>Car.Ves) or (Car.Speed<-Car.Ves) then
  begin
  Car.Y:=Car.Y+Sin(DegToRad(Car.Angle))*round(Car.speed);
  Car.X:=Car.X-Cos(DegToRad(Car.Angle))*round(Car.speed);
  end;

  

  //ogranichenie
  if Car.Y+63<=0 then Car.Y:=480;

  form1.Caption:='Speed='+floattostr(Car.speed)+'| Ves='+floattostr(Car.Ves)
  +'| SpeedLimit='+floattostr(Car.SpeedLimit)+'| Angle='+floattostr(Car.Angle);

end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  if key=VK_UP then
  Car.qGo:=true;

  if key=VK_Down then
  Car.qBack:=true;

  if Key=Vk_Right then
  begin
  Car.Angle:=Car.Angle-1;
  if Car.Angle>360 then Car.Angle:=0;
  IMGRotate(CarIMG, Car.Angle);
  end;

  if Key=Vk_Left then
  begin
  Car.Angle:=Car.Angle+1;
  if Car.Angle<0 then Car.Angle:=360;
  IMGRotate(CarIMG, Car.Angle);
  end;

end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  if key=VK_UP then Car.qGo:=false;
  if key=VK_Down then Car.qBack:=false;
  

end;


procedure IMGRotate(IMG:TBitmap; Angle:single);
var X,Y:uint;
    buf:TBitmap;
    x0,y0:Integer; //center katrinki
    sinus, cosinus: Extended;
    Result:Tpoint;

begin
  Buf:=TBitmap.Create;
  Buf.Assign(IMG);
  //tochka vokrug kotoroy nizhno vertet - tsentr izobrazheniya
  x0 := img.Width div 2;
  y0 := img.Height div 2;
  Angle:=Angle*PI/180;

  for X:=0 to IMG.width do
  begin
    for Y:=0 to IMG.Height do
    begin
    //vichislyaem koordinati
    Result.X:=Round(x0+(x-x0)*Cos(Angle)-(y-y0)*Sin(Angle));
    Result.Y:=Round(y0+(x-x0)*Sin(Angle)+(y-y0)*Cos(Angle));
    Buf.Canvas.Pixels[x,y]:=Img.Canvas.Pixels[Result.X,Result.Y];
    //beliy tsvet delaem prozrachnim
    if (Buf.Canvas.Pixels[x,y]=clWhite) then
    Buf.Canvas.Pixels[x,y]:=0;
    end;
  end;
  outhCarIMG.Assign(buf);
  Buf.FreeImage;
  Buf.Free;
end;


end.

Последний раз редактировалось Stilet; 17.06.2014 в 09:41.
Armageddets вне форума Ответить с цитированием
Старый 16.06.2014, 17:43   #4
XE5
Заблокирован
 
Регистрация: 02.03.2014
Сообщений: 439
По умолчанию

car.x, car.y целые числа, обозначающие позицию изображения. Ты не можешь обозначить позицию машины как дробное число, соответственно применяешь округление до целого числа. В итоге ты можешь сдвинуть изображение только на пиксель вверх, вниз влево, вправо, и одновременно влево вниз, вправо вниз, и т.д. Вот и получается что ты двигаешь картинку только под углы кратные 45 градусов. Чтоб двигать изображение на любой угол, нежно представить car.x, car.y как дробные числа, а перерасчёт производить только в момент перерисовки для получения координаты отрисовки. Сам координаты при этом останутся дробными числами.
XE5 вне форума Ответить с цитированием
Старый 16.06.2014, 17:54   #5
Armageddets
Форумчанин
 
Регистрация: 30.06.2012
Сообщений: 145
По умолчанию

Спасибо. Это решило мою проблему.
Armageddets вне форума Ответить с цитированием
Старый 16.06.2014, 18:34   #6
XE5
Заблокирован
 
Регистрация: 02.03.2014
Сообщений: 439
По умолчанию

На тебе ещё пару исправленных ошибок. Всё равно потом попрешся новую тему создавать.
Код:
unit Unit1;

interface

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

type

  
  TCar=record
  Angle:integer;
  Speed,Ves,Power,SpeedLimit,x,y:real;
  qGo,qBack:boolean;
  end;

  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Buf, CarIMG, OuthCarIMG:TBitmap;
  path:string;
  Car:TCar;
  procedure IMGRotate(IMG:TBitmap; Angle:single);

implementation
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin

path:=ExtractFileDir(Application.ExeName);
Buf:=TBitmap.Create;
Buf.Width:=640;
Buf.Height:=480;

CarIMG:=Tbitmap.Create;
CarIMG.Transparent:=true;
CarIMG.LoadFromFile(path+'\0.bmp');
OuthCarIMG:=Tbitmap.Create;
OuthCarIMG.Transparent:=true;
OuthCarIMG.LoadFromFile(path+'\0.bmp');

Car.X:=320;
Car.Y:=240;
Car.Speed:=0;
Car.qGo:=false;
Car.qBack:=false;
Car.Ves:=1.1;
Car.Power:=2.4;
Car.Angle:=0;
Car.SpeedLimit:=Car.Power-Car.Ves;
if Car.SpeedLimit<0 then Car.SpeedLimit:=0;


end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
buf.Canvas.Brush.Color:=clGreen;
 buf.Canvas.Rectangle(0,0,640,480);

 Buf.Canvas.Draw(Round(Car.X),Round(Car.Y),OuthCarIMG);

 form1.Canvas.Draw(0,0,Buf);

 //razgon
 if (Car.qGo=true) and (Car.SpeedLimit>=(Car.Speed+Car.Power-Car.Ves) ) then
 Car.Speed:=Car.Speed+(Car.Power-Car.Ves);
 //zadniy hod
 if (Car.qBack=true) and (Car.SpeedLimit>=-(Car.Speed-Car.Power+Car.Ves) ) then
 Car.Speed:=Car.Speed-(Car.Power-Car.Ves);

 //konets razgona
 if (Car.Speed-Car.Power+Car.Ves>=0) and (Car.qGo=false) then
 Car.Speed:=Car.Speed-Car.Power+Car.Ves;
 //konets zadnego hoda
 if (Car.Speed+Car.Power-Car.Ves<=0) and (Car.qBack=false) then
 Car.Speed:=Car.Speed+Car.Power-Car.Ves;

 //itogovaya skorost
 //esli oboroti skorosti pozvolyayut sdvinut mashinu
 if (Car.Speed>Car.Ves) or (Car.Speed<-Car.Ves) then
 begin
 Car.Y:=Car.Y+Sin(DegToRad(Car.Angle - 90))* Car.speed; // 90 градусов, ибо машина едет вбок
 Car.X:=Car.X+Cos(DegToRad(Car.Angle + 90))* Car.speed;
end;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  if key=VK_UP then
  Car.qGo:=true;

  if key=VK_Down then
  Car.qBack:=true;

  if Key=Vk_Right then
  begin
  Car.Angle := (Car.Angle-1) mod 360; // разберись как работает mod
  IMGRotate(CarIMG, Car.Angle);
  end;

  if Key=Vk_Left then
  begin
  Car.Angle:= (Car.Angle+1) mod 360; // разберись как работает mod
  IMGRotate(CarIMG, Car.Angle);
  end;

end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  if key=VK_UP then Car.qGo:=false;
  if key=VK_Down then Car.qBack:=false;


end;

procedure IMGRotate(IMG:TBitmap; Angle:single);
var X,Y:uint;
    buf:TBitmap;
    x0,y0:Integer; //center katrinki
    sinus, cosinus: Extended;
    Result:Tpoint;

begin
  Buf:=TBitmap.Create;
  Buf.Assign(IMG);
  //tochka vokrug kotoroy nizhno vertet - tsentr izobrazheniya
  x0 := img.Width div 2;
  y0 := img.Height div 2;
  Angle:=Angle*PI/180;

  for X:=0 to IMG.width do
  begin
    for Y:=0 to IMG.Height do
    begin
    //vichislyaem koordinati
    Result.X:=Round(x0+(x-x0)*Cos(Angle)-(y-y0)*Sin(Angle));
    Result.Y:=Round(y0+(x-x0)*Sin(Angle)+(y-y0)*Cos(Angle));
    Buf.Canvas.Pixels[x,y]:=Img.Canvas.Pixels[Result.X,Result.Y];
    //beliy tsvet delaem prozrachnim
    if (Buf.Canvas.Pixels[x,y]=clWhite) then
    Buf.Canvas.Pixels[x,y]:=0;
    end;
  end;
  OuthCarIMG.Assign(buf);
  Buf.FreeImage;
  Buf.Free;
end;

end.

Последний раз редактировалось XE5; 16.06.2014 в 18:38.
XE5 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поворот фигуры на заданный угол _Лето_ Общие вопросы C/C++ 0 23.03.2014 23:21
Поворот обьекта на угол Lemo Помощь студентам 4 06.04.2009 19:46
Движение обьекта клавишами в с++ Grizzzli Помощь студентам 2 05.04.2009 12:43
Вращение (поворот на заданный угол) векторного изображения Македонский Мультимедиа в Delphi 6 26.02.2009 21:19
Поворот изображения на заданный угол. taller07 Мультимедиа в Delphi 4 28.11.2008 14:01