Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИГС / Lab_03 / labor_03a.doc
Скачиваний:
11
Добавлен:
17.04.2018
Размер:
1.34 Mб
Скачать

Интерактивное изменение числа опорных точек сплайновых кривых с помощью диалоговых окон.

Теперь надо научиться, в интерактивном режиме, изменять число опорных точек сплайновой кривой. Для этого при выборе пункта меню GeneralBezierSplineдолжно появляться диалоговое окно, в котором должен присутствовать редактор, позволяющий изменять значение переменнойNorder– порядок кривой Безье.

За основу возьмем готовый проект LineBezie. Создаем новый проект с названиемLineBezieComposite. В рабочую папку нового проекта из рабочей папки старого проекта перебрасываем файлыCubeBezie.cpp, CubeBezie.rc, resource.h.

В окне Solutionнового проекта в пунктSource Filesдобавляем файлCubeBezie.cpp, в пунктResource Filesдобавляем файлCubeBezie.rc, в пунктHeader Filesдобавляем файлresource.h.

Откроем файл CubeBezie.cppи компилируем его. Скорее всего, появятся ошибки, связанные с кодировкой символов. Поэтому настроим проект. Идем по цепочке Project  Property  Configuration Properties  General  Characters Set. В последнем пункте вместо кодировкиUse Multi - Byteустанавливаем кодировкуUse Unicode. Повторная компиляция дает положительный результат.

Выделяем файл CubeBezie.rc и компилируем его. Затем создаем исполняемый файл. Проект готов. Теперь займемся добавлением строчек кода для создания диалогового окна.

Для этого в функции окна WndProcдобавим код обработки сообщенияID_GENERAL, приходящего при выборе пункта менюGeneralBezierSpline.

//значение, возвращаемое после закрытия диалогового окна

int EndDial;

case ID_GENERAL:

EndDial = DialogBox(hInstApp, (LPCTSTR)IDD_DIALOG1, hWnd, DialProc);

If(EndDial)

SplineDC(hWnd);

break;

Здесь присутствует функция DialogBox(), которая создает диалоговое окно (модальное). Модальное окно обладает следующим свойством. При открытии модального диалогового окна программа приостанавливает свою работу до тех пор, пока не будет закрыто модальное диалоговое окно.

Перечислим параметры функции DialogBox().

1-ый параметр - идентификатор экземпляра приложения

2-ой параметр - идентификатор шаблона диалогового окна

3-ий параметр - идентификатор родительского окна

4-ый параметр - имя функции диалогового окна

Первым параметром функции DialogBox()является идентификатор экземпляра приложенияhInstApp. Поэтому в начале файла вставим строчку кода.

//идентификатор приложения

HINSTANCE hInstApp;

В главной функции WinMain()добавим строчку.

hInstApp = hInstance;

Это сделано для того, чтобы идентификатор приложения стал глобальной переменной в программе.

Вторым параметром функции DialogBox()является идентификатор шаблона диалогового окнаIDD_DIALOG1. Этот идентификатор появиться, когда диалоговое оно будет добавлено в ресурсы программы.

Добавим диалоговое окно в ресурсы программы. В окне Solutionпроекта в пунктеResource Filesнажмем правой кнопкой мыши. Выберем пунктAddи строчкуResource. Появится окно Add Resource

Рис.17

Окно для добавления ресурсов в программу.

Выбираем пункт Dialogи нажимаем кнопкуNew. В результате создается шаблон диалогового окна.

Рис.18

Шаблон диалогового окна.

Щелкнем правой кнопкой мышки на заголовке шаблона диалогового окна, и выбираем пункт Properties, в результате появится окноPropertiesдля редактирования диалогового окна.

Рис.19

Окно для редактирования диалогового окна.

В окошечке IDнаходится идентификатор IDD_DIALOG1создаваемого шаблона диалогового окна. Этот идентификатор оставим без изменения. В окошечкеCaptionсменим название диалогового окна наOrderofBezierSpline.

При открытии шаблона диалогового окна появляется окно Toolboxс набором элементов управления диалогового окна. Если окноToolboxне высвечивается, то надо нажать кнопкуToolboxна панели управления проектом.

С помощью мышки добавим на шаблон диалогового окна окно редактирования Edit Control.

и с помощью мышки изменим, размеры шаблона, как показано на Рис.19.

Рис.20

Шаблон диалогового окна после внесения изменений.

Сохраним вновь созданный ресурс. В результате в файле ресурсов CubeBezie.rcпоявятся строчки кода описывающие диалоговое окно. В заголовочном файлеresource.hпоявятся две строчки с описанием идентификатораIDD_DIALOG1шаблона диалогового окна и идентификатора элемента управленияIDD_EDIT1, т.е. окна редактирования в диалоговом окне.

Диалоговое окно во многом похоже на обычное окно WIN-программы. Обычное окно имеет функцию окна, в которой происходит обработка сообщений поступающих в окно. То же самое можно сказать о диалоговом окне. У диалогового окна также должна быть функция окна, в которой обрабатываются сообщения приходящие к диалоговому окну.

Поэтому четвертым параметром функции DialogBox(), которая создает диалоговое окно, является имя функции диалогового окнаDialProc.

Поместим в начало программы прототип этой функции.

BOOL CALLBACK DialProc(HWND, UINT, WPARAM, LPARAM);

Ниже приведем код функции диалогового окна.

//функция диалогового окна

BOOL CALLBACK DialProc (HWND hwndDlg, UINT uMsg,

WPARAM wParam, LPARAM lParam)

{

// char S[10];

TCHAR S[10];

switch(uMsg)

{

//сообщение при открытии диалогового окна

case WM_INITDIALOG:

// sprintf(S,"%d",1);

swprintf_s(S,20,_T("%d"),1);

SetWindowText(GetDlgItem(hwndDlg, IDC_EDIT1), S);

break;

//сообщение при закрытии диалогового окна

case WM_CLOSE:

EndDialog(hwndDlg, 0);

break;

//сообщение, приходящее от элементов диалогового окна

case WM_COMMAND:

if(LOWORD(wParam) == IDCANCEL) //нажата кнопка

{

EndDialog(hwndDlg, 0);

}

if(LOWORD(wParam) == IDOK) //нажата кнопка

{

GetWindowText(GetDlgItem(hwndDlg, IDC_EDIT1), S, 10);

// NOrder = atoi(S);

NOrder = _wtoi(S);

if(NOrder > 20)

NOrder = 20;

EndDialog(hwndDlg, 1);

}

break;

}

return 0;

}

Здесь обратим внимание на API-функциюGetDlgItem(). Эта функция извлекает идентификатор элемента управленияIDC_EDIT1диалогового окна.

Далее функция SetWindowText()берет строкуS, и помещает ее в окно редактораIDC_EDIT1 диалогового окна.

Затем функция GetWindowText()берет содержимое окна редактораIDC_EDIT1 диалогового окна, и помещает в строкуS.

Кроме того, посмотрим на API-функциюEndDialog(). Эта функция закрывает диалоговое окно. Первый параметр это идентификатор диалогового окна, а второй параметр это то число которое возвращает функцияDialogBox(). В нашем случае, если диалоговое окно закрывается без изменений в окне редактирование, то это число равно 0, в противном случае возвращается число 1.

Программа готова. Компилируем и запускаем на выполнение. Результат работы программы показан на Рис.21.

Рис.21

Результат работы программы line9. Сплайновая кривая Безье 5-ого порядка.

B-сплайновые кривые.

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

Можно придумать другие сплайновые кривые, для которых составные сплайновые кривые будут как G1–непрерывными, так иG2–непрерывными кривыми. К таким сплайновым кривым относятсяB-сплайновые кривые (B-spline). Покажем, как можно построить кубическуюB-сплайновую кривую.

Возьмем четыре опорные вектора V0,V1,V2,V3. Параметрическое уравнение кубическойB-сплайновой кривой будем искать в следующем виде.

(38)

Здесь B-сплайновые функцииB3,i(t) определяются по следующим формулам.

(39)

Заметим, что кубическая кривая Безье вычисляться по аналогичной формуле.

(40)

На Рис.22 показана кубическая B-сплайновая кривая. Желтые точки на кривой, соответствуют началу (t=0) и концу (t=1) элементарной кубическойB-сплайновой кривой.

Рис.22

Кубическая B-сплайновая кривая.

Рис.23

Составная B-сплайновая кривая. Гладкая стыковка дух элементарных кубических кривых.

(Изображения на Рис. 22, 23 созданы программой line10.cpp.)

На Рис.22 видно, что кубическая B-сплайновая кривая не проходит через опорные точки.

Увеличим число опорных точек до пяти V0,V1,V2,V3,V4. На первых четырех опорных точкахV0,V1,V2,V3, построим первую кубическуюB-сплайновую кривую.

(41)

На следующих четырех опорных точках V1,V2,V3,V4, построим вторую кубическуюB-сплайновую кривую.

(42)

Легко проверить, что для этих двух B-сплайновых кривых выполняются следующие условия:

(43)

Первое условия (43) означает, что эти кривые стыкуются в некоторой точке пространства. Два вторых условия (43) означают, что в точке стыковки их первая и вторая производные непрерывны. А это означает непрерывность касательного вектора и вектора кривизны.

На Рис.23 показана составная B-сплайновая кривая, составленная из двух кубическихB-сплайновых кривых (41) и (42). На Рис.23 видно, что одна элементарная кубическаяB-сплайновая кривая гладко переходит в другую элементарную кривую.

Таким же образом на N+1 опорных точкахV0,V1,,VN-1,VNможно построить составнуюB-сплайновую кривую, состоящую изN-2 элементарных кубическихB-сплайновых кривых.

Кривые Безье обладают важным свойством. Так составная кривая Безье, построенная на опорных точках V0,V1,,VN-1,VN, начинается в точкеV0, а заканчивается в точкеVN. Кроме того, касательный векторT0в начале кривой параллелен отрезку, а в конце кривой касательный векторTNпараллелен отрезку.

Оказывается, что составная B-сплайновая кривая обладает аналогичными свойствами. Для этого на начальные и конечные опорные векторы надо наложить следующие условия:

(44)

На Рис.24 показана составная B-сплайновая кривая, с закрепленными концами. На рисунке видно, что кривая начинается в опорной точкеV1, и кончается в опорной точкеV8. Кроме того, на рисунке также видно, что кривая касается отрезкови.

Рис.24

Составная B-сплайновая кривая с закрепленными концами. Кривая составлена и 7-ми элементарных кривых.

Рис.25

Замкнутая B-сплайновая кривая. Кривая составлена и 7-ми элементарных кривых.

(Изображения на Рис. 24, 25 созданы программой line10.cpp.)

Составную B-сплайновую кривую можно также замкнуть, если на начальные и конечные опорные векторы наложить следующие условия:

(45)

На Рис.25 показана замкнутая составная B-сплайновая кривая. В этом примере условия (45) принимают видV9=V2,V8=V1,V7=V0.

Кроме того, составную B-сплайновую кривую можно прикрепить к любой опорной точкеVm, если будет выполняться условие, аналогичное условиям (44).

(46)

На Рис.26 показана замкнутая составная B-сплайновая кривая, с двумя закрепленными точкамиV5иV12.

Рис.26

Замкнутая B-сплайновая кривая. Кривая составлена и 14-и элементарных кривых. Кривая проходит через опорные точкиV5иV12.

(Изображение на Рис. 26 создано программой line10.cpp.)

Уравнение (40) для элементарной кубической B-сплайновой кривой можно записать в матричном виде, как уравнение (25) для кривой Эрмита и уравнение (33) для кривой Безье. Введем столбец, элементами которого будут опорные векторы.

(47)

Тогда уравнение (40) для элементарной кубической B-сплайновой кривой можно представить в виде матричного уравнения.

(48)

Здесь матрица MBназывается матрицейB-сплайна (B-splinematrix) и имеет следующий вид:

(49)

Соседние файлы в папке Lab_03