Число вершин в сплайне

numKnots <shape> [ <spline_index_integer> ]
Основной метод, возвращает число вершин (также называются узлами и контрольными точками) в сплайне с указанным номером. Тип значения integer. Если номер сплайна не указан, метод возвращает суммарное число вершин для всех сплайнов данного объекта shape.

Пример:
y = donut()
numKnots y

Методы интерполяции

Для работы с объектами shape существует целый ряд функций интерполяции. Они позволяют определять координаты на кривой в соответствии с шагом, вычислять длины кривых и ближайшую к указанным координатам точку на кривой. Полезно использовать эти функции при расстановке клонируемых объектов вдоль сплайна или при управлении ориентацией ряда объектов с помощью сплайна (пример - анимация костей позвоночника). Для работы всем функциям интерполяции требуется задать следующие аргументы:

  1. Объект shape
  2. Номер сплайна в случае если их в объекте shape несколько - необязательный параметр, по умолчанию равный 1.
  3. Значение в диапазоне от 0.0 до 1.0, определяющее позицию на кривой пропорционально ее длине.
Существует два типа интерполяции:
  1. Первый аналогичен Path Controller (контроллер пути в 3ds max), где процентные значения вдоль пути неравномерны и зависят от расстояний между вершинами. Это простая интерполяция вычисляется на основе интервалов параметра. Например, если у сплайна есть 4 сегмента, то для первого сегмента параметр будет меняться в интервале от 0.0 до 0.25, для второго 0.25-0.5, третьего 0.5-0.75, четвертого 0.75-1.0. Такая интерполяция не зависит от длин сегментов.
  2. Второй дает равномерную интерполяцию по всей длине кривой. Параметр вычисляется во всем интервале исходя из полного периметра кривой. Т.е. начальная вершина кривой соответствует значению 0.0, конечная 1.0, а значение 0.5 дает точку на середине кривой (половина ее периметра).

Если анимированный объект перемещается по управляющему сплайну при использовании неравномерной интерполяции по пути, то его скорость будет изменяться в случае, когда вершины сплайна расположены неравномерно. Интерполяция, использующая длины дуг (второй тип), дает равномерное распределение вдоль кривой в независимости от положения вершин. Преимущество неравномерной интерполяции по пути состоит в гораздо более быстром и эффективном просчете по сравнению с равномерной интерполяцией по длинам дуг. Равномерная интерполяция работает дольше, поскольку использует операции кэширования для ускорения расчетов, но эти операции можно настроить при помощи дополнительных параметров, как показано далее.
Необязательный аргумент steps: для методов, которые описаны чуть ниже, позволяет вам определить шаги интегрирования. По умолчанию аргумент равен 5, то есть длина кривой умножается на пять. Этого значения более чем достаточно в большинстве случаев. Например, если длина кривой равна 100 единицам измерения 3ds max (метрам, миллиметрам и т.п.), то по умолчанию размер шага будет равен 500. Погрешность алгоритма интерполяции не более, чем +-1/steps от единицы измерения 3ds max. Эти методы используют кэш для ускорения своих расчетов в общем случае, когда идет постепенное перемещение по одной кривой. В кэше запоминается состояние последней точки на кривой, которое извлекается при повторном вызове метода для той же кривой в это же время анимации. Скорость расчета интерполяции при таком подходе возрастает экспоненциально. Однако 3ds max не может знать, изменилась ли кривая от одного вызова до другого, поэтому не забывайте обнулять кэш с помощью метода resetLengthInterp(), когда кривая меняется в промежутках между вызовами методов в вашем коде.

Все координаты выводятся в текущей системе координат.

pathInterp <shape> [ <curve_num> ] <parameter>
Возвращает координату (тип point3) на кривой заданного номера (номер по умолчанию равен 1) соответствующую значению параметра из диапазона от 0.0 до 1.0. Используется первый тип интерполяции (неравномерная по пути) - диапазон рассчитывается исходя из количества вершин кривой.

lengthInterp <shape> [ <curve_num> ] <parameter> [ steps:<integer> ]
Возвращает координату (тип point3) на кривой заданного номера (по умолчанию 1) соответствующую значению параметра из диапазона от 0.0 до 1.0, как часть полного периметра кривой - используется второй тип интерполяции.

resetLengthInterp()
Очищает кэш интерполяции длин кривых. Метод используется в тех случаях, когда интерполируемая кривая изменяется между вызовами методов интерполяции.

curveLength <shape> [ <curve_num> ]
Возвращает длину кривой указанного номера, как сумму длин составляющих ее дуг. В этой длине не учитывается любое масштабирование, примененное к объекту shape.

pathTangent <shape> [ <curve_num> ] <parameter>
Возвращает вектор направления касательной в интерполируемой по пути точке на заданной кривой (первый тип интерполяции). К примеру, можно использовать данный метод для установки направления объекта таким образом, чтобы он следовал изгибам кривой. Направлением объекта считается направление его локальной оси Z.

lengthTangent <shape> [ <curve_num> ] <parameter> [ steps:<integer> ]
Возвращает вектор направления касательной в интерполируемой по длине дуги точке на заданной кривой (второй тип интерполяции). Метод используется аналогично предыдущему.

nearestPathParam <shape> [ <curve_num> ] <point3> [ steps:<integer> ]
Возвращает величину параметра интерполяции (из диапазона от 0.0 до 1.0), соответствующую точке на кривой, ближайшую к точке с указанными координатами <point3>. Параметр рассчитывается интерполяцией по пути. Затем можно применить метод pathInterp с этой величиной на входе, чтобы найти координаты ближайшей точки на дуге или использовать одну из двух следующих функций (см. ниже) для преобразования между интерполяцией по длине дуги и интерполяцией по пути.

pathToLengthParam <shape> [ <curve_num> ] <parameter> [ steps:<integer> ]
Возвращает параметр равномерной интерполяции по длине дуги, соответствующий заданному параметру интерполяции по пути для этой кривой.

lengthToPathParam <shape> [ <curve_num> ] <parameter> [ steps:<integer> ]
Возвращает параметр интерполяции по пути, соответствующий заданному параметру равномерной интерполяции по длине дуги для этой кривой.


Пример использования интерполяции для распределения по кривой окружностей случайного радиуса

max select all
max delete
R=100
pathcircle=circle radius: R pos: [0,0,0]
a=2*pi*R
convertToSplineShape pathcircle
cl=curveLength pathcircle
format "% = %\n" a cl
arrcircle=#(); len=0.0

for i=1 to 15 do
(
smallR=random 5.0 15.0
len+=(smallR*2)
c=circle radius: smallR pos: [0,0,0]
append arrcircle c
)
   
limit=len/cl; circlepos=0.0
for i=1 to 15 do
(
if i==1 then circlepos=(arrcircle[i].radius+circlepos)
else circlepos+=(arrcircle[i-1].radius+arrcircle[i].radius)
p=lengthInterp pathcircle (circlepos*limit/len)
arrcircle[i].pos=p
)

На выходе: