Авторизация
Регистрация

Напомнить пароль

Делаем пепелац и даем концерт на Плюке

Сразу предупреждаю уважаемую публику — мой пепелац будет не совсем аутентичен натуральному. Но я художник, я так вижу.

Узнаваемая форма перевернутого ведра, ржавая корона и гребешок сверху будут сохранены.

Рисовать будем в OpenSCAD. Может быть было бы лучше использовать что-то другое, но там, как правило, нужно иметь хоть какой-то художественный навык и представлять, что ты хочешь нарисовать.

Киса! Я давно хотел вас спросить как художник художника: вы рисовать умеете?

Я вот не умею. А написать какой-нибудь код и посмотреть, что получится — это я запросто.

Короче, пишем код перевернутого ведра — это усеченный цилиндр, покрываем его заклепкам, которых в натуральном пепелаце нет и сверху делаем корону из множества маленьких цилиндриков.

Код ведра
$fn=48;
pi=3.14;
d_bottom=100;
d_top=80;
h_barrel=120;

bucket();

module bucket()
{
  cylinder(d1=d_bottom, d2=d_top, h=h_barrel, center=true);
  translate([0,0,(h_barrel+24)/2]) cylinder(d1=20, d2=16, h=24, center=true);

  // заклепки
  rows_height = 10;  // количество рядов по высоте
  rows_angle  = 12; // количество заклёпок по окружности

  // шаг между рядами
  step = h_barrel / rows_height;

  for (hi = [0 : rows_height - 1])
  for (ai = [0 : rows_angle - 1])
  {
    let (
      z = -h_barrel/2 + step/2 + hi * step,

      // t от 0 до 1 для интерполяции радиуса
      t = (z + h_barrel/2) / h_barrel,

      angle = 360 / rows_angle * ai,

      current_r = (d_bottom/2) * (1 - t) + (d_top/2) * t,

      x = current_r * cos(angle),
      y = current_r * sin(angle),

      slope_angle = atan2((d_bottom - d_top) / 2, h_barrel)
    )
    translate([x, y, z])
      rotate([0, slope_angle, angle])
        scale([0.5, 1, 1])
          sphere(d=4);
  }

  // корона
  for (delta = [0:2])
  for (alpha = [0:19])
    let(
      angle  = 360/20 * alpha + (delta%2 == 1 ? 360/20/2 : 0),
      radius = (d_top/2 - 4) - delta * 7,
      z_pos  = (h_barrel + 10) / 2
    )
    rotate([0, 0, angle])
      translate([radius, 0, z_pos]) {
        cylinder(d1=8-delta, d2=3, h=10, center=true);
        translate([0, 0, 10/2]) scale([1, 1, 0.8]) sphere(d=3);
      }
}

Согласитесь, это выглядит намного проще, чем рисовать руками, обладая способностями Остапа Бендера к рисованию?

Теперь рисуем шасси.

Код лап пепелаца
$fn=48;

leg();

module leg()
{
  leg_width = 8;
  leg_height = 25;
  leg_depth = 40;
  points = [
        [0, 0],           // точка 1
        [leg_width, 0],   // точка 2
        [11, 15],         // точка 3
        [0, leg_depth],   // точка 4
        [12, leg_depth]   // точка 5
    ];
  for (angle = [0:120:240]) 
  {
    rotate([angle,0,0]) translate([0, -30,0]) 
    {
      translate([0, -41.5,0]) difference()
      {
        hull()
        {
          for (p = points) 
            translate([p[0], p[1], 0]) 
              cylinder(d=3, h=leg_height, center=true);
        }
        hull()
        {
          translate([4,5,11])  sphere(d=6);
          translate([6,33,12])  sphere(d=8);  
        }
        hull()
        {
          translate([4,5,-11])  sphere(d=6);
          translate([6,33,-12])  sphere(d=8);  
        }
      }
      translate([12,-26, 0]) cylinder(d=8, h=10, center=true);
      translate([26,-5, 0]) rotate([-60,90,0]) shock_absorber();
      translate([24,2, 0]) rotate([-20,90,0]) cylinder(d=10, h=40, center=true); 
      
    }
  }
}

module shock_absorber()
{
  cylinder(d=8, h=14, center=true);
  translate([0,0, 8]) cylinder(d1=8, d2=5, h=2, center=true);  
  translate([0,0, -8]) cylinder(d1=5, d2=8, h=2, center=true);  
  translate([0,0, -12]) cylinder(d=5, h=26, center=true);    
}

 

Самое интересное с точки зрения программирования в этом проектике — это гребешок. Он хоть и не очень похож на натуральный, зато его печатать можно без поддержек.

Код гребешка

$fn=48;

x = 50;
y = 6;
steps = 36;   // количество сегментов

kx = 0.95;
ky = 0.98;
dz = 1.5;     // шаг по высоте (Z)
ka = 6;       // угол загиба за один шаг (градусы)
ksh = 0.4;    // сдвиг по X за один шаг

head();

module head()
{
 difference()
 {
   union()
   {
     hull()
     {
       cylinder(d=30, h=5, center=true); 
       translate([20,0,0])  cylinder(d=10, h=5, center=true);   
       translate([-20,0,0])  cylinder(d=10, h=5, center=true);   
     }
     translate([0,-11,7]) rotate([-140,0,0]) snake_outer(0, x, y);    
     translate([0,0,3])cylinder(d=12, h=7, center=true); 
   }
   cylinder(d=5.2, h=20, center=true);   
 }
 translate([0,-11,7])
 {
   rotate([0,90,0])  cylinder(d=6, h=48, center=true);   
   translate([-48/2,0,0]) sphere(d=6);
   translate([48/2,0,0]) sphere(d=6);
 }
}

// Рекурсивный модуль 
module snake_outer(i, cx, cy) 
{
 if (i < steps) 
 {
   hull()
   {
     // текущий сегмент
     cube([cx, cy, 0.1], center=true);
           
     // следующий сегмент
     translate([ksh, 0, dz])
       rotate([ka, 0, 0])
         cube([cx * kx, cy * ky, 0.1], center=true);
   }
       
   // рекурсия — следующий шаг
   translate([ksh, 0, dz])
     rotate([ka, 0, 0])
       snake_outer(i + 1, cx * kx, cy * ky);
 }
}

Модуль, совершенно согласен с вами, переусложненный, но он был сделан, как часть чего-то другого, я его просто скопипастил сюда.

Теперь собираем все вместе, делаем ниши под шасси и выдавливаем дверь-рампу и вуаля! — пепелац готов.

 

Полностью проект с исходниками лежит здесь.

Печатаем его и ставим в сторонку — больше он нам не понадобится.

 

Но впереди у нас — полет на Плюк. И концерт с неизменным шлягером «Мама, мама, что я буду делать?»

Вселенную, вернее, какую-то ее часть, сопрем из Интернета, сам Плюк сгенерируем Gemini.

Начальную часть кина с полетом к Плюку мы делаем с помощью ffmpeg и bash скрипта.

bash полета
#!/bin/bash

# Создаем временную папку
TEMP_DIR="temp_frames_$$"
mkdir -p "$TEMP_DIR"

# Проверяем, что входные файлы существуют
if [ ! -f "stars.png" ]; then
    echo "Ошибка: файл stars.png не найден!"
    exit 1
fi

if [ ! -f "pluk2.png" ]; then
    echo "Ошибка: файл pluk2.png не найден!"
    exit 1
fi

# Настройки
TOTAL_FRAMES=480
FPS=24
DURATION=10
BG_WIDTH=1920
BG_HEIGHT=1080
CENTER_X=$((BG_WIDTH / 2))
CENTER_Y=$((BG_HEIGHT / 2))

START_CENTER_X=1600
START_CENTER_Y=200
END_CENTER_X=$CENTER_X
END_CENTER_Y=$CENTER_Y

MIN_SIZE=5
MAX_SIZE=2500

echo "Создаю $TOTAL_FRAMES кадров с равными интервалами..."
echo "Фон: ${BG_WIDTH}x${BG_HEIGHT}"
echo ""

# Функция для вычислений с плавающей точкой
calc() {
    echo "scale=10; $1" | bc -l
}

# Генерируем кадры с ФИКСИРОВАННОЙ задержкой
for ((i=0; i<TOTAL_FRAMES; i++)); do
    # Прогресс 0..1
    T=$(calc "$i / ($TOTAL_FRAMES - 1)")
    
    # Ease-in: t^2
    EASED=$(calc "$T * $T")
    
    # Размер
    SIZE=$(calc "$MIN_SIZE + ($MAX_SIZE - $MIN_SIZE) * $EASED")
    SIZE_INT=$(printf "%.0f" "$SIZE")
    
    # Позиция центра
    CX=$(calc "$START_CENTER_X + ($END_CENTER_X - $START_CENTER_X) * $EASED")
    CY=$(calc "$START_CENTER_Y + ($END_CENTER_Y - $START_CENTER_Y) * $EASED")
    
    # Overlay (верхний левый угол)
    OX=$(calc "$CX - $SIZE / 2")
    OY=$(calc "$CY - $SIZE / 2")
    OX_INT=$(printf "%.0f" "$OX")
    OY_INT=$(printf "%.0f" "$OY")
    
    OUTPUT_FILE="$TEMP_DIR/frame_$(printf "%05d" $i).png"
    
    # Прогресс
    if (( i % 20 == 0 )); then
        PERCENT=$(printf "%.0f" $(calc "$i * 100 / ($TOTAL_FRAMES - 1)"))
        echo "Кадр $((i+1))/$TOTAL_FRAMES ($PERCENT%): size=${SIZE_INT}px, pos=($OX_INT,$OY_INT)"
    fi
    
    # Генерируем кадр
    ffmpeg -i stars.png \
           -i pluk2.png \
           -filter_complex "[1:v]scale=$SIZE_INT:$SIZE_INT:flags=lanczos,format=rgba[p];[0:v][p]overlay=$OX_INT:$OY_INT:format=auto" \
           -vframes 1 \
           -y "$OUTPUT_FILE" 2>/dev/null
    
    if [ ! -f "$OUTPUT_FILE" ]; then
        echo "❌ Ошибка на кадре $((i+1))"
        exit 1
    fi
done

echo -e "\nСобираю видео с постоянной частотой кадров..."

# Собираем видео с ТОЧНОЙ частотой кадров
ffmpeg -framerate $FPS -i "$TEMP_DIR/frame_%05d.png" \
       -c:v libx264 -preset medium -crf 18 \
       -pix_fmt yuv420p \
       -r $FPS \
       output.mp4 -y 2>/dev/null

if [ -f "output.mp4" ]; then
    echo "✅ Видео создано: output.mp4"
    
    # Проверяем реальную частоту кадров
    echo ""
    echo "=== Проверка видео ==="
    ACTUAL_FPS=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 output.mp4)
    echo "Частота кадров: $ACTUAL_FPS"
    
    # Удаляем временную папку (опционально)
    # rm -rf "$TEMP_DIR"
else
    echo "❌ Ошибка при создании видео!"
fi

Дальше нам понадобится несколько ключевых кадров, генерируем их с помощью Gemini. Штук 20 картинок в сутки он генерирует нахаляву, для нашего ролика этого хватит.

Сначала пепелац в разных ракурсах:

Потом сцена 

 

Более безумной мысли, чем использовать слайд с изображением супруги, сделанный лет 40 тому назад, в качестве певицы, мне не пришло. А что? — получилось очень похоже.

Бесплатно видео ролики с длительностью 5 секунд и заданным первым кадром делает https://www.meta.ai

С этими роликами издеваемся с помощью команд ffmpeg — где его задом наперед запустим, где разобьем на кадры, чтобы последний кадр 5-секундного ролика использовать, как первый для следующей последовательности. С его же помощью из картинок можно сшить видео и из кусков видео весь клип. Звуковую дорожку добавляем им же.

Полезные команды ffmpeg
разбивка на кадры
ffmpeg -i orchestra2_0.mp4 -q:v 1 -start_number 0 orchestra2/img%05d.png

комбинация - сборка кадров
ffmpeg -framerate 24 -i img%05d.png -c:v libx264 -pix_fmt yuv420p output.mp4

сборка видео
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

инверсия
ffmpeg -i input.mp4 -vf reverse -c:v libx264 -an output.mp4

кроссфейд
ffmpeg -loop 1 -i start.jpg -loop 1 -i end.jpg -filter_complex "[0:v][1:v]xfade=transition=fade:duration=2:offset=0" -t 2 -c:v libx264 -r 24 -an output.mp4

первый кадр
ffmpeg -i input.mp4 -frames:v 1 output.png

слить видео и аудио
ffmpeg -i Pluk.mp4 -i clip.mp3 -c:v libx265 -crf 32 -preset fast -c:a aac -b:a 96k -movflags +faststart output.mp4

выделить звук из mp4
ffmpeg -i sound.mp4 -vn -acodec libmp3lame output.mp3

midi в mp3
timidity input.mid -Ow -o - --output-mono | ffmpeg -i - -ac 1 -c:a libmp3lame -b:a 192k output.mp3

вырезать из MP3 всё лишнее
ffmpeg -i "melody.mp3" -vn -c:a copy -map_metadata -1 "melody1.mp3"

В итоге имеем вот такой клип:

Если youtube не работает — можно посмотреть тут: https://vkvideo.ru/video-238066715_456239018

Похоже, сайт позволяет встраивать видео только с youtube, поэтому на vkvideo я могу дать только ссылку.

Какой халявой я пользовался в концерте

  • https://suno.com/create — пишем музыку и поем песни
  • Выступление конферансье — https://elevenlabs.io
  • https://elevenlabs.io/sound-effects — звуковые эффекты
  • OpenShot Video Editor — монтаж звуковой дорожки
  • Использованы мелодии Ievan Polkka — хотя в оригинале там только вокал на непонятном диалекте финского.
  • Старая добрая Mambo no5

 

С ИИ ресурсами ситуация очень нестабильная — что-то вчера еще работало бесплатно, а сегодня уже денег просит — меркантильные кю. Зато появилось что-то еще — возможно, даже лучше. Уследить за этим невозможно, пока кто-то строчит статьи или снимает видосики — ситуация уже поменялась и информации стала абсолютно бесполезной. Бесплатные локальные ИИ программы по возможностям за коммерческими не поспевают и требуют видеокарт все толще и толще. У меня стоит машина с картой RTX 3050 c 8Gb видеопамяти — сейчас это абсолютный минимум, который работает с самыми легкими моделями и даже с ними требует танцев с бубнами.

 Для тех, кто дочитал до конца — вот еще мультик по мотивам «Крылья, ноги и хвосты», сделанный для внучки. Правда, она не оценила — дескать, чем бы дедушка не занимался, лишь бы водку не пил.

Посмотреть можно тут, встроить мне его не удалось: vkvideo.ru/video-238066715_456239017

 

 

 

 

Добавить в избранное
+11 +12
свернутьразвернуть
Комментарии (8)
RSS
+
avatar
0
Без гравицапы летает?
+
avatar
+2
Да, но очень медленно
+
avatar
0
И низенько-низенько, как крокодилы ;-)
+
avatar
0
А если колёса прикрутить, то и без луца сможет
+
avatar
0
чем бы дедушка не занимался, лишь бы водку не пил
А думаю, почему гравицапы нет, а оно вон чего.
+
avatar
+9
+
avatar
0
написать какой-нибудь код и посмотреть, что получится — это я запросто
тоже чаще проще и быстрее в SVG программно чего-то «нарисовать», чем мучиться с Inkscape
+
avatar
-1
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.