Чтение онлайн

ЖАНРЫ

Написание скриптов для Blender 2.49

Anders Michel

Шрифт:

Мы смоделировали распределительный вал с кулачком, указывающим точно вниз. Если мы хотим управлять вращением по оси X распределительного вала на входе посредством вращения ведущего вала, мы должны принять во внимание, что он двигается на половинной скорости. Кроме того, его задержки вращения немного отстают, чтобы соответствовать циклу воспламенения цилиндра, поскольку он открывает входной клапан на начальном движении вниз и закрывает клапан как раз перед искрой воспламенения:

ob('DriveShaftPart').RotX/(2*m.pi)*18+9

Выражение для распределительного вала на выходе почти идентично за исключением времени запаздывания (здесь 24, но настройка этого двигателя не совсем соответствует реальной механике):

ob('DriveShaftPart').RotX/(2*m.pi)*18+24

Движение поршня ограничено только по вертикали, но его точное движение более сложно для вычисления. Нас интересует длина отрезка Q — смотрите предыдущий рисунок — и расстояние между центром ведущего вала и точкой, где шатун (L на диаграмме) соединяется с поршнем. Поскольку длина шатуна постоянна, изменение Q будет функцией от угла поворота ведущего вала. Расстояние от центра ведущего вала, до точки, где шатун связан с ведущим валом, фиксировано. Мы назовем это расстояние R. Теперь у нас есть треугольник со сторонами Q, L, и R и известен угол . Поскольку три из этих данных (L, R, и ) известны, мы можем вычислить Q, при использовании теоремы косинусов . Поэтому мы определяем функцию

q
в файле
pydrivers.py
, которая возвращает длину Q, при заданных L, R, и :

 def q(l,r,a): return r*cos(a)+sqrt(l**2-(r*sin(a))**2)

Выражение для канала поршня

LocZ
просто обращается к этой функции с соответствующими значениями аргументов:

p.q(1.542,0.655,ob('DriveShaftPart').RotX)

Точные значения для L и R были взяты из меша, используя координаты соответствующих вершин шатуна и ведущего вала в окне

Transform Properties
. (кнопка N в окне 3D-вида)

Для самого шатуна можно использовать то же выражение для

LocZ
– канала, но нужно так тщательно сделать соединение поршня и шатуна, чтобы они точно совпадали.

Однако, движение шатуна не ограничено только перемещением по оси Z, так как он вращается вокруг оси X с центром в точке, соединяющей шатун с поршнем. Угол вращения ( на диаграмме) можно вывести из значений L, R, и :

def topa(l,r,a):

Q=q(l,r,a)

ac=acos((Q**2+l**2-r**2)/(2*Q*l))

if a%(2*pi)>pi : ac = -ac

return -ac

Pydriver выражение для RotX будет выглядеть вот так:

m.degrees(p.topa(1.542,0.655,ob('DriveShaftPart').RotX))/1 0.0

Впускной и выпускной клапаны управляются вращением их соответствующих распределительных валов. Очертание кулачка очень сложно, так что здесь мы используем не фактическую форму его контура, а аппроксимируем ее, она выглядит достаточно хорошо (то есть, открытый клапан в функции еще оживленное движение в правильном моменте). Следующая картинка показывает движение клапана как функцию от угла вращения:

< image l:href="#"/>

Наконец, в

pydrivers.py
мы определяем функцию
spike
, которая принимает угол поворота распределительного вала как аргумент и возвращает значение между
0.0
и
1.0
которое резко возрастает в районе нулевого угла:

def spike(angle):

t = (cos(angle)+1.0)/2.0

return t**4

Сейчас клапан движется линейно, но линия, по которой он следует, наклонена на 10 градусов (вперед для впускного клапана, назад для выпускного клапана), теперь нам придется управлять двумя каналами, LocZ и LocY, каждый нужно умножить на правильное значение для создания наклонного движения. Поэтому мы определим две функции в

pydrivers.py
:

def valveZ(angle,tilt,travel,offset):

return cos(radians(tilt))*spike(angle)*travel+offset

def valveY(angle,tilt,travel,offset):

return sin(radians(tilt))*spike(angle)*travel+offset

Обе функции возвращают расстояние в зависимости от угла поворота управляющего объекта.

Tilt
(наклон) - наклон клапана (в градусах),
travel
— максимальная длина пути, по которому проходит клапан вдоль наклонной линии, а
offset
(компенсация) - значение, которое позволяет регулировать позицию клапана. Соответствующие pydriver– выражения для
LocZ
и
LocY
– каналов впускного клапана:

p.valveZ(ob('CamInlet').RotX+m.pi,-10.0,-0.1,6.55)

и

p.valveY(ob('CamInlet').RotX+m.pi,-10.0,-0.1,-0.03)

(Выражения для выпускного клапана аналогичны, но с положительным углом

tilt.
)

До сих пор, все IPO-каналы были каналами объекта, такими как расположение и вращение. Но также возможно управлять другими каналами, ведь нам нужно изменять энергию лампы, помещенной в свечу зажигания. В

pydrivers.py
мы для начала определим вспомогательную функцию
topi
, которая, в качестве аргументов, кроме угла вращения движущегося объекта принимает угол
h
(в радианах) и интенсивность
i. topi
возвращает эту интенсивность, если угол двигающегося объекта находится между
0
и
h
, и ноль, если угол выйдет за пределы этого ряда. Поскольку угол на входе функции, возможно больше, чем 2*pi (когда двигающийся объект пройдет больше чем полный круг), мы исправляем это выделенной операцией деления по модулю:

def topi(a,h,i):

m = a%(2*pi)

r=0.0

if m<h: r=i

return r

pydriver– выражение для канала энергии (называемый "Energ" в редакторе Кривых IPO), может быть выражено следующим образом:

p.topi(ob('DriveShaftPart').RotX/2+m.pi,0.3,0.5)

Как видно, это выражение запустит «огонь» в свече зажигания при первых 17 градусах (0.3 радиан), установив энергию для этого цикла в 0.5 .

Больше мощности — комбинирование нескольких цилиндров в двигателе

Как только мы смоделировали один цилиндр и позаботились о управлении движением отдельных частей, нашим следующим шагом будет дублирование цилиндров, для создания мотора как на вводной иллюстрации этой главы. В принципе мы можем просто выделить все и продублировать, нажав Shift + D, отрегулировав время срабатывания каждого IPO-канала.

Но есть препятствие. Если мы используем Shift + D, вместо Alt + D мы получим одинаковые копии мешей объектов, вместо того чтобы просто воспользоваться ссылкой на первый объект. К тому же, мы ожидаем, что скопировали и остальные атрибуты объекта, такие как материалы, текстуры и IPO. Блендер, по-умолчанию, не дублирует вышеперечисленные категории, копируя только сам объект. Это получится неуклюже, так как изменение IPO первого поршня, к примеру, затронуло бы все остальные.

Мы могли бы сделать остальные копии уникальными впоследствии (нажав на поле количества пользователей этих кривых IPO, например, и подтвердив своё согласие со всплывающим вопросом make single user?), но было бы слишком утомительным повторять это для каждой копии отдельно.

Лучшим способом будет изменить настройки копирования объектов (Duplicate with object) в панели Edit Methods, как показано на скриншоте выше. Таким образом, кривые IPO, связанные с объектом, будут превращены в уникальные копии при дублировании объекта.

Поделиться с друзьями: