我有一个Rectangle
,可以通过将其RenderTransform属性设置为TransformGroup
来进行转换。转换组包含以下转换:SkewTransform
,RotateTransform
,TranslateTransform
。
现在,我想创建一个确定Point
是否位于矩形附近的方法。因此,不仅当该点是in(变形的)矩形时,而且当它非常接近它时。不仅仅是从矩形的中心开始使用假想的圆/半径。
确定该点是否足够接近并可以视为接近的阈值,始终与变换后的矩形轮廓处于相同距离。您可以看到它就像矩形具有30像素的边框。当该点位于此边界(或矩形本身)中时,结果为true。否则结果为false。
拥有.NET框架的所有帮助,这似乎很容易。它尝试了几种方法,例如使用Visual.pointFromScreen()
。反转转换等。但是我一直做错了。
为了使事情变得更加困难,我还在寻找一种快速有效的解决方案。
我尝试过的代码:
public bool IsInHitArea(Point pt)
{
// _transformedRect = my rectangle
// HitRectangleMargin = proximity treshold.
// _offsetX, _offsetY = x and y position of rectangle
// _areaWidth, _areaHeight = width/height of rectangle
Point p = _transformedRect.PointFromScreen(pt);
return (p.X >= _offsetX - HitRectangleMargin
&& p.X <= _offsetX + _areaWidth + HitRectangleMargin
&& p.Y >= _offsetY - HitRectangleMargin
&& p.Y <= _offsetY + _areaHeight + HitRectangleMargin);
}
// Or another try
public bool IsInHitArea(Point pt)
{
// TransformGroup is a property containing the transform group.
Point p = TransformGroup.Inverse.Transform(pt);
// I actually don't really undersand if it's maybe naive to use just the following
// equations:
return (p.X >= _offsetX - HitRectangleMargin
&& p.X <= _offsetX + _areaWidth + HitRectangleMargin
&& p.Y >= _offsetY - HitRectangleMargin
&& p.Y <= _offsetY + _areaHeight + HitRectangleMargin);
}
代替使用由RenderTransform
转换的矩形,最好使用具有转换后的RectangleGeometry
的路径。
您可以用另一个具有透明Stroke
和Fill
和足够宽StrokeThickness
的路径覆盖显示的路径,以在显示的矩形附近捕获鼠标输入。
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Canvas>
<Path Data="{Binding TransformedRectangle}"
StrokeThickness="3" Stroke="Black"/>
<Path Data="{Binding TransformedRectangle}"
StrokeThickness="60" Stroke="Transparent" StrokeLineJoin="Round"
Fill="Transparent"
MouseLeftButtonDown="PathMouseLeftButtonDown"/>
</Canvas>
提供转换后的几何体的示例视图模型:
public class ViewModel
{
public RectangleGeometry TransformedRectangle { get; } = new RectangleGeometry();
public ViewModel()
{
var transform = new TransformGroup();
transform.Children.Add(new ScaleTransform(2, 1));
transform.Children.Add(new SkewTransform(30, 0));
transform.Children.Add(new RotateTransform(45, 250, 150));
TransformedRectangle.Rect = new Rect(100, 100, 100, 100);
TransformedRectangle.Transform = transform;
}
}