SCRIPT.com.ua
Логин: Пароль:
Регистрация Забыл пароль
МАТЕРИАЛЫ
Поиск
Новости
Материалы
Работа с WDDX в РНР [PHP]
Рецепт по установке web-сервера под Windows [PHP]
Инициализация для Flash Player 8 Beta [Flash]
Криптование [Action Script]
Настрока Homesite под Action Script [Action Script]
Учитесь писать код правильно [PHP]
Пасхальные яйца. [Action Script]
Flash-игры: проще, если знаешь как [Flash]
Установка Ming под win32 Apache+PHP [Action Script]
Wysiwyg HTML Редакторы [DHTML]
Исходники
"Объект" на JavaScript - аналог AsBroadcaster [DHTML]
Запрет кэширования [HTML]
Полупрозрачные картинки, которые 'востанавливаются' при наведении. [DHTML]
Новостная лента v1.2.1 [PHP]
Обход XML-дерева [Action Script]
CDATA и комментарии [XSL]
Кроссразмерный полноэкранный режим [Action Script]
KeyListener [Action Script]
Редирект [HTML]
Текстовый узел [XSL]
Лаборатория
Документация
Файлы
Ссылки
Пользователи
Контакты
Наш выбор
Need for Speed Most Wanted
Наши партнеры
Четверг, 11 Марта, 2004
Физика и математика. часть 1 [Action Script]
Как ни странно, но с появлением во Флаш достаточно мощного и простого языка программирования толпы народу потянулись к учебникам по математике и физике. Казалось бы…, Action Script , пожалуй, по скорости уступает доброй сотни языков программирования. Но доступность, прозрачность действий, продвинутая объектная модель языка взяла свое. И такие незатейливые задачи как движение объекта, ускорение, гравитация, столкновения, имитация простой динамики - вполне по силам Action Script. Статья, скорее всего, адресуется человекам, которые уже что-то смыслят в Action Script, но в школе прогуливали математику и физику. Прошу прощения за мой литературный и за чрезмерную розжеваноость. В свое время я бы с удовольствием об этом почитал, поэтому вот...

Если говорить о прямолинейном поступательном движении, то тут нет ничего сложного: объект движется все время в одном направлении. Через определенный интервал времени просто к текущим его координатам X, Y - добавляем какие-нибудь значения dX и dY соответственно.
рис. 1На рисунке изображены оси координат. Точка отсчета находится в верхнем левом углу(как на мониторе). Объект двигается с т. А к точке В. Приращиваем dX и dY . Если в следующие моменты времени мы будем добавлять к текущим координатам dX и dY - объект будет двигаться поступательно и прямолинейно. Попытаемся изменить ситуацию. В определенный момент времени изменим координаты объекта на dX_2 и dY_2. В данном случае величина dX равняется dX_2, но dY и dY_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 нужно прощитать, исходя из заданного угла. Тут и приходит на помощь математика.
Нельзя не заметить два фиолетовых прямоугольных треугольника на рисунке. Катеты каждого равняются соответственно: dX, dY и dX_2, dY_2.
Давайте присмотримся к прямоугольному треугольнику:
Обозначим углы как angleA, angleB, angleC соответственно. A, B и С - это твершины, a, b, с - это стороны. angleA =90°, b, c - катеты, a - гипотенуза.
Вот теоремы и тождества, которые нам пригодятся:
Теорема синусов:
a / sin(angleA) = b / sin(angleB) = c / sin(angleC) (1)
Иными словами: сторона, разделенная на синус противоположного угла для всех углов отдельно взятого треугольника - одинакова.
Рассмотрим схему полета:

Все внимание на сиреневый треугольник. V0 - это вектор скорости, и, по совместительству гипотенуза треугольника. Катеты - dX и dY. Не смущайтесь, что вектор скорости выполз за траекторию движения тела. Это просто схема. Если сложить из очень маленьких векторов нашу параболу - из далека она покажется плавной, тем более в движении. Тут важно не переборщить с дисритизацией. dX и dY должны быть оптимальными величинами. Если они будут слишком малыми - теряем производительность, если большие - теряем плавность движения.
Итак, сиреневый треугольник с углом между катетами и начальной скоростью - гипотенузой. Из перечисленного нам известны:
начальная скорость и угол.
Нужно узнать:
dX и dY.
Перенесём и приведем его к понятному виду:
Ищем 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
Опубликовал: Syo (21:51) | комментарии [3]  | Редактировал: 13.03.2004, 21:51 - Alexander
< назад
Вверх © Copyright 2004-2014 Script.com.ua



Версия для печати