2014-11-23 29 views
0

我创建了一个帮助程序来演示我的问题。从c中的操作事件计算位置#

我有一个填充图像画笔的矩形,这个画笔可以使用手势操纵在矩形内进行变形。

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

下面是如何重现我的问题与下面附加的帮手应用程序: 运行该应用程序,只需移动(不捏)图像,直到您获取的位置值图像和矩形的左上角作为(0,0)。 下一页捏和移动图像,并一起返回左上角,现在你可以看到该值不是(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; 
    } 

回答

0

首先,找到初始上相对左上角的位置变换的中心。这是非常直接的减法。这些可以预先计算,因为变换前帧不会改变。您不希望通过在_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(); 

这将让事情相当接近准确的,除了一些舍入误差和一些古怪从翻译是通过改变位置,然后通过应用转换跟踪两种方式。通常你只会做后者。我会留下追踪,作为一个阅读练习:)

微软的Rob Caplan帮我解决了这个问题。