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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.03.2015, 23:44   #1
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
Вопрос Canvas и вращение

Здравствуйте, пишу небольшую игру с физической моделью, не могу понять как организовать вращение. Даётся n квадратов состоящих из набора точек и выводятся через Canvas.Polygon;
Перерыв интернет так и не понял как заставить вращать их относительно точки, допустим упал один кубик на угол и должен наклониться относительно точки соприкосновения вправо/влево. Но получается только наклонить все кубики одновременно при чем относительно верхнего левого угла экрана. Помогите с формулой расчёта.

Код:
  TMyBlock = class
  x,y:single;
  sx,sy:Single;  //speed x, speed y
  aX,aY:Single;  //accelerating x, y
  angle:single;  //rotating x,y
  onGround:boolean;
  kind: TKindOfBlock
  end;

  TFloatPoint = record
  X,Y:Single;
  end;

  TMyPoly = class(TMyBlock)
  arr:array of TFloatPoint;
  public
  constructor Create;
  function getwidth:Integer;
  function getheight:Integer;
  procedure addPoint(p:TFloatPoint);
  end;
Вращаю формулой из википедии
Код:
{
x'=x*cos(angle)-y*sin(angle)
y'=x*sin(angle)+y*cos(angle)
}
      xo:=bb[i].arr[0].X + bb[i].getwidth / 2;  // Середина фигуры по X
      yo:=bb[i].arr[0].y + bb[i].getheight / 2; // По Y

      for j:=0 to High(bb[i].arr) do
      begin
        bb[i].arr[j].X:=bb[i].arr[j].X*cos(DegToRad(15))-bb[i].arr[j].y * sin(DegToRad(15)) + xo + yo ;
        bb[i].arr[j].y:=bb[i].arr[j].X*sin(DegToRad(15))+bb[i].arr[j].y * cos(DegToRad(15)) + yo + yo;
      end;
Изменил немного формулу, но вращение почему то происходит от начала координат, помогите пожалуйста


Кому интересно - Демо
Здравствуйте

Последний раз редактировалось NEoMASTERR; 14.03.2015 в 08:45.
NEoMASTERR вне форума Ответить с цитированием
Старый 14.03.2015, 11:42   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

обычно формулы поворота приводятся для варианта с центром поворота в начале координат.

Для произвольной точки надо ЗНАТЬ
(A0x,A0y,B0x,....D0y) координаты упавшего кубика
(С0x,X0y) Угол на который упал кубик (координаты точки поворота)

1. перенести начало координат в точку поворота (угол кубика и поверхность)
(A1x=Ax-C0x, A1y=Ay-C0y, B1x=Bx-C0x,..., D1y=Dy-C0y)

2. повернуть кубик относительно начала новых коодинат на @
(A2x=A1x*cos@-A1y*sin@, A2y=A1x*sin@+A1y*cos@, B2x=...., D2y=...)
формулу не проверял взял из вашего поста

3.Вернуть начало координат на место
(A3x=A2x+C0x, A3y=A2x+C0y, B3x=B2x+C0x, .... , D3y=D2y+C0y)
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 14.03.2015 в 11:45.
evg_m вне форума Ответить с цитированием
Старый 23.03.2015, 19:28   #3
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
обычно формулы поворота приводятся для варианта с центром поворота в начале координат.

Для произвольной точки надо ЗНАТЬ
(A0x,A0y,B0x,....D0y) координаты упавшего кубика
(С0x,X0y) Угол на который упал кубик (координаты точки поворота)

1. перенести начало координат в точку поворота (угол кубика и поверхность)
(A1x=Ax-C0x, A1y=Ay-C0y, B1x=Bx-C0x,..., D1y=Dy-C0y)

2. повернуть кубик относительно начала новых коодинат на @
(A2x=A1x*cos@-A1y*sin@, A2y=A1x*sin@+A1y*cos@, B2x=...., D2y=...)
формулу не проверял взял из вашего поста

3.Вернуть начало координат на место
(A3x=A2x+C0x, A3y=A2x+C0y, B3x=B2x+C0x, .... , D3y=D2y+C0y)
В Общем сделал поворот кубика, но, он уменьшаться начинает, в чем проблема? Координаты ставятся в центр куба (думаю в этом проблема т.к. делаю для фигур с любым количеством углов и центр неправильно высчитывается). Хелп

Код:
procedure Rotate(var a:PMyBlock;angle:Single);
var
  i:integer;
  b:PMyPoly;
  fp:TFloatPoint;
  x,y:Single;
begin
  if a^ is TMyPoly then
  begin
    b:=PMyPoly(a);

    fp.X:=b^.x + b^.width / 2;
    fp.y:=b^.y - b^.height / 2;

    for i:=0 to high(b^.arr) do
    begin
      x:=b^.arr[i].X - fp.X;
      y:=b^.arr[i].Y - fp.y;

      x := x * cos(angle) - y * sin(angle);
      y := x * sin(angle) + y * cos(angle);

      b^.arr[i].X := fp.x + x;
      b^.arr[i].y := fp.y + y;
    end;
  end;
end;
Здравствуйте
NEoMASTERR вне форума Ответить с цитированием
Старый 24.03.2015, 14:38   #4
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Возможно проблемы с округлением (неточность расчетов, расчет в Extended - хранение в Single). Храни только начальное состояние полигона (модель), и текущие смещение и поворот.
Смещение объекта сводится к увеличению текущего смещения.
Поворот - к увеличению текущего поворота.
Ну а отрисовку (расчет текущих координат) ты уже сделал.

А можеш попробовать хранить все координаты в Extended. Должно помочь.
Sibedir вне форума Ответить с цитированием
Старый 24.03.2015, 15:22   #5
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
Возможно проблемы с округлением (неточность расчетов, расчет в Extended - хранение в Single). Храни только начальное состояние полигона (модель), и текущие смещение и поворот.
Смещение объекта сводится к увеличению текущего смещения.
Поворот - к увеличению текущего поворота.
Ну а отрисовку (расчет текущих координат) ты уже сделал.

А можеш попробовать хранить все координаты в Extended. Должно помочь.
А как же обрабатывать касания блоков если хранится только начальное состояние?) как например в движках сделано? Extended не помог(
Здравствуйте
NEoMASTERR вне форума Ответить с цитированием
Старый 24.03.2015, 15:57   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

ок. домой вернусь - посмотрю.

Добавлено ---------------------------------------
Кажись понял
Код:
x := x * cos(angle) - y * sin(angle);
y := x * sin(angle) + y * cos(angle); // Вот тут у тебя X уже не тот
Попробуй так
Код:
b^.arr[i].X := fp.x + x * cos(angle) - y * sin(angle);
b^.arr[i].y := fp.y + x * sin(angle) + y * cos(angle);
Добавлено ---------------------------------------
Вращение ролигона.zip

Последний раз редактировалось Sibedir; 24.03.2015 в 20:00.
Sibedir вне форума Ответить с цитированием
Старый 24.03.2015, 21:25   #7
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
Попробуй так
Код:
b^.arr[i].X := fp.x + x * cos(angle) - y * sin(angle);
b^.arr[i].y := fp.y + x * sin(angle) + y * cos(angle);
Огромное спасибо!
Здравствуйте
NEoMASTERR вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вращение эллипса kpat1k Общие вопросы Delphi 14 04.11.2014 16:47
Вращение Элипса в canvas Never_more Помощь студентам 0 13.05.2010 23:38
Вращение stscolt Помощь студентам 1 08.10.2009 20:39
Вращение параллелепипеда stscolt Помощь студентам 1 06.10.2009 22:50
Вращение изображения beginner JavaScript, Ajax 5 07.07.2008 23:44