Проще всего определить имеют ли два контрола точки пересечения или нет, используя функцию TRectF.IntersectsWith. Которая позволяет определить пересекаются ли два указанных прямоугольника или нет.
Далее остается определить регионы контролов:
Контролы имею общего родителя. В этом случае они лежат на одном уровне и являются дочерними объектами одного и того же родителя. А это значит, что в качестве их положения можно взять их регион в родительских координатах TControl.ParentedRect.
Контролы не имеют общего родителя. В этом случае нужно воспользоваться регионом взятым в абсолютных координатах формы. То есть TControl.AbsoluteRect.
Весь код функции определения пересечения двух контролов представлена ниже:
function IsControlIntersected(const AControl1: TControl; const AControl2: TControl): Boolean;
var
ControlRect1: TRectF;
ControlRect2: TRectF;
begin
Assert(AControl1 <> nil);
Assert(AControl2 <> nil);
if AControl1.Parent = AControl2.Parent then
begin
ControlRect1 := AControl1.ParentedRect;
ControlRect2 := AControl2.ParentedRect;
end
else
begin
ControlRect1 := AControl1.AbsoluteRect;
ControlRect2 := AControl2.AbsoluteRect;
end;
Result := ControlRect1.IntersectsWith(ControlRect2);
end;
P.S. Мы могли бы всегда вычислять пересечение путем взятия абсолютного положения контролов. Однако, получение абсолютного положения контрола через AbsoluteRect выполняет дополнительные действия по конвертации координат (с учетом матрицы преобразования), что при очень частом использовании может быть не выгодным. Именно по этому правильнее будет использование абсолютных координат только в том, случае, когда это действительно необходимо. Именно по этому код функции IsControlIntersected имеет в себе два подхода.