#45; str - строка с координатами выбранной точки (тип string);- List - список точек, найденных в области вблизи указателя мыши· Словесный алгоритмПодпрограмма выводит в строку состояния координаты движущегося указателя мыши и осуществляет проверку того, наведен ли он на точку, путем поиска точек дерева в области вокруг указателя. Если таковые имеются, изображение первой из них перерисовывается соответствующим цветом.2.1.5.9 Процедура MaxImageClick· Процедура предназначена для добавления точки в дерево и «запоминания» координат выбранной точки· Процедура является методом класса TMainForm· Параметры - входной параметр - объект, сгенерировавший событие (тип TObject)· Локальные переменные- Point - новая либо выбранная точка (тип TPoint);- str - строка с координатами выбранной точки (тип string);- i, j - координаты точки относительно окна просмотра (тип integer)· Словесный алгоритмПодпрограмма получает координаты новой (или выбранной) точки из строки состояния. Затем, если программа находится в режиме добавления точек, вставляет в дерево новую точку; в зависимости от результата функции вставки, увеличивает счетчик точек на единицу и перерисовывает изображение. В режиме выбора точек процедура записывает в глобальную переменную координаты выбранной точки и перекрашивает ее на карте соответствующим цветом. Координаты выбранной точки выводятся в строку состояния.2.1.5.10 Процедура ButtonDeleteClick· Процедура предназначена для удаления выбранной точки из дерева· Процедура является методом класса TMainForm· Параметры - входной параметр - объект, сгенерировавший событие (тип TObject)· Словесный алгоритмПодпрограмма удаляет выбранную точку из дерева; затем, если необходимо, перерисовывает просматриваемую область карты.2.1.5.11 Процедура ButtonClearClick· Процедура предназначена для удаления всех точек из дерева· Процедура является методом класса TMainForm· Параметры - входной параметр - объект, сгенерировавший событие (тип TObject)· Словесный алгоритмПодпрограмма удаляет все точки из дерева, «стирает» изображение с карты и устанавливает «пустые » координаты для выбранной и текущей точек.2.1.5.12 Процедура FormKeyDown· Процедура осуществляет перемещение окна выделения при нажатии клавиш· Процедура является методом класса TMainForm· Параметры - входной параметр - объект, сгенерировавший событие (тип TObject);- выходной параметр - индикатор нажатой клавиши (тип word);- входной параметр - индикатор нажатой клавиши (тип TShiftState)· Локальные константы- dif = 4 - число пикселей, на которое перемещается окно выделения· Словесный алгоритмПодпрограмма вызывает перемещающую окно выделения процедуру ShapeViewMouseMove, передавая ей разные параметры в зависимости от нажатой клавиши.Заключение Разработанный программный продукт обеспечивает выполнение всех требований, предъявленных к нему в техническом задании. Программный продукт рекомендован к использованию для широкого круга пользователей. Использование программного продукта позволяет существенно облегчить работу с множествами и ускорить их обработку. Список используемых источников1 Сухарев М.В. Основы Delphi. Профессиональный подход - СПб.: Наука и Техника, 2004. 2 Кэнту М. Delphi 7: для профессионалов - СПб.: Питер, 2004. ПриложениеТекст программы program Qtree; uses Forms, UnitMainForm in 'UnitMainForm.pas' {MainForm}, UnitModel in 'UnitModel.pas'; {$R *.res} begin Application.Initialize; Application.CreateForm(TMainForm, MainForm); Application.Run; end. unit UnitModel; interface uses Classes; const M = 3; //число точек в листе type //Тип узла дерева----------------------------------- TNodeKind = (nkBranch, nkLeaf); TPoint = record X: real; Y: real; end; TRect = record X1, Y1, X2, Y2: real; end; //Массив для хранения точек в листе----------------- TArrayOfPoints = array[1..M] of TPoint; //Узел дерева--------------------------------------- PNode = ^TNode; TNode = packed record case Kind: TNodeKind of nkBranch: (SZ, SV, YZ, YV: PNode); nkLeaf: (Points: TArrayOfPoints; PointsCount: integer); end; function InsertPoint(var Node: PNode; Bounds: TRect; Point: TPoint): boolean; procedure DeletePoint(var Node: PNode; Bounds: TRect; Point: TPoint); procedure ClearTree(var Node: PNode); function Find(Node: PNode; const Bounds, Rect: TRect): TList; implementation //Установка характеристик нового листа ======================================= procedure SetProperties(var ChildNode: PNode); begin New(ChildNode); ChildNode^.Kind:= nkLeaf; ChildNode^.PointsCount:= 0; //в массиве нет точек end; //Копирование точек из листа в дополнительный массив ========================= procedure CopyPoints(Node: PNode; var DopArray: TArrayOfPoints; var i: integer); var j: integer; begin for j:=1 to Node^.PointsCount do begin DopArray[i]:= Node^.Points[j]; inc(i); end; end; //ВСТАВКА ТОЧКИ В ДЕРЕВО ===================================================== function InsertPoint(var Node: PNode; Bounds: TRect; Point: TPoint): boolean; var CurNode: PNode; //текущий квадрант DopArray: TArrayOfPoints; //дополнительный массив (когда делим узел) i: integer; midX, midY: real; NewBounds: TRect; begin if Node = nil then begin New(Node); Node^.Kind:= nkLeaf; Node^.PointsCount:= 0; end; CurNode:= Node; Result:= true; with Bounds do begin while CurNode^.Kind = nkBranch do //если ветвь, то смотрим, куда идти begin midX:= (X2 - X1)/2 + X1; midY:= (Y2 - Y1)/2 + Y1; if Point.X < midX then if Point.Y < midY then begin CurNode:= CurNode^.SZ; X2:= midX; Y2:= midY; end else begin CurNode:= CurNode^.YZ; Y1:= midY; X2:= midX; end else if Point.Y < midY then begin CurNode:= CurNode^.SV; X1:= midX; Y2:= midY; end else begin CurNode:= CurNode^.YV; X1:= midX; Y1:= midY; end; end; midX:= (X2 - X1)/2 + X1; midY:= (Y2 - Y1)/2 + Y1; end; //Собственно вставка---------------------------------------------------------- //Проверить, есть ли место в массиве точек и нет ли уже там новой: for i:=1 to CurNode^.PointsCount do if (CurNode^.Points[i].X = Point.X)and(CurNode^.Points[i].Y = Point.Y) then begin Result:= false; Exit; end; //Если массив не заполнен, вставляем точку... if CurNode^.PointsCount < M then begin CurNode^.Points[CurNode^.PointsCount + 1]:= Point; CurNode^.PointsCount:= CurNode^.PointsCount + 1; end else begin //...иначе делим лист на 4 новых: DopArray:= CurNode^.Points; CurNode^.Kind:= nkBranch; SetProperties(CurNode^.SZ); SetProperties(CurNode^.SV); SetProperties(CurNode^.YZ); SetProperties(CurNode^.YV); //Распределение точек по узлам for i:=1 to M do with Bounds do if DopArray[i].X < midX then if DopArray[i].Y < midY then begin NewBounds.X1:= X1; NewBounds.X2:= (X2 - X1)/2 + X1; NewBounds.Y1:= Y1; NewBounds.Y2:= (Y2 - Y1)/2 + Y1; InsertPoint(CurNode^.SZ, NewBounds, DopArray[i]); end else begin NewBounds.X1:= X1; NewBounds.X2:= (X2 - X1)/2 + X1; NewBounds.Y1:= (Y2 - Y1)/2 + Y1; NewBounds.Y2:= Y2; InsertPoint(CurNode^.YZ, NewBounds, DopArray[i]); end else if DopArray[i].Y < midY then begin NewBounds.X1:= (X2 - X1)/2 + X1; NewBounds.X2:= X2; NewBounds.Y1:= Y1; NewBounds.Y2:= (Y2 - Y1)/2 + Y1; InsertPoint(CurNode^.SV, NewBounds, DopArray[i]); end else begin NewBounds.X1:= (X2 - X1)/2 + X1; NewBounds.X2:= X2; NewBounds.Y1:= (Y2 - Y1)/2 + Y1; NewBounds.Y2:= Y2; InsertPoint(CurNode^.YV, NewBounds, DopArray[i]); end; //Вставка новой точки InsertPoint(CurNode, Bounds, Point); end; end; //УДАЛЕНИЕ ТОЧКИ ИЗ ДЕРЕВА =================================================== procedure DeletePoint(var Node: PNode; Bounds: TRect; Point: TPoint); var CurNode, ParentNode: PNode; DopArray: TArrayOfPoints; midX, midY, PointsInNodes, numSZ, numSV, numYZ, numYV: real; there: boolean; i, N: integer; begin if Node = nil then Exit; CurNode:= Node; ParentNode:= CurNode; with Bounds do while CurNode^.Kind = nkBranch do //если ветвь, то смотрим, куда идти begin ParentNode:= CurNode; midX:= (X2 - X1)/2 + X1; midY:= (Y2 - Y1)/2 + Y1; if Point.X < midX then if Point.Y < midY then begin CurNode:= CurNode^.SZ; X2:= midX; Y2:= midY; end else begin CurNode:= CurNode^.YZ; Y1:= midY; X2:= midX; end else if Point.Y < midY then begin CurNode:= CurNode^.SV; X1:= midX; Y2:= midY; end else
Страницы: 1, 2, 3, 4
|