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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.04.2013, 18:54   #1
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию Проблема с математикой. (Осторожно! Возможно матан!)

Пожалуйста, прочтите, может эта задачка для вас проще простого...
Не знаю как реализовать расчет value, в зависимости от (iter, iterAll, valueStart, valueStop, time) в теле процедуры таймера, чтоб было относительно плавное движение.
Делаю vcl-аналог анимации из firemonkey, для, собственно, vcl-проекта.
Вообщем надо чтоб value формировался соответственно графику:

К параметру Y объекта X каждую итерацию прибавляется value, за счет чего происходит движение, а при последней итерации параметр Y просто приравнивается к valueStop.
Со средним значением value это работает, но движение начинается резко, резко и заканчивается.
Вообщем:
time - время на выполнение анимации (допустим 1000, секунда).
timer.interval всегда равен 50, так как гугление дает понять, что стандартный таймер не способен стабильно выдавать интервал менее 40, 10 прозапас.
iterAll=time/50 (1000/50=20).
path=valueStop-valueStart (100=250-150, к примеру, среднее значение здесь бы получилось 5=100/20).
Собственно, самая важная часть:
Код:
procedure tanimation.timerontimer(sender:tobject);
begin
  inc(iter);
  value:= //здесь неизвестная мне строка
  X.Y:=X.Y+value;
  if iter=iterAll then animationstop;
end;
В итоге мы должны начать с X.Y=valueStart, а закончить на X.Y=valueStop.
Медленный старт, уверенная скорость посередине и торможение.
alextrof94$gmail.com

Последний раз редактировалось alextrof94; 13.04.2013 в 19:16.
alextrof94 вне форума Ответить с цитированием
Старый 13.04.2013, 21:34   #2
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Еще инфы нарыл:
Код:
if iter<=iterall/2 then 
  value:=((sin(iter/((iterall/2)/pi)-2*pi)+1)/2)*valuemax
else
  value:=((sin(iter/((iterall/2)/pi)-pi)+1)/2)*valuemax;
Но теперь проблема: откуда узнать valueMax (наивысшую точку графика)?

UPD:
valuestop-valuestart==value(0)+value(1)+value (2)+...+value(iterall);
valuemax==value(iterall/2);
может поможет
alextrof94$gmail.com

Последний раз редактировалось alextrof94; 13.04.2013 в 22:43.
alextrof94 вне форума Ответить с цитированием
Старый 13.04.2013, 22:12   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
узнать valueMax (наивысшую точку графика)?
Это высота рабочей области на которой рисуется график, за вычетом нескольких пикселей+толщина линии графика.
Человек_Борща вне форума Ответить с цитированием
Старый 13.04.2013, 22:41   #4
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Это высота рабочей области на которой рисуется график, за вычетом нескольких пикселей+толщина линии графика.
ты юморист.
alextrof94$gmail.com
alextrof94 вне форума Ответить с цитированием
Старый 13.04.2013, 23:49   #5
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

ПО хорошему - нужно записывать дифференциальное уравнение движения.
Это если подходить серьезно к физической достоверности движения.
Но можно и схимичить, например, как в Вашем примере - с использованием тригонометрических функций.

Мне кажется, Вам нужно определиться, который из путей Вам ближе, после чего сообщить о своем выборе и указать, что именно Вам непонятно.
Потому как по двум последним сообщениям - каков вопрос, таков и ответ.
s-andriano вне форума Ответить с цитированием
Старый 14.04.2013, 00:21   #6
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Цитата:
Сообщение от s-andriano Посмотреть сообщение
ПО хорошему - нужно записывать дифференциальное уравнение движения.
Это если подходить серьезно к физической достоверности движения.
Но можно и схимичить, например, как в Вашем примере - с использованием тригонометрических функций.

Мне кажется, Вам нужно определиться, который из путей Вам ближе, после чего сообщить о своем выборе и указать, что именно Вам непонятно.
Потому как по двум последним сообщениям - каков вопрос, таков и ответ.
Ну мне лучше - правильней, потому как эта задачка общего применения и работать должна всегда, вне зависимости от значений, но у меня полный голяк с дифференциальными уравнениями. С матаном не дружу.
alextrof94$gmail.com
alextrof94 вне форума Ответить с цитированием
Старый 14.04.2013, 00:24   #7
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Вот собственно весь код unita с типом "анимация", нужен код где откоменчено.
Код:
unit animationtype;

interface

uses Vcl.ExtCtrls, Vcl.StdCtrls;

type tanimation = record
public
  function create(aobj: tobject; aparametr: string; atime, avstart, avstop, aanimationtype: integer): boolean;
  private
  obj:tobject;
  parametr:string;
  time, vstart, vstop, animationtype, iter, iterall:integer;
  timer:ttimer;
  started:boolean;
  procedure doanimation(sender:tobject);
  procedure stopanimation;
end;

implementation

{ tanimation }

function tanimation.create(aobj: tobject; aparametr: string; atime, avstart,
  avstop, aanimationtype: integer): boolean;
begin
  if started then
    result:=false
  else
  begin
    started:=true;
    obj:=aobj;
    parametr:=aparametr;
    time:=atime;
    vstart:=avstart;
    vstop:=avstop;
    animationtype:=aanimationtype;
    iter:=0;
    iterall:=round(time/50);
    timer:=ttimer.Create(nil);
    timer.Interval:=50;
    timer.OnTimer:=doanimation;
    timer.Enabled:=true;

    if (obj is tpanel) then
    begin
      if parametr='left' then
        (obj as tpanel).Left:=vstart;
      if parametr='top' then
        (obj as tpanel).top:=vstart;
      if parametr='width' then
        (obj as tpanel).width:=vstart;
      if parametr='height' then
        (obj as tpanel).height:=vstart;
    end;
  end;
end;

procedure tanimation.doanimation(sender: tobject);
  var value:integer;
begin
  if animationtype=0 then
  begin
    value:= //тут должен быть код <=========================================================================================
  end;
  if animationtype=1 then
    value:=round((vstop-vstart)/iterall);
  if animationtype=2 then
    value:=0;

  if (obj is tpanel) then  //panel
  begin
    if parametr='left' then  //left
      (obj as tpanel).Left:=(obj as tpanel).Left+value;
    if parametr='top' then  //top
      (obj as tpanel).top:=(obj as tpanel).top+value;
    if parametr='width' then  //width
      (obj as tpanel).width:=(obj as tpanel).width+value;
    if parametr='height' then  //height
      (obj as tpanel).height:=(obj as tpanel).height+value;
  end;
  inc(iter);
  if iter>=iterall then
    stopanimation;
end;

procedure tanimation.stopanimation;
begin
  timer.Enabled:=false;
  timer.Free;

  if (obj is tpanel) then
  begin
    if parametr='left' then
      (obj as tpanel).Left:=vstop;
    if parametr='top' then
      (obj as tpanel).top:=vstop;
    if parametr='width' then
      (obj as tpanel).width:=vstop;
    if parametr='height' then
      (obj as tpanel).height:=vstop;
  end;

  started:=false;
end;

end.
alextrof94$gmail.com
alextrof94 вне форума Ответить с цитированием
Старый 14.04.2013, 00:45   #8
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

По идее, valuemax = (valuestop-valuestart) * 2 * pi / ((2 + pi) * iterall).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 14.04.2013, 00:53   #9
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
По идее, valuemax = (valuestop-valuestart) * 2 * pi / ((2 + pi) * iterall).
Замечены изменения в нужную сторону в частности разгона и торможения, но они происходят 2жды, т.е. на старте, по середине, в конце.
alextrof94$gmail.com

Последний раз редактировалось alextrof94; 14.04.2013 в 01:02.
alextrof94 вне форума Ответить с цитированием
Старый 14.04.2013, 01:01   #10
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

alextrof94, если рассматривать верхний график, как график ускорения, то все работает по графику

UPD А может и нет...
Не должно тормозить в центре.
Скорость в центре должна быть максимальной.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Осторожно кидала. mr_kolobokov Свободное общение 8 30.03.2012 09:09
Проблема с математикой. EliteSly Помощь студентам 7 06.03.2012 23:16
Осторожно Webmoney.Вопрос знатокам! DeleteRz Софт 1 16.02.2010 18:13
Помогите с математикой Chals Помощь студентам 3 13.06.2007 16:07