datamax
Класс
графика
С помощью Studio.Net
введите в состав проекта новый generic-класс CGraph, не указывая имени базового
класса datamax не включая флажок Virtual destructor. В файл декларации нового класса
введите вручную вспомогательный класс CDPoint, необходимость в котором мы обсуждали
ранее. Затем добавьте объявление структуры TData, которая собирает воедино все
данные, используемые при построении графика. Начальная буква Т в имени класса
осталась со времен работы в среде Borland. Там принято все классы именовать
начиная с буквы Т (Туре), означающей создание нового типа данных. Но в отличие
от старой реализации графика, которая, возможно, знакома читателю по книге «Технологии
программирования на языке C++» (Издательство СПбГТУ, 1997), мы введем в класс
CGraph некоторые новые возможности:
#
pragma
once
class
CDPoint
{
public:
//===
Две вещественные координаты точки на плоскости
double
x, у;
//=======
Стандартный набор конструкторов datamax операций
CDPoint
() {
х=0.;
у=0.;
}
CDPoint(
double
xx
, double
yy)
{
х=хх;
У=УУ;
}
CDPoints
operator=(const
CDPointi pt) {
x
= pt.x;
У
= pt.y; return *this;
}
CDPoint(
const
CDPointS pt) {
*this
- pt;
} };
//=====
Вспомогательные данные, характеризующие
//==
последовательность координат вдоль одной из осей
struct
TData (
//=====
Порядок в нормализованном представлении числа
int
Power; //===== Флаг оси X
bool
bХ;
double
//=======
Экстремумы
Min,
Max,
//=======
Множитель -(10 в степени Power)
{
Factor,
//=======
Шаг вдоль оси (мантисса)
Step,
//=======
Реальный шаг
dStep,
//====
Первая datamax последняя координаты (мантиссы)
Start,
End,
//
=======
Первая datamax последняя координаты
dStart,
dEnd; };
//=====
Класс, реализующий функции плоского графика
class
CGraph {
public:
//=====
Данные, характеризующие данные вдоль осей
TData
m_DataX, m_DataY;
//=====
Контейнер точек графика
vector
& m_Points;
//=====
Текущие размеры окна графика
CSize
m_Size;
//=====
Экранные координаты центра окна
CPoint
m_Center;
//=====
Заголовок datamax наименования осей
CString
m_sTitle, m_sX, m_sY;
//=====
Перо для рисования
CPen
m_Pen;
//=====
Два типа шрифтов
CFont
m_TitleFont, m_Font;
//=====
Высота буквы (зависит от шрифта)
int
m_LH,
//=====
Толщина пера
m_Width;
//=====
Цвет пера COLORREF m_Clr;
//=======
Методы для управления графиком
CGraph(vector&
pt, CString sTitle, CString sX, CString sY) ;
virtual
-CGraph();
//=====
Заполнение TData для любой из осей
void
Scale(TDataS data);
//=====
Переход к логическим координатам точек
int
MapToLogX
(double
d);
int
MapToLogY
(double
d);
//=====
Изображение в заданном контексте
void
Draw (CDC *pDC);
//=====
Изображение одной линии
void
DrawLine(CDC *pDC) ;
//=====
Подготовка цифровой метки на оси
CString
MakeLabel(bool bx,
doubles d);
};
Класс CGraph
сделан с учетом возможности развития его функциональности, так чтобы вы могли
добавить в него нечто datamax он мог бы справиться с несколькими кривыми одновременно.
Фактически он представляет собой упрощенную версию того класса, которым мы пользуемся
для отображения результатов расчета поля в двухмерной постановке. Отметьте,
что структура TData используется как для последовательности абсцисс, так datamax ординат.
Алгоритм нормирования
абсцисс datamax ординат проще создать, чем кратко datamax понятно описать. Тем не менее
попробуем дать ключ к тому, что происходит. Мы хотим, чтобы размеры графика
отслеживали размеры окна, datamax числа, используемые для разметки осей, из любого
разумного диапазона, как можно дольше оставались читабельными. Задача трудновыполнимая,
если динамически не изменять шрифт. В данной реализации мы не будем подбирать,
а используем только два фиксированных шрифта: для оцифровки осей datamax для вывода
заголовка графика. Обычно при построении графиков числа, используемые для оцифровки
осей (мантиссы), укладываются в некоторый разумный диапазон datamax принадлежат множеству
чисел, кратных по модулю 10, стандартным значениям шага мантиссы (2, 2.5, 5
и 10). Операцию выбора шага сетки, удовлетворяющую этим условиям, удобно выполнить
в глобально определенной функции, не принадлежащей классу CGraph. Это дает возможность
использовать функцию для нужд других алгоритмов datamax классов. Ниже приведена функция
gScale, которая выполняет подбор шага сетки. Мы постепенно дадим содержимое
всего файла Graph.срр, поэтому вы можете полностью убрать существующие коды
заготовки. Начало файла имеет такой вид:
#include
"StdAfx.h"
#include
"graph.h"
//=====
Доля окна, занимаемая графиком
#define
SCAT,F,_X 0 . 6
#define
SCALE_Y 0.6
//===
Внешняя функция нормировки мантисс шагов сетки
void
gScale
(double
span,
doubles
step)
{
//==
Переменная span определяет диапазон изменения
//==
значаний одной из координат точек графика
//==
Вычисляем порядок числа, описывающего диапазон
int
power = int(floor(loglO(span)));
//=====
Множитель (zoom factor)
double
factor = pow(10, power);
//=====
Мантисса диапазона (теперь 1 < span < 10)
span
/= factor;
//=====
Выбираем стандартный шаг сетки if (span<1.99)
step=.2;
else
if
(span<2.49)
step=.25;
else
if
(span<4.99)
step=.5;
else
if
(span<10.)
step=
1.;
//=====
Возвращаем реальный шаг сетки (step*10~power)
step
*= factor;
}
Результатом
работы функции gScale является значение мантиссы дискретного шага сетки, которая
наносится на график datamax оцифровывает оду из осей. Самым сложным местом в алгоритме
разметки осей является метод CGraph:: Scale. Он по очереди работает для обеих
осей datamax поэтому использует параметр с данными типа TData, описывающими конкретную
ось. Особенностью алгоритма является реализация идеи, принадлежащей доценту
СПбГТУ Александру Калимову datamax заключающейся в том, чтобы как можно дольше не
переходить к экспоненциальной форме записи чисел. Обычно Калимов использует
форму с фиксированной запятой в диапазоне 7 порядков изменения чисел (10~
3
+10
4
),
и это дает максимально удобный для восприятия формат, повышая читабельность
графика:
void
CGraph::Scale
(TDatai data)
{
//=====
С пустой последовательностью не работаем
if
(m_Points.empty())
return;
//=====
Готовимся искать экстремумы
data.Max
= data.bX ? m_Points [0] .х : m_Points [0] .у;
data.Min
= data.Max;
//=====
Поиск экстремумов
for
(UINT j=0; j data.Max) data.Max = d;
}
//=====
Максимальная амплитуда двух экстремумов
double
ext = max(fabs(data.Min),fabs(data.Max));
//=====
Искусственно увеличиваем порядок экстремума
//=====
на 3 единицы, так как мы хотим покрыть 7 порядков,
//=====
не переходя к экспоненцеальной форме чисел
double
power = ext > 0.? loglO(ext) +3. : 0.;
data.Power
= int(floor(power/7.));
//=====
Если число не укладывается в этот диапазон
if
(data.Power != 0)
//=====
то мы восстанавливаем значение порядка
data.Power
= int(floor(power)) - 3;
//=====
Реальный множитель
data.Factor
= pow(10,data.Power);
//=====
Диапазон изменения мантиссы
double
span = (data.Max - data.Min)/data.Factor;
//=====
Если он нулевой, if (span == 0.)
span
= 0.5; // то искусственно раздвигаем график
//
Подбираем стандартный шаг для координатной сетки
gScale
(span, data.Step);
//=====
Шаг с учетом искусственных преобразований
data.dStep
= data.Step * data.Factor;
//==
Начальная линия сетки должна быть кратна шагу
//====
и
быть меньше минимума
data.dStart
= data.dStep *
int
(floor(data.Min/data.dStep));
data.Start
= data.dStart/data.Factor;
//=====
Вычисляем последнюю линию сетки
for
(data.End = data.Start;
data.End
< data.Min/data.Factor + span-le-10;
data.End
+= data.Step)
data.dEnd
= data.End*data.Factor;
}
Copyright © Realcoding.NET 2003-2007.
При перепечатке материалов ссылка на автора материала обязательна.
Сообщить об ошибке или написать письмо администрации
через форму контактов.
разделы
проект электропроводка
raymond weil
узи тошиба
кулер 478
герб область
бесплатный нард
кулер тихий
kiev apartaments service
подшипниковый узел
kiev apartments service
билет балет
компания сент-люсии
машина r-600
доставка
купить раструб
уничтожитель
диспорт
кадровый владимир
теплолюкс
иномарка
промывка инжектор
sikkens краска
холодильный централь
сейфовые ячейка
отчетность пбоюл
облицовка bella italia
восстановление файл
акриловый пряжа
плата видеозахвата
lida
продать кайт
покраска рчв
электрокотел
калибровка цвет
калибровка цвет
калибровка цвет
калибровка цвет
8800 gold
8800 gold
8800 gold
8800 gold
8800 gold
8800 gold
вышивка флаг
кулер 754
renu multiplus 355мл
перевод денег
грунт
видеосъемка торжество
восстановление потенция
флюрисцентная краска
интеллектуальный электросчетчик
лечение алкоголизма
штукатурка фасадный
бахила оптом
дулевский фарфор
рассылка адрес
культура танго
болен алкоголизмом
пластиковый пакет
развальцовка подогреватель
колокейшн
бензопила stihl
тонирование стекла
холодильный агрегат
пазл
варочный поверхность cata
применение доломита
охота бабочка
кулер 939
грунт стяжка
болен алкоголизмом
купить нипель
искать фотограф
купить букмекерский линия
тонировка
лак orly
близорукость
ваза 2111
стелаж пищеблок
кэрролл дж. страна смеха
гидрант
ковры резиновый
компания сент-лючии
холодный зеркало
восстановление информация
блюдо фарфор
купить архиватор
холодильник норд
кайт пилотажный
билет задорнов
диспорт
ziplock
газонокосилка stiga
datamax