Устройство двигателя внутреннего сгорания |
Сначала мы изобразим этот механизм упрощенно (а в следующих уроках добавим графику).
Рассматриваемый механизм в произвольном положении |
В качестве исходных данных принимаем:
- в начальном положении поршень находится в верхней мертвой точке (ВМТ), т.е. угол φ = 0 градусов (все звенья вытягиваются в линию);
- длину кривошипа AB принимаем равной 50 пикселей;
- длину шатуна ВС принимаем равной 200 пикселей;
- скорость вращения кривошипа принимаем произвольной, например 0,1 радиан за кадр.
Положение точки А неизменно (она неподвижна):
Координаты точки В зависят от угла поворота кривошипа AB. Выразить эту зависимость не составит труда тем, кто совсем немного помнит школьное определение синуса и косинуса в прямоугольном треугольнике:
С расчетом положения точки С немного сложнее, здесь нам поможет теорема синусов. Рассмотрим треугольник АВС, по теореме синусов имеем следующее соотношение:
отсюда:
Теперь нам осталось лишь выразить все эти зависимости в коде:package { // Импорт необходимых классов import flash.display.Sprite; import flash.events.Event; // Объявление класса public class Mechanism extends Sprite { // Основные размеры механизма: // // Длина кривошипа АВ private var a:Number = 50; // Длина шатуна ВС private var b:Number = 200; // Угловые параметры, характеризующие положение механизма // // Угол поворота кривошипа private var phi:Number = 0; // Угол поворота шатуна private var psi:Number; // Угловая скорость кривошипа private var angularVelocity:Number = 0.1; // Положение неподвижной точки кривошипа (точки А) private var oporaX:Number; private var oporaY:Number; // Символы для отображения характерных точек механизма // // Точка А private var sharnirOne:Sprite; // Точка В private var sharnirTwo:Sprite; // Точка С private var sharnirThree:Sprite; // Ползун private var polzun:Sprite; // Конструктор класса public function Mechanism(oporaX:Number = 0, oporaY:Number = 0):void { this.oporaX = oporaX; this.oporaY = oporaY; if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } // Инициализация класса private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // Расчет начального положения механизма startPosition(); // Добавление автоматического обновления состояния механизма addEventListener(Event.ENTER_FRAME, onEnterFrame); } // Расчет начального положения механизма // (поршень находится в верхней мертвой точке) private function startPosition():void { sharnirOne = makeSharnir(oporaX, oporaY); addChild(sharnirOne); sharnirTwo = makeSharnir(oporaX + a, oporaY); addChild(sharnirTwo); polzun = makePolzun(oporaX + a + b, oporaY); addChild(polzun); sharnirThree = makeSharnir(oporaX + a + b, oporaY); addChild(sharnirThree); } // Расчет и отрисовка текущего положения механизма private function onEnterFrame(e:Event):void { // Обновление значения угла поворота кривошипа phi += angularVelocity; // Обновление положения точки В: sharnirTwo.x = oporaX + a * Math.cos(phi); sharnirTwo.y = oporaY + a * Math.sin(phi); psi = Math.asin(a * Math.sin(phi) / b); var ac:Number = a * Math.cos(phi) + b * Math.cos(psi); polzun.x = oporaX + ac; // Обновление положения точки С: sharnirThree.x = oporaX + ac; // Очистка экрана this.graphics.clear(); this.graphics.lineStyle(2, 0x000000); // Отрисовка звеньев АВ и ВС: drawStergen(sharnirOne, sharnirTwo); drawStergen(sharnirTwo, sharnirThree); } // Отрисовка ползуна private function makePolzun(x:Number, y:Number):Sprite { var polzun:Sprite = new Sprite(); polzun.graphics.lineStyle(2, 0x000000); polzun.graphics.beginFill(0x0099ff); polzun.graphics.drawRect( -15, -8, 30, 16); polzun.graphics.endFill(); polzun.x = x; polzun.y = y; return polzun; } // Отрисовка стержневых звеньев private function drawStergen(spr1:Sprite, spr2:Sprite):void { this.graphics.moveTo(spr1.x, spr1.y); this.graphics.lineTo(spr2.x, spr2.y); } // Отрисовка характерных точек механизма private function makeSharnir(x:Number, y:Number):Sprite { var sharnir:Sprite = new Sprite(); sharnir.graphics.lineStyle(2, 0x000000); sharnir.graphics.beginFill(0x0099ff); sharnir.graphics.drawCircle(0, 0, 4); sharnir.graphics.endFill(); sharnir.x = x; sharnir.y = y; return sharnir; } } }
Сохраните этот код в файле Mechanism.as. Вы уже можете скомпилировать данный файл (для этого в панели менеджера проекта щелкните по нему правой кнопкой мыши и в появившемся меню выберите пункт “Always Compile” и нажмите клавишу F5). Но можно пойти немного дальше – изменить положение механизма на плоскости, для этого создадим еще один класс Main, сделав его главным классом проекта:
package { import flash.display.Sprite; public class Main extends Sprite { public function Main() { var mechanism:Mechanism = new Mechanism(); mechanism.x = 100; mechanism.y = 100; mechanism.rotation = 45; addChild(mechanism); } } }
Если у Вас после компиляции видна только часть механизма, то нужно просто изменить свойства проекта. Для этого в меню Project выбираем пункт “Properties…” и в появившемся окне изменяем размеры (Dimensions) выходного файла на необходимые (у меня это 350х350 пикселей).
В итоге получим следующую картину:
Если у Вас что-то не получается или Вы не хотите набирать весь код, то можете скачать исходники к этому уроку. Кстати, если хотите попрактиковаться, то попробуйте создать анимацию вот такого механизма (свою реализацию я покажу в одном из следующих постов):
V-образный двигатель |
Кстати, Вы можете найти очень много различных анимированных моделей на этой страничке, к некоторым из них есть исходники (правда они на ActionScript 1.0 и сделаны во Flash IDE)
P.S. Да, я знаю, что этот код не является универсальным и получившейся модели нужны дополнительные детали. Этим примером я хотел показать относительную простоту использования Flash для построения моделей механизмов. В дальнейшем мы будем совершенствовать наши примеры, используя существующие библиотеки.
Здорово! Сразу захотелось сделать паровоз!
ОтветитьУдалитьОчень даже. долго искал хорошие уроки по флеш девелоп. Чтоб и подробно и понятно было. спасибо большое!)
ОтветитьУдалить