Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > C++

Ответ
 
Опции темы
Старый 20.10.2012, 23:29   #1
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Библиотека для моделирования динамических звеньев

Примеры звеньев - смотри тут.
Если вы незнакомы с Теорией Автоматического Управления, то, возможно, вы несколько не понимаете: о чём идёт речь.
Простым языком теория изложена здесь.
Впрочем, чтобы использовать библиотеку на практике - эти знания вам не нужны.

Сразу пример (к сожалению, вам понадобиться Xors3D). Читаем этот топик.
Вот решение с визуализацией (на скорую руку):
#include <xors3d.h>
#include "DynUnit.h"

int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR commandLine, int commandShow)
{
    DynUnitSpace::DynUnit XFilt;
    DynUnitSpace::DynUnit YFilt;

    double T=0.4;//постоянная времени
    double KSI=0.5;//затухание (коэффициент демпфирования)

    double NUM[]={1};
    double DENUM[]={T*T,2*KSI*T,1};

    XFilt.SetParam(NUM,DENUM,sizeof(NUM)/sizeof(double),sizeof(DENUM)/sizeof(double));
    YFilt.SetParam(NUM,DENUM,sizeof(NUM)/sizeof(double),sizeof(DENUM)/sizeof(double));

    xAppTitle("sample");
    int SCRX=800;
    int SCRY=600;
	xGraphics3D(SCRX, SCRY, 32, false, true);
    xMoveMouse(SCRX>>1,SCRY>>1);
    double SEC=xMillisecs()*0.001;
    //"затравочка" - звено не просто усилитель, а с памятью
    XFilt(xMouseX(),SEC);
    YFilt(xMouseY(),SEC);
    int xp,yp;
	while(!xKeyDown(1) || xWinMessage("WM_CLOSE"))
	{
        SEC=xMillisecs()*0.001;
        xp=XFilt(xMouseX(),SEC);
        yp=YFilt(xMouseY(),SEC);

        xCls();
        xOval(xp,yp,20,20,true);
	    xRenderWorld();
	    xFlip();
	}
    return 0;
}
Варьируя два параметра - автор легко получает множество различных типов колебаний. Впрочем - изменив вызовы метода SetParam, можно получить и другие виды следования кружка за мышью, например, медлительное преследование.

Продублирую код заголовочного файла ниже:
/*
Пролистав книгу о принципах магии и не взглянув на обложку,
сложно не решить, что это книга о разработке программного обеспечения.
Bruce Tognazzini
*/

/*
НАЗВАНИЕ БИБЛИОТЕКИ:
    DynUnit
    версия 2012.10.04.1
АВТОР:
    impersonalis (icq: 11-999-51-51)
НАЗНАЧЕНИЕ:
    простая библиотека для работы с динамическими звеньями
ЛИНКУЕМЫЕ БИБЛИОТЕКИ:
    -
ДОПОЛНИТЕЛЬНО СМОТРИ:
    -
*/

#ifndef DYNUNIT_H
#define DYNUNIT_H

//пространство библиотеки
namespace DynUnitSpace{

    //функции для работы с матрицами

    //умножение матрицы M (nxn) на столбец Col (n). Результат в R.
    inline void Multip_MatCol(double *(*M),double *Col,int n,double *R);

    //умножение вектора Col (n) на скаляр S. Результат в R.
    inline void Multip_VecScal(double *Col,double S,int n,double *R);

    //умножение строки Row (n) на столбец Col (n). Результат возвращается
    inline double Multip_RowCol(double *Row,double *Col,int n);

    //сложение векторов (n) и (n). Результат в R.
    inline void Add_VecVec(double *V1,double *V2,int n,double *R);

    /*Алгоритм решателя:
    ODE1 - Метод Эйлера         http://ru.wikipedia.org/wiki/Метод_Эйлера
    ODE2 - Heun's method        http://en.wikipedia.org/wiki/Heun's_method
    ODE4-  Метод Рунге — Кутты  http://ru.wikipedia.org/wiki/Метод_Рунге_—_Кутты
    */
    enum ODE_TYPE{ODE1,ODE2,ODE4};

    //Класс "динамическое звено"
    class DynUnit{
        public:
            DynUnit();  //к-тр
            ~DynUnit(); //д-тр

            //Установить параметры звена
            //NUM - коэффициенты числителя (от высшей к низшей степени)
            //DEN - коэффициенты знаменателя (от высшей к низшей степени)
            //NUMs, DENs - размеры соответсвующих векторов
            //Н.у. - нулевые
            //(только для "остановленного" звена)
            //В случае ошибки вернёт false. Если ошибка произошла - состояние звена
            //не теряется (остаётся прежним).
            bool SetParam(double NUM[],
                          double DEN[],
                          int NUMs,
                          int DENs);

            //Установить н.у. ("стартовое" состояние вектора X)
            //(только для "остановленного" звена)
            //В случае ошибки вернёт false. Если ошибка произошла - состояние звена
            //не теряется (остаётся прежним).
            bool Set0(double X0[]);

            //Установить тип решателя (см. описание ODE_TYPE)
            //(только для "остановленного" звена)
            //В случае ошибки вернёт false. Если ошибка произошла - состояние звена
            //не теряется (остаётся прежним).
            bool SetODE(DynUnitSpace::ODE_TYPE OT);

            //"Остановить" звено
            void Stop();

            //Функтор для работы со звеном:
            //U - входное воздействие
            //CurTime - время в сек. (появления этого воздействия)
            //          время не обязательно должно идти от ометки 0.
            //Выход - выход звена
            //          если звено не простой усилитель, то первый такт вернёт 0.
            double operator()(double U,double CurTime);

            //Получить последний выход (тот что вернул функтор при последнем вызове)
            double GetY()const;

        private:

            //очистить внутернние массивы и флаги
            void clear();

            //флаг звено "работает"
            bool RUN;

            //флаг звено - простой усилитель
            bool booster;

            //коэффициент усиления (при booster=true)
            double MULT;

            //вектор состояния
            double *X;

            //числитель
            double *NUM;

            //знаменатель
            double *DEN;

            //старшая степень числителя и знаменателя соответственно
            int m,n;

            //выход звена
            double Y;

            //controllable canonical form
            double *(*A);
            double *B;
            double *C;
            double D;
            //вспомогательные вектора (см. методы)
            double *K1;
            double *K2;
            double *K3;
            double *K4;
            //
            double LastTime;    //"последнее" время
            double LastU;       //"последнее" входное воздействие
            //
            ODE_TYPE ODE;       //тип решателя
            //
            //временные буферы для вычислений
            double *TMP1;
            double *TMP2;
            double *TMP3;
            double *TMP4;
    };
}
#endif // DYNUNIT_H

Динамическое звено описывается:
во frontend: коэффициентами числителя и знаменателя передаточной функции звена.
в backend: пространство состояний.
Для моделирования необходимо реализовать решение диф.ур-ий.
Библиотека предусматривает три метода (чем, точнее, тем дольше одна итерация решения), переключаемых функцией SetODE
Метод Эйлера (дефолтный решатель)
Heun's method
Метод Рунге — Кутты.

Библиотека протестирована, а её выход сравнён с аналогичными реализациями на MATLAB. За это огромное спасибо Felix (реализация, тестирование, советы).

Несколько страшноватенькая реализация (и, конечно же, тот кто не понял теорию - обязательно упрекнёт меня хоть в этом), а именно - обилие векторов, которые при желании можно было бы объединить в матрицу, объясняется привязкой к исходной математической сущности алгоритмов и моделей. К тому же подобная борьба за красоту ещё сильнее усложнила бы решатели.
Да - я не стал городить класс для работы с матрицами, а набросал конкретные inline-реализации для конечного числа операций с векторами и квадратными матрицами без всяких защит от дурака - это служебные методы библиотеки, и именно поэтому они включены в её пространство. Объектный подход просто чудовищно бы прибил производительность (куча присваиваний и иных манипуляций в решателе на каждый такт). Однако обортная сторона такого подхода - код решателя превратился в набор команд для абстрактного матричного ассемблера. С другой стороны - там вам копаться не придётся.

Пароль от архива
Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 1 сообщение(ий)):
У вас нет прав, чтобы видеть скрытый текст, содержащийся здесь.
Вложения
Тип файла: zip DynVis.zip (3.5 Кб, 519 просмотров)
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 21.10.2012, 01:06   #2
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ответ: Библиотека для моделирования динамических звеньев

Для этой задачи, библиотеку можно использовать тоже (хотя сперва надо всё же разобраться с характером помех).
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 21.10.2012, 03:53   #3
Randomize
[object Object]
 
Аватар для Randomize
 
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,355
Написано 2,471 полезных сообщений
(для 6,852 пользователей)
Ответ: Библиотека для моделирования динамических звеньев

Демку запустить не на чем.
Я понял это нечто вроде easing?
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
(Offline)
 
Ответить с цитированием
Старый 21.10.2012, 05:30   #4
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ответ: Библиотека для моделирования динамических звеньев

Сообщение от Randomize Посмотреть сообщение
Демку запустить не на чем.
Я понял это нечто вроде easing?
На сайте увидел графики, которые могут описывать выход звена от времени при правильном подборе структуры звена (коэффициенты пер.функ.) и входном воздействии.
На сайте, как я понял, представлена коллекция функций от времени с фиксированным параметром x. Иными словами - частные случаи. Так что ответ на вопрос - "да".

Представь, что между указателем мыши и объектом находится пружина. Как будет выглядеть функция горизонтальной координаты, когда ты переместишь мышь из позиции 121px в 348px за 1.2сек? При этом ты можешь указать степень затухания колебаний, "медлительность" пружины и усиление/ослабление, которое оно придаёт объекту.
Но это если про демку говорить. Так же с помощью этих механизмов можно реализовывать другие зависимости между входом и выходом. Например, поведение объекта в плотной среде.
Таким же образом можно влиять на выходной спектр сигнала (например подавлять высокочастотные колебания), т.е. осуществлять фильтрацию сигнала от паразитных составляющих. Например если в ходе раскачивания на качелях начать слишком быстро менять направления усилия, то качели просто остановятся, а пользователь будет дрыгаться туда-сюда. Вооот - качели фильтр нижних частот.
Что-то меня понесло. Пока не ляпнул лишнего - приостановлюсь
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 22.10.2012, 01:17   #5
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ответ: Библиотека для моделирования динамических звеньев

Сообщение от Randomize Посмотреть сообщение
Демку запустить не на чем.
Вот демка. Можно менять параметры колебательно звена T и KSI (напомню, что библиотека может реализовать и другие звенья, но мне лень городить монстроинтерфейс).
Вложения
Тип файла: zip Release.zip (1.87 Мб, 541 просмотров)
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (22.10.2012)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 08:19.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com