Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Совместно используемые данные в c++

87
11 января 2009 года
Kogrom
2.7K / / 02.02.2008
Есть 3 класса для создания графика: класс поля и 2 класса для осей. Класс поля не должен ничего знать об осях, так как может быть использован отдельно от них. Оба класса осей используют данные, которые содержатся в классе поля, причем каждый только определенную часть.

Вопрос: как лучше сделать совместное использование данных?

Я пока вижу несколько путей, но все они кривоватые:

1. Объявить классы осей frend-ми. Но тогда они получат доступ к данным, не предназначенным для них.

2. Передавать каждое данное через открытый метод класса поля типа Get... Но тогда получится слишком много таких методов, и класс будет выглядеть некрасиво и плохо читаться.

3. Создать специальные структуры, в которых будут содержаться данные, предназначенные только двум классам. Соответственно, в классе поля такую структуру сделать закрытой. Клиенту (оси) передавать константную ссылку или указатель на структуру. Тут проблема в том, что классу поля вроде бы такие структуры ни к чему.
11
11 января 2009 года
oxotnik333
2.9K / / 03.08.2007
задача настолько туманна, что диапазон ее решений лежит в пределах от минус 273 градуса по цельсию, до плюс 1000 градусов по фаренгейту.
А по теме, если я правильно понимаю, то скрытием/показом определенных видов данных должен заниматься некий общий базовый класс, либо п.3. вполне решает нужную задачу - для каждой оси своя структура, а класс поля умеет работать с обеими структурами.
5
11 января 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Есть 3 класса для создания графика: класс поля и 2 класса для осей.

Почему на каждую ось свой класс? Скажите, чем концептуально отличается ось абсцисс от оси ординат? Ничем!
Отлично теперь нужно определиться с сущностью внутри которой все дружно живут - это некая Канва, именно она должна заниматься отображением элементов.
Вспомните идею MVC: ваши оси и точки (поля) есть модель, значит совсем другие сущности должны быть представлением!

87
11 января 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: oxotnik333
задача настолько туманна, что диапазон ее решений лежит в пределах


Мне же не нужна конкретная реализация. Мне только подходящий метод нужен.

Цитата: hardcase
Почему на каждую ось свой класс? Скажите, чем концептуально отличается ось абсцисс от оси ординат? Ничем!
Отлично теперь нужно определиться с сущностью внутри которой все дружно живут - это некая Канва, именно она должна заниматься отображением элементов.
Вспомните идею MVC: ваши оси и точки (поля) есть модель, значит совсем другие сущности должны быть представлением!



Почти со всем согласен. Обе оси у меня являются наследником одного абстрактного класса. Разница в том, что метки оси времени (x) постоянно обновляются.

Канва есть. Она включает все 3 класса и закрывает от клиентов.

Пока она управляет объектами так:

 
Код:
нарисовать поле,
нарисовать ось x,
нарисовать ось y

Ну можно конечно изменить
 
Код:
нарисовать поле в таких-то координатах, с таким-то масштабом, с таким-то цветом фона и. т.д.,
нарисовать ось x в таких-то координатах, с таким-то масштабом,
нарисовать ось y в таких-то координатах, с таким-то масштабом

Но, думаю, лучше задавать все параметры отдельными функциями, а рисовать другими.

Не могу согласиться, что я говорю о модели. Поле - это как-раз представление. Точки (модель) храняться отдельно от графика.
5
11 января 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Мне же не нужна конкретная реализация. Мне только подходящий метод нужен.

Пока вы не определитесь (и не покажете тут) какой оси нужна какая информация от поля у вас ничего не выйдет.
Абстрактные задачи решать можно только абстрактно: "перепроектируете классы и все круто :)".

87
12 января 2009 года
Kogrom
2.7K / / 02.02.2008
Можно и с кодом, но не думаю, что будет легче.

Код:
class ksField
{
public:
    struct X
    {
        int leftIndent; // отступ поля слева (поле, ось времени)
        int fieldWidth; // ширина поля вывода графиков
        int tSpace; // число секунд, выводимых на график (поле, ось времени)
        double nPixPerTUnit; // число пикселов на секунду (поле, ось времени)

        int topIndent; // отступ поля сверху (поле, ось параметра)
        int fieldHeight; // высота поля вывода графиков
        int maxY; // максимальная величина по оси y (поле, ось параметра)
        int minY; // минимальная величина по оси y (поле, ось параметра)
        double nPixPerYUnit; // число пикселов на единицу величины y (поле, ось параметра)

        X(){/*...*/}
    };
private:
    X x;
    int rightIndent; // отступ поля справа (для пересчета поля)
    int bottomIndent; // отступ поля снизу (для пересчета поля)

    vector<ksLine> lines; // линии графика
public:
    const X& GetXVars(){return x;}

    void SetLegends(const vector<string> &nms) {/*...*/}
    void SetValuesPtr(vector< vector<int> > *vPtr) {/*...*/}
    void Draw(HDC hDC);
    void Resize(int wWidth, int wHeight);
    ksField();
};

class ksGrid
{
protected:
    string name;
    const ksField::X &xptr;
    int gridStep; // шаг сетки
public:
    virtual void SetName(const string& sname){ name = sname;}
    virtual void SetGridStep(int s){gridStep = s;}
    virtual void Draw(HDC hDC) = 0;
    ksGrid(const ksField::X &x):xptr(x){}
    virtual ~ksGrid() {}
};

class ksVertGrid: public ksGrid
{
public:
    virtual void Draw(HDC hDC);
    ksVertGrid(const ksField::X &x);
};

class ksHorzGrid: public ksGrid
{
    int currentTime; // текущее время (ось времени)
public:
    virtual void Draw(HDC hDC);
    void SetTime(int t)
    {
        currentTime = t;
    }
    ksHorzGrid(const ksField::X &x);
};

class ksGraph
{
    int wndWidth; // ширина окна (для контроля изменения)
    int wndHeight; // высота окна

    ksField field;
    ksVertGrid vGrid;
    ksHorzGrid hGrid;

public:
    void SetGridNames(const string& sHorz, const string& sVert) {/*...*/}
    void SetLegends(const vector<string> &nms) {/*...*/}
    void SetValuesPtr(vector< vector<int> > *vPtr) {/*...*/}
    void Draw(HWND hwnd, HDC hDC); // прорисовка графика
    ksGraph();
};


В общем, данные, которые я выделил в структуру ksField::X должны быть доступны для чтения осям (наследникам ksGrid).
87
12 января 2009 года
Kogrom
2.7K / / 02.02.2008
Есть еще альтернатива сделать все элементы графика (и более мелкие тоже) наследниками абстрактного класса-глифа (как в книге GoF про паттерны проектирования), который содержит и пересчитывает все координаты в себе, да еще и может включать других потомков. А потом как-то компоновать эти глифы.

Так будет возможно гибче, но уж больно избыточно для моего простого графика.
11
12 января 2009 года
oxotnik333
2.9K / / 03.08.2007
да вобще то все написано давно... CDC в MFC или TCanvas в VCL
остается только замасштабировать и выводить
87
12 января 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: oxotnik333
да вобще то все написано давно... CDC в MFC или TCanvas в VCL
остается только замасштабировать и выводить


Это вы про глифы? MFC и VCL я не использую - комерческие библиотеки... Но я уверен, что есть какие-то бесплатные варианты. Другое дело, что неизвстно, стоит ли применять тут эти глифы.

Но вообще, стоит порыться в исходниках библиотек - может найду в каком-нибудь wxWidgets или WTL себе образец как строить диаграммы.

5
12 января 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
MFC и VCL я не использую - комерческие библиотеки...

А зря. Сами по себе эти библиотеки не являются коммерческими. А вот полноценные IDE -да.
Visual Studio есть в редакции Express и ниразу не коммерческая.
Code Gear RAD Stuido Тоже есть в Express и также бесплатная.
Учитесь пользоваться тем, что уже сделано.

341
12 января 2009 года
Der Meister
874 / / 21.12.2007
Цитата:
Есть еще альтернатива сделать все элементы графика (и более мелкие тоже) наследниками абстрактного класса-глифа (как в книге GoF про паттерны проектирования), который содержит и пересчитывает все координаты в себе, да еще и может включать других потомков. А потом как-то компоновать эти глифы.

Тогда уже смотрите в сторону декораторов.
Но мне кажется, что вы излишне наворачиваете. Посмотрите диаграмму во вложении. Ответственность за обмен данными лежит на кассе Chart (фасад, если хотите).

505
12 января 2009 года
vAC
343 / / 28.02.2006
Цитата: Kogrom
Но вообще, стоит порыться в исходниках библиотек - может найду в каком-нибудь wxWidgets или WTL себе образец как строить диаграммы.



Полюбопытствуйте как сделаны сцены в Qt, даже исходники не надо рыть, все предельно просто. Можно выделить 3 основные компоненты:
1. График (сцена), как контейнер элементов;
2. Элементы графика (оси, вспомогательные линии, кривая графика и т.д.);
3. Средство визуализации (DC, Canvas).

Элементы имеют связь типа use со средством визуализации, которое используется при отрисовке. Всю необходимую информацию для отображения следует хранить только в этом классе элемента, никаких ссылок наружу - минимум связей.

Сама сцена графика предоставляет необходимый интерфейс (более высокого уровня, чем просто сцена) для управления внешним видом графика.

Таким образом я бы выделил следующие абстракции:
1. Сцена
2. Элемент
3. Визуализатор
4. Сцена_графика: Сцена
5. Ось: Элемент
6. Кривая: Элемент
7. ...

87
13 января 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Der Meister
Тогда уже смотрите в сторону декораторов.
Но мне кажется, что вы излишне наворачиваете. Посмотрите диаграмму во вложении. Ответственность за обмен данными лежит на кассе Chart (фасад, если хотите).



Хм. Я под полем подразумевал фон - прямоугольную область определенного цвета, а все этим термином называют линию графика. Но не важно.

В вашем примере, как я понял, 3 особенности:

1. Есть определенный прямоугольник (Rectangle) используя который все элементы графика рассчитывают свое положение и размер.
2. Есть класс, который хранит значения отступов от внешнего прямоугольника. В этот класс делегирована функция перерасчета прямоугольника графика по внешнему прямоугольнику.
3. График является статическим и автоматически масштабируемым. Таким образом, свойства осей корректируются по характеристикам диапазона реальных значений.

В общем, все ясно и легко читается.

В моем случае, нужен график, на котором могут отображаться несколько полей (в вашем понимании), причем данные их меняются динамически. Т.е. что-то вроде экрана осциллографа. Поэтому автоматический масштаб мне не нужен – неудобно смотреть при постоянно изменяющихся осях. То есть масштаб должен выбирать пользователь. Легенды тоже не статические. Кроме какого-либо комментария они выводят текущее или среднее значение отображаемого параметра. Поэтому я легенду включил в поле, хотя можно ее использовать и отдельно.

Но это для справки. Переделать ваш пример для использования в моем я наверняка смогу.

Еще вопрос. Каким редактором рисовали диаграмму?

Цитата: hardcase
А зря. Сами по себе эти библиотеки не являются коммерческими. А вот полноценные IDE -да.
Visual Studio есть в редакции Express и ниразу не коммерческая.
Code Gear RAD Stuido Тоже есть в Express и также бесплатная.


Бесплатные IDE от Code Gear, как мне помнится, имеют неудобные ограничения в лицензии (регистрация по интернету, один продукт на один комп, одному человеку). Мне это не подходит, так как требуется такая среда сразу на нескольких компьютерах.

Visual Studio редакции Express распространяется свободнее, но как раз MFC там и нет. Люди как-то прикручивают к ней и MFC и WTL, но какими-то ненадежными хакерскими методами.

Кроме того, неохота использовать библиотеку, рассчитанную на одну ОС. Тут лучше использовать Qt или wxWidgets. В этом направлении и двигаюсь, но пока не решил некоторые технические вопросы. Вот за это меня можно упрекнуть.

Цитата: vAC
Полюбопытствуйте как сделаны сцены в Qt, даже исходники не надо рыть, все предельно просто.



За совет спасибо. Этим займусь позже, если вариант от Der Meister чем-то не устроит. Да и вообще, интересно.

341
13 января 2009 года
Der Meister
874 / / 21.12.2007
[QUOTE=Kogrom]Еще вопрос. Каким редактором рисовали диаграмму?[/QUOTE]Visio. Уже привык к нему, достаточно хорошая штука.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог