围绕手势点旋转/缩放

问题描述:

我想通过手势来移动/缩放/旋转用户控件,并且我希望旋转和缩放的中心点位于手势的中心(例如,当使用两个手指旋转,手指之间的点应该是旋转的中心)。围绕手势点旋转/缩放

当我不试图设置旋转/缩放的中心点或设置一个静态点时,一切都按预期工作。将CompositeTransform.CenterX/Y设置为ManipulationDeltaRoutedEventArgs.Position的值时,usercontrol将随着每个手势更加错误的中心点旋转,并偶尔会加速。

我使用的是CompositeTransform作为渲染变换我的用户控制的,我已经迷上了在ManipulationDelta事件,像这样:

private void UserControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
    { 
     //this.transform is my composite transform 
     //which is set to be the render transform of the user control 
     this.transform.CenterX = e.Position.X; 
     this.transform.CenterY = e.Position.Y; 
     this.transform.ScaleX *= e.Delta.Scale; 
     this.transform.ScaleY *= e.Delta.Scale; 
     this.transform.Rotation += e.Delta.Rotation; 
     this.transform.TranslateX += e.Delta.Translation.X; 
     this.transform.TranslateY += e.Delta.Translation.Y; 
    } 

看来,e.Position不给我我想要什么,不幸的是文档非常简短,只能说明Gets the point from which the manipulation originated.从我的调试打印中看来,CompositeTransform.CenterX/Y和ManipulationDeltaRoutedEventArgs.Position都位于用户控件的坐标系中。

问题原来是CompositeTransform只能处理一个中心点。因此,当中心点发生变化时,它也会对所有以前的变换进行追溯改变。解决方案是使用TransformGroup并使用自己的中心点创建单独的转换:

private void UserControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
    { 
     var localCoords = e.Position; 
     var relativeTransform = this.TransformToVisual(this.Container); 
     Point parentContainerCoords = relativeTransform.TransformPoint(localCoords); 
     var center = parentContainerCoords; 

     RotateTransform rotation = new RotateTransform(); 
     rotation.CenterX = center.X; 
     rotation.CenterY = center.Y; 
     rotation.Angle = e.Delta.Rotation; 
     this.transformGroup.Children.Add(rotation); 

     ScaleTransform scaling = new ScaleTransform(); 
     scaling.CenterX = center.X; 
     scaling.CenterY = center.Y; 
     scaling.ScaleX = e.Delta.Scale; 
     scaling.ScaleY = e.Delta.Scale; 
     this.transformGroup.Children.Add(scaling); 

     TranslateTransform translation = new TranslateTransform(); 
     translation.X = e.Delta.Translation.X; 
     translation.Y = e.Delta.Translation.Y; 
     this.transformGroup.Children.Add(translation); 
    }