Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.12.28;
Скачать: CL | DM;

Вниз

Помогите разобраться с построением   Найти похожие ветки 

 
@!!ex ©   (2008-11-01 16:52) [0]

TPoint = record
 x,y,z:single;  //Позиция точки в пространстве
 time:integer;  //Время
end;

Есть
список точек в 3D пространстве Points:array of TPoint отсортированных по time.
текущее время CurrentTime:integer;
инертность inert:single;

По сути набор точек задает траекторию движения объекта. Ключевые позиции.
Нужно получить позицию объекта в текущий момент времени.
Если время попадает на ключевую позицию, то просто значение позиции возвращается.
А вот если нужно интерполировать, то проблема.
inert - это коэфициент инертности. Если коэфициент 0 - то все просто, линейная интерполяция дает нужный результат.
Если коэфициент 1 - нужен идеально гладкий сплайн.

Проблема в том, что я не умею сплайны в 3Д строить. и инет не очень то делится инфой.
Математических знаний хватило на то, чтобы понять, что будет кривая третьего порядка, но как ее строить - х.з.


 
MBo ©   (2008-11-01 17:06) [1]

>нужен идеально гладкий сплайн.
Если устроит гладкость первого порядка (согласование по первой производной), то легче всего использовать сплайны Кэтмулл-Рома (частный случай TCB-сплайнов). По четырем соседним точкам рассчитывается полином между второй и третьей точкой.

Гладкость второго порядка - согласование в узлах по производной (наклону) и по второй производной (кривизне)
Кубичеси\кие интерполяционные сплайны достаточно широко освещены, иcходники найти нетрудно (например, alglib.sources.ru).
Правда, в большинстве случаев рассматривается двумерный случай с параметризацией по X, тебе же лучше использовать параметрические сплайны, выбрав нужную параметризацию. Единого мнения о том, какая параметризация кошернее, нету. В простейшем случае - по номеру точки, если точки относительно равномерно расположены. Можно и по расстоянию между ними.


 
MBo ©   (2008-11-01 17:15) [2]

Да, еще обратил внимание на твой коэффициент 0-1. Если нужны и промежуточные значения, то TCB-сплайны (Kochanek-Bartels) - то, что доктор прописал - параметр T (tension) меняешь в нужных пределах, а С и B нулевые (или единичные, не помню), и получаешь нужные результаты


 
@!!ex ©   (2008-11-01 18:56) [3]

Нашел аглоритм построения сплайна Кэтмулл-Рома.
Но пробелма в том, что он для 2Д случая. Как на 3Д переделать? Знаний не хватает. :(

PROCEDURE Spline_Calc (Ap, Bp, Cp, Dp: Point3D; T, D: Real; Var X, Y: Real);
VAR T2, T3: Real;
BEGIN
  T2 := T * T;           { Square of t }
  T3 := T2 * T;          { Cube of t }
  X := ((Ap.X*T3) + (Bp.X*T2) + (Cp.X*T) + Dp.X)/D;  { Calc x value }
  Y := ((Ap.Y*T3) + (Bp.Y*T2) + (Cp.Y*T) + Dp.Y)/D;  { Calc y value }
END;

PROCEDURE Catmull_Rom_ComputeCoeffs (N: Integer; Var Ap, Bp, Cp, Dp: Point3D);
BEGIN
  Ap.X := -CtrlPt[N-1].X + 3*CtrlPt[N].X - 3*CtrlPt[N+1].X + CtrlPt[N+2].X;
  Bp.X := 2*CtrlPt[N-1].X - 5*CtrlPt[N].X + 4*CtrlPt[N+1].X - CtrlPt[N+2].X;
  Cp.X := -CtrlPt[N-1].X + CtrlPt[N+1].X;
  Dp.X := 2*CtrlPt[N].X;
  Ap.Y := -CtrlPt[N-1].Y + 3*CtrlPt[N].Y - 3*CtrlPt[N+1].Y + CtrlPt[N+2].Y;
  Bp.Y := 2*CtrlPt[N-1].Y - 5*CtrlPt[N].Y + 4*CtrlPt[N+1].Y - CtrlPt[N+2].Y;
  Cp.Y := -CtrlPt[N-1].Y + CtrlPt[N+1].Y;
  Dp.Y := 2*CtrlPt[N].Y;
END;


 
@!!ex ©   (2008-11-01 18:57) [4]

Стоп. Или все просто и я туплю??


 
@!!ex ©   (2008-11-01 18:59) [5]

Координаты же вроде одинаково считаются...
Для трех координат будет так:
PROCEDURE Spline_Calc (Ap, Bp, Cp, Dp: Point3D; T, D: Real; Var X, Y, Z: Real);
VAR T2, T3: Real;
BEGIN
  T2 := T * T;           { Square of t }
  T3 := T2 * T;          { Cube of t }
  X := ((Ap.X*T3) + (Bp.X*T2) + (Cp.X*T) + Dp.X)/D;  { Calc x value }
  Y := ((Ap.Y*T3) + (Bp.Y*T2) + (Cp.Y*T) + Dp.Y)/D;  { Calc y value }
  Y := ((Ap.Z*T3) + (Bp.Z*T2) + (Cp.Z*T) + Dp.Z)/D;  { Calc z value }
END;

PROCEDURE BSpline_ComputeCoeffs (N: Integer; Var Ap, Bp, Cp, Dp: Point3D);
BEGIN
  Ap.X := -CtrlPt[N-1].X + 3*CtrlPt[N].X - 3*CtrlPt[N+1].X + CtrlPt[N+2].X;
  Bp.X := 3*CtrlPt[N-1].X - 6*CtrlPt[N].X + 3*CtrlPt[N+1].X;
  Cp.X := -3*CtrlPt[N-1].X + 3*CtrlPt[N+1].X;
  Dp.X := CtrlPt[N-1].X + 4*CtrlPt[N].X + CtrlPt[N+1].X;

  Ap.Y := -CtrlPt[N-1].Y + 3*CtrlPt[N].Y - 3*CtrlPt[N+1].Y + CtrlPt[N+2].Y;
  Bp.Y := 3*CtrlPt[N-1].Y - 6*CtrlPt[N].Y + 3*CtrlPt[N+1].Y;
  Cp.Y := -3*CtrlPt[N-1].Y + 3*CtrlPt[N+1].Y;
  Dp.Y := CtrlPt[N-1].Y + 4*CtrlPt[N].Y + CtrlPt[N+1].Y;

  Ap.Z := -CtrlPt[N-1].Z + 3*CtrlPt[N].Z - 3*CtrlPt[N+1].Z + CtrlPt[N+2].Z;
  Bp.Z := 3*CtrlPt[N-1].Z - 6*CtrlPt[N].Z + 3*CtrlPt[N+1].Z;
  Cp.Z := -3*CtrlPt[N-1].Z + 3*CtrlPt[N+1].Z;
  Dp.Z := CtrlPt[N-1].Z + 4*CtrlPt[N].Z + CtrlPt[N+1].Z;
END;

?


 
@!!ex ©   (2008-11-01 19:01) [6]

Упс. не тот код:
PROCEDURE Spline_Calc (Ap, Bp, Cp, Dp: Point3D; T, D: Real; Var X, Y, Z: Real);
VAR T2, T3: Real;
BEGIN
  T2 := T * T;           { Square of t }
  T3 := T2 * T;          { Cube of t }
  X := ((Ap.X*T3) + (Bp.X*T2) + (Cp.X*T) + Dp.X)/D;  { Calc x value }
  Y := ((Ap.Y*T3) + (Bp.Y*T2) + (Cp.Y*T) + Dp.Y)/D;  { Calc y value }
  Y := ((Ap.Z*T3) + (Bp.Z*T2) + (Cp.Z*T) + Dp.Z)/D;  { Calc z value }
END;

PROCEDURE Catmull_Rom_ComputeCoeffs (N: Integer; Var Ap, Bp, Cp, Dp: Point3D);
BEGIN
  Ap.X := -CtrlPt[N-1].X + 3*CtrlPt[N].X - 3*CtrlPt[N+1].X + CtrlPt[N+2].X;
  Bp.X := 2*CtrlPt[N-1].X - 5*CtrlPt[N].X + 4*CtrlPt[N+1].X - CtrlPt[N+2].X;
  Cp.X := -CtrlPt[N-1].X + CtrlPt[N+1].X;
  Dp.X := 2*CtrlPt[N].X;

  Ap.Y := -CtrlPt[N-1].Y + 3*CtrlPt[N].Y - 3*CtrlPt[N+1].Y + CtrlPt[N+2].Y;
  Bp.Y := 2*CtrlPt[N-1].Y - 5*CtrlPt[N].Y + 4*CtrlPt[N+1].Y - CtrlPt[N+2].Y;
  Cp.Y := -CtrlPt[N-1].Y + CtrlPt[N+1].Y;
  Dp.Y := 2*CtrlPt[N].Y;

  Ap.Z := -CtrlPt[N-1].Z + 3*CtrlPt[N].Z - 3*CtrlPt[N+1].Z + CtrlPt[N+2].Z;
  Bp.Z := 2*CtrlPt[N-1].Z - 5*CtrlPt[N].Z + 4*CtrlPt[N+1].Z - CtrlPt[N+2].Z;
  Cp.Z := -CtrlPt[N-1].Z + CtrlPt[N+1].Z;
  Dp.Z := 2*CtrlPt[N].Z;
END;


 
@!!ex ©   (2008-11-01 19:05) [7]

Похоже что нет...


 
Sapersky   (2008-11-01 19:15) [8]

Вроде одинаково. У тебя опечатка в Spline_Calc, там Z = должно быть.
Можно ещё B-сплайны использовать (искать TBSpline), хотя считать их сложнее, но кривая получается более плавная.


 
@!!ex ©   (2008-11-01 19:20) [9]

> У тебя опечатка в Spline_Calc, там Z = должно быть.

Исправил уже. Толку нету.


> Можно ещё B-сплайны использовать (искать TBSpline), хотя
> считать их сложнее, но кривая получается более плавная.


У меня как раз код, который сравнивает два варианта, БСплайны и Кэтмулл-Рома.
Отсюда код:
http://www.enlight.ru/demo/faq/smth.phtml?query=alg_curves_splines

На 2Д отлично работает. А вот 3Д не хотит.


 
@!!ex ©   (2008-11-01 19:20) [10]

Вот еще нашел:
http://newsgroups.cryer.info/borland/public.delphi.graphics/200802/0802026065.html

попытаюсь понять что там.

MBo, спасибо за пинок в нужном направлении!


 
Sapersky   (2008-11-01 19:43) [11]

У меня как раз код, который сравнивает два варианта, БСплайны и Кэтмулл-Рома.
На 2Д отлично работает. А вот 3Д не хотит.


У меня работает:
http://sapersky.narod.ru/files/Splines.rar


 
@!!ex ©   (2008-11-01 20:28) [12]

Все. у меня заработало.
Спасибо всем!!!!!


> [11] Sapersky   (01.11.08 19:43)

Уже заработало. :) Видимо я где-то косячил.
Спасибо!


 
MBo ©   (2008-11-02 08:35) [13]

>Видимо я где-то косячил.
пополам не делил



Страницы: 1 вся ветка

Текущий архив: 2008.12.28;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.015 c
15-1224761475
pochemuchka
2008-10-23 15:31
2008.12.28
Не генерируется объявление класса в HPP


15-1225443980
clickmaker
2008-10-31 12:06
2008.12.28
Кто-нибудь разворачивал asp.net под IIS 7 на Windows 2008 Server?


15-1225078082
Slider007
2008-10-27 06:28
2008.12.28
С днем рождения ! 25 октября 2008 суббота


15-1225230195
Германн
2008-10-29 00:43
2008.12.28
Спам-боты


2-1227080020
Andrey_ka
2008-11-19 10:33
2008.12.28
ошибка при закрытии проэкта