материалы :: физика и математика. часть 1.
 
-------------------------
>DHTML лаборатория
-------------------------
>Новости
Архив (8.5.2003)
Архив (18.4.2003)
Архив (4.4.2003)
Архив (24.3.2003)
Архив (7.3.2003)
Архив (18.2.2003)
Архив (4.2.2003)
Архив (21.1.2003)
Архив (6.1.2003)
Архив (23.12.2002)
-------------------------
>Лаборатория
Лабиринт
Scorch
Машинка
Пуповина
Соты
Мост
Кривые
С Новым Годом!
Снежок
Рыбки вернулись
Рыбки
Аркада
Микромашинка
-------------------------
>Материалы
Прелоадинг. Часть 1.
Физмат. Часть 1.
Календарь
Чат, чтоб не молчать
-------------------------
>Ссылки
VM Studio
Флэш Потрошитель
Flasher.ru
Ivan Dembicki
actionscript.org
junioronline
bit-101
flashcomponents
...
-------------------------

-------------------------
>Контакты
>Загрузить Flash
>Translate

>Поиск на сайте


-------------------------
Хостинг от UkrHosting
 
Как ни странно, но с появлением во Флаш достаточно мощного и простого языка программирования толпы народу потянулись к учебникам по математике и физике. Казалось бы…, Action Script , пожалуй, по скорости уступает доброй сотни языков программирования. Но доступность, прозрачность действий, продвинутая объектная модель языка взяла свое. И такие незатейливые задачи как движение объекта, ускорение, гравитация, столкновения, имитация простой динамики - вполне по силам Action Script. Статья, скорее всего, адресуется человекам, которые уже что-то смыслят в Action Script, но в школе прогуливали математику и физику. Прошу прощения за мой литературный и за чрезмерную розжеваноость. В свое время я бы с удовольствием об этом почитал, поэтому вот...

Если говорить о прямолинейном поступательном движении, то тут нет ничего сложного: объект движется все время в одном направлении. Через определенный интервал времени просто к текущим его координатам X, Y - добавляем какие-нибудь значения dX и dY соответственно.

рис. 1

На рис. 1 изображены оси координат. Точка отсчета находится в верхнем левом углу(как на мониторе). Объект двигается с т. А к точке В. Приращиваем dX и dY . Если в следующие моменты времени мы будем добавлять к текущим координатам dX и dY - объект будет двигаться поступательно и прямолинейно. Попытаемся изменить ситуацию. В определенный момент времени изменим координаты объекта на dX_2 и dY_2. В данном случае величина dX равняется dX_2, но dY и dY_2 - разные. Траектория изменилась на криволинейную. Траектории бывают разные: парабола, гипербола, круг, квадрат… короче дофига всякого. Например, тело, брошеное под углом к горизонту, рисует в небе параболу:

рис. 2

Как же заставить наше виртуальное тело описывать разнообразные траектории?
Разберем примерчик и смоделируем полет ядра.
Из школьного учебника по физике можно узнать, что тело, брошенное под углом к горизонту с определенной скоростью описывает параболу и в конечном итоге упадет.:) А еще, во время своего полета , его dX остается неизменным. Т. е. - если наблюдать траекторию полета с ребра -увидим прямолинейное поступательное движение. С dX уже проще. А вот с dY дело обстоит посложнее. С рисунка видно, что dY со временем уменьшается, и в наивысшей точке равняется нулю. Потом опять его абсолютная величина увеличивается (но уже с обратным знаком) и тело падает на землю. Например, если начальное значение dY=10, то изменяться оно будет так: 10, 9, ... 2, 1, 0, -1, -2, ... , -9 ,-10. В данном случае величина, на которую изменялось dY равняется единице. В природе, например, эта величина составляет 9.8м/с*с(ускорение свободного падения), и еще сопротивление воздуха. Но это уже детали. Вот простой примерчик:


Вот весь код для нашего тела:
onClipEvent (enterFrame) {
if (_root.polet == 1) {
_x += _root.dX;
_y += -_root.dY;
_root.dY -= _root.g;
_root.dYTxt.text=_root.dY;
if (_y>190) {
_root.polet = 0;
}
}
}

код для кнопки "go":
on (press) {
telo._x = 10;
telo._y = 190;
_root.dX = 2;
_root.dY = 5;
_root.g = 0.1;
_root.polet = 1;
}

Вроде уже кое-что. :)
Тело летит, похоже, даже немного реалистично. Изменяя начальные значения dX, dY, g на свои можно изменить траекторию. Все это подходит для частного варианта. А что если угол, под которым брошено тело, должен изменяться? Или, скорость(ведь тело можно бросить под одним углом, и при разных начальных скоростях оно поведет себя по разному)? Следовательно dX и dY нужно прощитать, исходя из заданного угла. Тут и приходит на помощь математика.
Нельзя не заметить два фиолетовых прямоугольных треугольника на рис 1. Катеты каждого равняются соответственно: dX, dY и dX_2, dY_2.
Давайте присмотримся к прямоугольному треугольнику:
рис. 3

Обозначим углы как angleA, angleB, angleC соответственно. A, B и С - это твершины, a, b, с - это стороны. angleA =90°, b, c - катеты, a - гипотенуза.
Вот теоремы и тождества, которые нам пригодятся:
Теорема синусов:
a / sin(angleA) = b / sin(angleB) = c / sin(angleC) (1)
Иными словами: сторона, разделенная на синус противоположного угла для всех углов отдельно взятого треугольника - одинакова.
Рассмотрим схему полета:
рис. 4
Все внимание на сиреневый треугольник. V0 - это вектор скорости, и, по совместительству гипотенуза треугольника. Катеты - dX и dY. Не смущайтесь, что вектор скорости выполз за траекторию движения тела. Это просто схема. Если сложить из очень маленьких векторов нашу параболу - из далека она покажется плавной, тем более в движении. Тут важно не переборщить с дисритизацией. dX и dY должны быть оптимальными величинами. Если они будут слишком малыми - теряем производительность, если большие - теряем плавность движения.
Итак, сиреневый треугольник с углом между катетами и начальной скоростью - гипотенузой. Из перечисленного нам известны:
начальная скорость и угол.
Нужно узнать:
dX и dY.
Перенесём и приведем его к понятному виду:
рис. 5
Ищем dY.
По теореме синусов (1):
c/sin(90)=a/sin(angleA) или
Vo/sin(90)=dY/sin(angleA).
Выводим dY:
dY = Vo* sin(angleA)/ sin(90).
Sin(90) = 1 , поэтому:
dY = Vo* sin(angleA)
Как видно dY есть ни что иное, как скорость умноженная на синус угла, под которым брошено тело.
Теперь ищем dX:
По теореме синусов (1):
c/sin(90)=b/sin(angleB)
Vo/sin(90)=dX/sin(angleB).
Выводим dX:
sin(angleB)=sin(90-angleA)=cos(angleA) (это объясняется тем, что сумма всех углов треугольника всегда = 180 градусов. Если angleC у нас = 90, то сума осталных тоже 90. Поэтому angleB=90-angleA. Справедливо равенство sin(90-angleA)=cos(angleA). Вот так у нас появляется косинус.)
В итоге:
dX = Vo* cos(angleA);
Все вместе:
dY = Vo* sin(angleA);
dX = Vo* cos(angleA);

То, что надо.
Давайте применим это на практике.

Введите свои данные и нажмите кнопку "go".
Вот весь код для нашего тела:
onClipEvent (enterFrame) {
if (_root.polet == 1) {
_x += _root.dX;
_y += -_root.dY;
_root.dY -= _root.g;
if (_y>190) {
_root.polet = 0;
}
}
}

код для кнопки "go":
on (press) {
telo._x = 10;
telo._y = 190;
_root.g = 0.1;
_root.dY = speed*Math.sin(Math.PI/180*(angle));
_root.dX = speed*Math.cos(Math.PI/180*(angle));
_root.polet = 1;
}

Все ясно, надеюсь. Угол для синусов и косинусов в Action Script задается не в градусах, а в радианах. Чтобы преобразовать градусы в радианы пользуйтесь формулой: Math.PI/180*(angle).
Как известно, угол падения равен углу отражения. Перепишем скрипт для тела, и теперь оно будет отскакивать от земли и от правой серой стенки:
onClipEvent (enterFrame) {
if (_root.polet == 1) {
_x += _root.dX;
_y += -_root.dY;
_root.dY -= _root.g;
if (_y>190) {
_root.dY = -_root.dY;
}
if (_x>240) {
_root.dX = -_root.dX;
}
}
}

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


Скачать исходники: math.zip

Материал подготовил: syoPic