![]() |
| Устройство двигателя внутреннего сгорания |
Сначала мы изобразим этот механизм упрощенно (а в следующих уроках добавим графику).
| Рассматриваемый механизм в произвольном положении |
В качестве исходных данных принимаем:
- в начальном положении поршень находится в верхней мертвой точке (ВМТ), т.е. угол φ = 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 для построения моделей механизмов. В дальнейшем мы будем совершенствовать наши примеры, используя существующие библиотеки.







