【问题标题】:Check if point is in proximity of transformed rectangle检查点是否在转换后的矩形附近
【发布时间】:2019-09-25 09:26:51
【问题描述】:

我有一个 Rectangle,通过将其 RenderTransform 属性设置为 TransformGroup 来进行转换。转换组包含以下转换:SkewTransformRotateTransformTranslateTransform

现在我想创建一个方法来确定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);
}

【问题讨论】:

  • 请提供您尝试过的最佳代码
  • 制作一个变换后的矩形的不可见副本,将其放大以匹配阈值周长,然后检查点是否在该矩形内......这就是我要做的,大致。
  • Rectangle 究竟是如何转换的?通过它的 RenderTransform,还是使用带有转换后的几何图形的路径作为其数据?
  • @Clemens 通过在矩形上设置 RenderTransform 属性。

标签: c# wpf transform collision-detection rectangles


【解决方案1】:

与其使用由其RenderTransform 转换的矩形,不如使用带有转换后的RectangleGeometry 的路径。

您可以用另一个具有透明的StrokeFill 和足够宽的StrokeThickness 的路径覆盖显示的路径,以便在显示的矩形附近捕获鼠标输入。

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>
<Canvas>
    <Path Data="{Binding TransformedRectangle}"
          StrokeThickness="3" Stroke="Black"/>

    <Path Data="{Binding TransformedRectangle}"
          StrokeThickness="60" StrokeLineJoin="Round"
          Stroke="Transparent" 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;
    }
}

【讨论】:

    猜你喜欢
    • 2013-06-12
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多