C# 如何计算要缩放到的X/Y坐标

C# 如何计算要缩放到的X/Y坐标,c#,wpf,math,translation,zooming,C#,Wpf,Math,Translation,Zooming,我正在编写一个具有缩放和平移功能的WPF应用程序,但我还想实现“自动”(通过单击按钮)缩放和平移的功能 我已经定义了所有缩放和平移的方法,但是我很难告诉应用程序平移所需的X/Y坐标 基本上,我知道我希望控件以所需的缩放级别居中(例如放大6倍),但平移目标点不是控件的中心点,因为在缩放之后,它已被缩放 是否有人知道一种计算所需的X/Y平移位置的方法,同时考虑到缩放?我是否只缩放所需的目标点?它似乎对我不起作用 非常感谢 编辑--已完成-- 下面是我现在所拥有的一切,它工作得很好:) 最初,您的视口

我正在编写一个具有缩放和平移功能的WPF应用程序,但我还想实现“自动”(通过单击按钮)缩放和平移的功能

我已经定义了所有缩放和平移的方法,但是我很难告诉应用程序平移所需的X/Y坐标

基本上,我知道我希望控件以所需的缩放级别居中(例如放大6倍),但平移目标点不是控件的中心点,因为在缩放之后,它已被缩放

是否有人知道一种计算所需的X/Y平移位置的方法,同时考虑到缩放?我是否只缩放所需的目标点?它似乎对我不起作用

非常感谢

编辑--已完成--

下面是我现在所拥有的一切,它工作得很好:)


最初,您的视口位于(0,0),图像和视口的大小均为X X X Y。您希望通过一些放大系数m来缩放大小,以便图像的大小为mX X X Y,但您的视口(正在显示的部分)仍然是一个大小为X X X Y的矩形,位于图像上的(0,0)处。因此,您需要移动视图端口


如果您的图像现在是mX by mY,您可以通过将每个图像除以2来找到中点。然后可以减去视口大小的一半以获得左上角。类似于(mX/2-X/2,mY/2-Y/2)。

你说的是一种转变——一个平底锅和一个天平

您可以通过两种不同的方式来实现这一点,但是既然您使用的是WPF,那么有没有理由不使用RenderTransforms呢

var pointClicked = (where user clicked)
var myWindow = (whatever your window is);

myWindow.RenderTransform = new TransformGroup();
var pan = new TranslateTransform(pointClicked.X, pointClicked.Y);
var scale = new ScaleTransform(6.0,6.0);
myWindow.RenderTransform.Children.Add(pan);
myWindow.RenderTransform.Children.Add(scale);

如果不想走这条路线,则需要“手动”进行二维变换:但首先要进行平移,然后进行缩放。转换通常不是交流的;如果以不同的顺序进行转换,您将得到错误的结果。

我的转换工作正常,问题是我无法计算所需的X/Y转换,以便将点平移到屏幕中心。这就是我所指的操作顺序-您是否先尝试过转换(即,新中心=clickpoint.X,clickpoint.Y)然后执行缩放?换句话说:如果我单击点(50,50),我应该首先重新居中查看点(50,50),然后执行缩放缩放。如果你用另一种方法进行缩放,为了平移到正确的点,你必须按比例变换原始平移…这听起来比实际情况更令人困惑。基本上,为了计算deltaX/deltaY后期缩放,你需要取deltaX/deltaY的值,然后进行缩放通过缩放变换得到的向量。嗯,听起来是个正确的想法……我来试一试:)你就快到了-你只需要变换平移向量:deltaX=center.X-translaterataget.X*zoomTo;deltaY=center.Y-translaterateget.Y*zoomTo;删除/=行-这与你需要的相反。我理解你的意思,但是,我仍然不知道如何计算所需的翻译,以便使翻译动画化,使所需的点位于屏幕的中心。
    private void r1_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r1.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r1.ActualWidth, r1.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r2_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r2.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r2.ActualWidth, r2.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r3_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r3.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r3.ActualWidth, r3.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r4_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r4.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r4.ActualWidth, r4.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width/2), bounds.TopLeft.Y + (bounds.Height/2)));
    }

    public void ZoomInAndPan(double zoomTo, Point translateTarget)
    {
        var group = (ProductCanvas.RenderTransform as TransformGroup);

        var zoomTransform = group.Children[0] as ScaleTransform;
        var translateTransform = group.Children[3] as TranslateTransform;

        Point center = new Point(512, 384);

        destinationPoint.X *= newScale;
        destinationPoint.Y *= newScale;

        var deltaX = center.X - (translateTarget.X);
        var deltaY = center.Y - (translateTarget.Y);

        translateTransform.BeginAnimation(TranslateTransform.XProperty, CreateZoomAnimation(deltaX));
        translateTransform.BeginAnimation(TranslateTransform.YProperty, CreateZoomAnimation(deltaY));

        zoomTransform.BeginAnimation(ScaleTransform.ScaleXProperty, CreateZoomAnimation(zoomTo));
        zoomTransform.BeginAnimation(ScaleTransform.ScaleYProperty, CreateZoomAnimation(zoomTo));
    }

    private DoubleAnimation CreateZoomAnimation(double toValue)
    {
        var da = new DoubleAnimation(toValue, new Duration(TimeSpan.FromMilliseconds(700)))
        {
            AccelerationRatio = 0.1,
            DecelerationRatio = 0.9
        };

        return da;
    }
var pointClicked = (where user clicked)
var myWindow = (whatever your window is);

myWindow.RenderTransform = new TransformGroup();
var pan = new TranslateTransform(pointClicked.X, pointClicked.Y);
var scale = new ScaleTransform(6.0,6.0);
myWindow.RenderTransform.Children.Add(pan);
myWindow.RenderTransform.Children.Add(scale);