Форум: "Прочее";
Текущий архив: 2008.12.28;
Скачать: [xml.tar.bz2];
ВнизПомогите разобраться с построением Найти похожие ветки
← →
@!!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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.005 c