【问题标题】:Calculating positions from Manipulation events in c#从 C# 中的操作事件计算位置
【发布时间】:2015-01-21 01:59:13
【问题描述】:

我创建了一个帮助应用程序来演示我的问题。

我有一个用图像画笔填充的矩形,这个画笔可以使用手势操作在矩形内转换。

我正在从矩形的左上角确定图像左上角的位置。我在(仅)翻译图像时得到正确的值,但在使用捏合手势时得到错误的值。如果放大太多并平移图像,则画笔会向相反方向移动。

以下是如何使用下面附加的帮助应用程序重现我的问题: 运行应用程序,只需移动(不收缩)图像,直到将位置值设为 (0,0),即可将图像和矩形的左上角放在一起。 Next 捏合并移动图像,将左上角一起拉回,现在您可以看到该值不是(0,0)。

Download here

这是我的操作增量事件:

public virtual void Brush_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        if (e.PinchManipulation != null)
        {
            // Rotate
            _currentAngle = previousAngle + AngleOf(e.PinchManipulation.Original) - AngleOf(e.PinchManipulation.Current);

            // Scale
            _currentScale *= e.PinchManipulation.DeltaScale;

            // Translate according to pinch center
            double deltaX = (e.PinchManipulation.Current.SecondaryContact.X + e.PinchManipulation.Current.PrimaryContact.X) / 2 -
                (e.PinchManipulation.Original.SecondaryContact.X + e.PinchManipulation.Original.PrimaryContact.X) / 2;

            double deltaY = (e.PinchManipulation.Current.SecondaryContact.Y + e.PinchManipulation.Current.PrimaryContact.Y) / 2 -
                (e.PinchManipulation.Original.SecondaryContact.Y + e.PinchManipulation.Original.PrimaryContact.Y) / 2;

            _currentPos.X = previousPos.X + deltaX;
            _currentPos.Y = previousPos.Y + deltaY;
        }
        else
        {
            // Translate

            previousAngle = _currentAngle;
            _currentPos.X += e.DeltaManipulation.Translation.X;
            _currentPos.Y += e.DeltaManipulation.Translation.Y;
            previousPos.X = _currentPos.X;
            previousPos.Y = _currentPos.Y;
        }

        e.Handled = true;

        ProcesstTransform();
    }

    void ProcesstTransform()
    {
        CompositeTransform gestureTransform = new CompositeTransform();

        gestureTransform.CenterX = _currentPos.X;
        gestureTransform.CenterY = _currentPos.Y;

        gestureTransform.TranslateX = _currentPos.X - outputSize.Width / 2.0;
        gestureTransform.TranslateY = _currentPos.Y - outputSize.Height / 2.0;

        gestureTransform.Rotation = _currentAngle;

        gestureTransform.ScaleX = gestureTransform.ScaleY = _currentScale;

        brush.Transform = gestureTransform;
    }

【问题讨论】:

    标签: c# windows-phone-8 gesture


    【解决方案1】:

    首先,找到初始左上角相对于变换中心的位置。这几乎是直接的减法。这些可以预先计算,因为转换前的帧不会改变。您不想通过乘以 _scale 来预缩放 _brushSize。这将最终缩放画笔两次。

      Point origCentre = new Point(ManipulationArea.ActualWidth / 2, ManipulationArea.ActualHeight / 2);
      Point origCorner = new Point(origCentre.X - _brushSize.Width / 2, origCentre.Y - _brushSize.Height /2);
    

    然后将gestureTransform应用于角点: 点transCorner = gestureTransform.Transform(origCorner);

      XValue.Text = transCorner.X.ToString();
      YValue.Text = transCorner.Y.ToString();
    

    这将使事情变得非常接近准确,除了通过更改位置和应用变换来跟踪翻译的方式中的一些舍入误差和一些怪异。通常你只会做后者。我将把它作为练习留给读者:)

    来自 Microsoft 的 Rob Caplan 帮助我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2020-05-23
      • 2021-12-25
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      相关资源
      最近更新 更多