Руководство - Отображение графики & простых рисунков
В этом примере показано, как создать простой рисунок. Он использует команды 2D рисования , для вывода двух синусоидальных волн на разных частотах и показывает гармонику, создаваемую объединением двух волн. Он использует процедуры, которые мы обсудим более подробно позже, чтобы разбить всё рисование на три самостоятельные задачи:; Окно Enumeration #WinHarmonic EndEnumeration ; Гаджеты Enumeration #txtPlot1 #cboPlot1 #txtPlot2 #cboPlot2 #imgPlot EndEnumeration ; Изображение Enumeration #drgPlot EndEnumeration ; Размеры изображения используются в нескольких местах, поэтому определяем константы. #imgPlotX = 8 #imgPlotY = 40 #imgPlotW = 745 #imgPlotH = 645 ; Переменные событий Define.l Event, EventWindow, EventGadget, EventType, EventMenu ; Реализация Procedure CreateWindow() ; Создает окно и Гаджеты. If OpenWindow(#WinHarmonic, 30, 30, #imgPlotW + 20, #imgPlotH + 55, "Harmonics", #PB_Window_SystemMenu - #PB_Window_MinimizeGadget - #PB_Window_TitleBar) ; Это не визуальный Гаджет, используемый для рисования изображения, позже его содержимое будет отображаться в #imgPlot. CreateImage(#drgPlot, #imgPlotW - 5, #imgPlotH - 5, 24) ; Метка для точки 1 на combo. TextGadget(#txtPlot1, 2, 5, 50, 25, "Точка 1:") ; Точка 1 на combo. ComboBoxGadget(#cboPlot1, 55, 5, 150, 25) AddGadgetItem(#cboPlot1, 0, "Sin(X)") AddGadgetItem(#cboPlot1, 1, "Sin(X * 2)") AddGadgetItem(#cboPlot1, 2, "Sin(X * 3)") AddGadgetItem(#cboPlot1, 3, "Sin(X * 4)") AddGadgetItem(#cboPlot1, 4, "Sin(X * 5)") AddGadgetItem(#cboPlot1, 5, "Sin(X * 6)") ; Выбор Sin(X) SetGadgetState(#cboPlot1, 0) ; Метка для точки 2 на combo. TextGadget(#txtPlot2, 230, 5, 50, 25, "Точка 2:") ; Точка 2 на combo. ComboBoxGadget(#cboPlot2, 280, 5, 150, 25) AddGadgetItem(#cboPlot2, 0, "Sin(X)") AddGadgetItem(#cboPlot2, 1, "Sin(X * 2)") AddGadgetItem(#cboPlot2, 2, "Sin(X * 3)") AddGadgetItem(#cboPlot2, 3, "Sin(X * 4)") AddGadgetItem(#cboPlot2, 4, "Sin(X * 5)") AddGadgetItem(#cboPlot2, 5, "Sin(X * 6)") ; Выбор Sin(X * 2), в противном случае начальный дисплей немножко неинтересный. SetGadgetState(#cboPlot2, 1) ; Создание Гаджета визуального изображения в окне. ImageGadget(#imgPlot, #imgPlotX, #imgPlotY, #imgPlotW, #imgPlotH, 0, #PB_Image_Border) EndIf EndProcedure Procedure PlotAxes() ; Рисует оси на изображении #drgPlot. ; Направляет последующие команды рисования в #drgPlot. StartDrawing(ImageOutput(#drgPlot)) ; Нарисовать белый фон. Box(0, 0, ImageWidth(#drgPlot), ImageHeight(#drgPlot), RGB(255, 255, 255)) ; Нарисовать оси черным цветом. Line(1, 1, 1, ImageHeight(#drgPlot) - 2, RGB(0, 0, 0)) Line(1, (ImageHeight(#drgPlot) - 2) /2, ImageWidth(#drgPlot) -2, 1, RGB(0, 0, 0)) ; Закончить вывод команд рисования, в данном случае в #drgPlot. StopDrawing() EndProcedure Procedure PlotLegend(alngPlot1, alngPlot2) ; Рисует легенду изображения #drgPlot. Protected.s strFunc1, strFunc2, strLabel1, strLabel2, strLabel3 ; Установить текст метки 1. If alngPlot1 = 0 strFunc1 = "Sin(X)" Else strFunc1 = "Sin(X * " + StrU(alngPlot1 + 1) + ")" EndIf ; Установить текст метки 2. If alngPlot2 = 0 strFunc2 = "Sin(X)" Else strFunc2 = "Sin(X * " + StrU(alngPlot2 + 1) + ")" EndIf ; Установить текст метки. strLabel1 = "Y = " + strFunc1 strLabel2 = "Y = " + strFunc2 strLabel3 = "Y = " + strFunc1 + " + " + strFunc2 ; Рисует легенду. StartDrawing(ImageOutput(#drgPlot)) ; Прямоугольник. DrawingMode(#PB_2DDrawing_Outlined) Box(20, 10, TextWidth(strLabel3) + 85, 80, RGB(0, 0, 0)) ; Метка 1. Line(30, 30, 50, 1, RGB(0, 0, 255)) DrawText(95, 22, strLabel1, RGB(0, 0, 0), RGB(255, 255, 255)) ; Метка 2. Line(30, 50, 50, 1, RGB(0, 255, 200)) DrawText(95, 42, strLabel2, RGB(0, 0, 0), RGB(255, 255, 255)) ; Метка 3. Line(30, 70, 50, 1, RGB(255, 0, 0)) DrawText(95, 62, strLabel3, RGB(0, 0, 0), RGB(255, 255, 255)) StopDrawing() EndProcedure Procedure PlotFunction(alngPlot1, alngPlot2) ; Рисует осциллограммы на изображении #drgPlot. Protected.l lngSX, lngEX Protected.f fltRad1, fltRad2, fltSY1, fltEY1, fltSY2, fltEY2, fltSY3, fltEY3 StartDrawing(ImageOutput(#drgPlot)) ; Определить начальные точки старта для каждой волны. lngSX = 1 fltSY1 = ImageHeight(#drgPlot) / 2 fltSY2 = fltSY1 fltSY3 = fltSY1 ; Формирует волновые формы. For lngEX = 1 To 720 ; Синусоидальная функция работает в радианах, поэтому конвертируем из градусов и вычисляем синус. ; Функция 1 If alngPlot1 = 0 fltRad1 = Sin(Radian(lngEX)) Else ; Если функция должна иметь множитель, то учитывает это. fltRad1 = Sin(Radian(lngEX) * (alngPlot1 + 1)) EndIf ; Функция 2 If alngPlot2 = 0 fltRad2 = Sin(Radian(lngEX)) Else fltRad2 = Sin(Radian(lngEX) * (alngPlot2 + 1)) EndIf ; Точка функции 1, синего цвета. ; Вычисляет конечную точку Y. fltEY1 = (ImageHeight(#drgPlot) / 2) + (fltRad1 * 100) ; Рисует линию от стартовой точки до конечной точки. LineXY(lngSX, fltSY1, lngEX, fltEY1, RGB(0, 0, 255)) ; Обновить значение следующей начальной точки Y, от текущей конечной точки Y. fltSY1 = fltEY1 ; Точка функции 2, зелёного цвета. fltEY2 = (ImageHeight(#drgPlot) / 2) + (fltRad2 * 100) LineXY(lngSX, fltSY2, lngEX, fltEY2, RGB(0, 255, 200)) fltSY2 = fltEY2 ; Точка гармоники, красного цвета. fltEY3 = (ImageHeight(#drgPlot) / 2) + ((fltRad1 + fltRad2) * 100) LineXY(lngSX, fltSY3, lngEX, fltEY3, RGB(255, 0, 0)) fltSY3 = fltEY3 ; Обновить значение следующей начальной точки X, от текущей конечной точки X. lngSX = lngEX Next lngEX StopDrawing() EndProcedure ;- Главный код. CreateWindow() PlotAxes() PlotLegend(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2)) PlotFunction(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2)) ; Перезагрузите Гаджет изображения, теперь с завершенным рисунком. ImageGadget(#imgPlot, #imgPlotX, #imgPlotY, #imgPlotW, #imgPlotH, ImageID(#drgPlot), #PB_Image_Border) ;- Цикл событий Repeat Event = WaitWindowEvent() EventWindow = EventWindow() EventGadget = EventGadget() EventType = EventType() Select Event Case #PB_Event_Gadget If EventGadget = #txtPlot1 Or EventGadget = #txtPlot2 ; Ничего не делать. ElseIf EventGadget = #imgPlot ; Ничего не делать. ElseIf EventGadget = #cboPlot1 Or EventGadget = #cboPlot2 ; Если один из списков изменился, перерисует изображение. PlotAxes() PlotLegend(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2)) PlotFunction(GetGadgetState(#cboPlot1), GetGadgetState(#cboPlot2)) ImageGadget(#imgPlot, #imgPlotX, #imgPlotY, #imgPlotW, #imgPlotH, ImageID(#drgPlot), #PB_Image_Border) EndIf Case #PB_Event_CloseWindow If EventWindow = #WinHarmonic CloseWindow(#WinHarmonic) Break EndIf EndSelect ForEver
Навигация Руководства
< Создание графического интерфейса пользователя (GUI) - Обзор - Структурирование кода в Процедурах >