Конференция "Прочее" » Помогите разобраться с построением
 
  • @!!ex © (01.11.08 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 © (01.11.08 17:06) [1]
    >нужен идеально гладкий сплайн.
    Если устроит гладкость первого порядка (согласование по первой производной), то легче всего использовать сплайны Кэтмулл-Рома (частный случай TCB-сплайнов). По четырем соседним точкам рассчитывается полином между второй и третьей точкой.

    Гладкость второго порядка - согласование в узлах по производной (наклону) и по второй производной (кривизне)
    Кубичеси\кие интерполяционные сплайны достаточно широко освещены, иcходники найти нетрудно (например, alglib.sources.ru).
    Правда, в большинстве случаев рассматривается двумерный случай с параметризацией по X, тебе же лучше использовать параметрические сплайны, выбрав нужную параметризацию. Единого мнения о том, какая параметризация кошернее, нету. В простейшем случае - по номеру точки, если точки относительно равномерно расположены. Можно и по расстоянию между ними.
  • MBo © (01.11.08 17:15) [2]
    Да, еще обратил внимание на твой коэффициент 0-1. Если нужны и промежуточные значения, то TCB-сплайны (Kochanek-Bartels) - то, что доктор прописал - параметр T (tension) меняешь в нужных пределах, а С и B нулевые (или единичные, не помню), и получаешь нужные результаты
  • @!!ex © (01.11.08 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 © (01.11.08 18:57) [4]
    Стоп. Или все просто и я туплю??
  • @!!ex © (01.11.08 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 © (01.11.08 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 © (01.11.08 19:05) [7]
    Похоже что нет...
  • Sapersky (01.11.08 19:15) [8]
    Вроде одинаково. У тебя опечатка в Spline_Calc, там Z = должно быть.
    Можно ещё B-сплайны использовать (искать TBSpline), хотя считать их сложнее, но кривая получается более плавная.
  • @!!ex © (01.11.08 19:20) [9]
    > У тебя опечатка в Spline_Calc, там Z = должно быть.

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


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


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

    На 2Д отлично работает. А вот 3Д не хотит.
  • @!!ex © (01.11.08 19:20) [10]
    Вот еще нашел:
    http://newsgroups.cryer.info/borland/public.delphi.graphics/200802/0802026065.html

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

    MBo, спасибо за пинок в нужном направлении!
  • Sapersky (01.11.08 19:43) [11]
    У меня как раз код, который сравнивает два варианта, БСплайны и Кэтмулл-Рома.
    На 2Д отлично работает. А вот 3Д не хотит.


    У меня работает:
    http://sapersky.narod.ru/files/Splines.rar
  • @!!ex © (01.11.08 20:28) [12]
    Все. у меня заработало.
    Спасибо всем!!!!!


    > [11] Sapersky   (01.11.08 19:43)

    Уже заработало. :) Видимо я где-то косячил.
    Спасибо!
  • MBo © (02.11.08 08:35) [13]
    >Видимо я где-то косячил.
    пополам не делил
 
Конференция "Прочее" » Помогите разобраться с построением
Есть новые Нет новых   [134446   +31][b:0][p:0.003]