Карта сайтаСсылкиКонтакты

Простой способ поворота области (региона)

PDF Печать
Статьи

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

Вторая процедура делает то же самое с исходной областью без создания новой области (региона).


function _RotateRgn(ARgn : HRGN; ADegree : Real) : HRGN;
var
  wXFORM  : XFORM;    // структура трансформации, см. Windows API
  kRgnD   : DWord;    // количество структур RGNDATA в регионе
  RgnData : PRgnData; // указатель на данные региона
  Rt      : TRect;
  kX, kY  : Integer;
begin
  if (ARgn = 0) or (ADegree = 0) then
    Exit;
     
  // Получить окружность прямоугольной области
  GetRgnBox(ARgn, Rt);

  // Переместить исходный регион так, чтобы центр окружности проходил
  // по левому верхнему углу окна
  kX := Rt.Left+(Rt.Right -Rt.Left) div 2;
  kY := Rt.Top +(Rt.Bottom-Rt.Top) div 2;
  OffsetRgn(ARgn, -kX, -kY);

  // Заполнить XFORM согласно задаче (повернуть регион)
  FillChar(wXFORM, SizeOf(wXFORM), #0);
  wXFORM.eM11 := Cos(ADegree/180*pi);
  wXFORM.eM12 := -Sin(ADegree/180*pi);
  wXFORM.eM21 := -wXFORM.eM12;
  wXFORM.eM22 := wXFORM.eM11;

  // Подготовить буфер для хранения данных региона
  kRgnD := GetRegionData(ARgn, 0, nil);
  GetMem(RgnData, SizeOf(RGNDATA) * kRgnD);
  // ..и заполнить буфер данными региона
  GetRegionData(ARgn, kRgnD, RgnData);
  // ..переместить начальный регион в его начальную позицию
  OffsetRgn(ARgn, kX, kY);

  // Создать выходной регион, используя данные в буфере и преобразованном wXFORM
  Result := ExtCreateRegion(@wXFORM, kRgnD, RgnData^);
  // Переместить выходной регион на место исходного
  OffsetRgn(Result, kX, kY);
  FreeMem(RgnData);
end;

procedure _RotateRgnEx(Var ARgn : HRGN; ADegree : Real);
var
  wXFORM  : XFORM;
  kRgnD   : DWord;
  RgnData : PRgnData; // указатель на данные региона
  Rt      : TRect;
  kX, kY  : Integer;
begin
  if (ARgn = 0) or (ADegree = 0) then
    Exit;
     
  GetRgnBox(ARgn, Rt);

  kX := Rt.Left+(Rt.Right -Rt.Left) div 2;
  kY := Rt.Top +(Rt.Bottom-Rt.Top) div 2;
  OffsetRgn(ARgn, -kX, -kY);

  FillChar(wXFORM, SizeOf(wXFORM), #0);
  wXFORM.eM11 := Cos(ADegree/180*pi);
  wXFORM.eM12 := -Sin(ADegree/180*pi);
  wXFORM.eM21 := -wXFORM.eM12;
  wXFORM.eM22 := wXFORM.eM11;

  kRgnD := GetRegionData(ARgn, 0, nil);
  GetMem(RgnData, SizeOf(RGNDATA) * kRgnD);
  GetRegionData(ARgn, kRgnD, RgnData); 
  DeleteObject(ARgn); 

  ARgn := ExtCreateRegion(@wXFORM, kRgnD, RgnData^);
  // Перемещаем выходной регион на место оригинала
  OffsetRgn(ARgn, kX, kY);
  FreeMem(RgnData);
end;

 

Добавить комментарий


Защитный код
Обновить