さて、左上隅を中心に回転させたいImageオブジェクトがあります。'X'度のRotateTransformを設定します。マイイメージのマージンは(400,400,0,0)に設定されています。これにより、キャンバスの中央に配置されます。
問題は、異なる回転角を適用すると、画像が左右にシフトすることです。投稿を見ると、なぜこれが起こっているのかがわかりました。回転変換は境界の長方形を計算するため、画像を回転すると、境界の長方形が大きくなります。マージンはその境界の長方形に適用され、角度が変化すると実際の画像が下方向および右方向にシフトします。
私が欲しいのは、画像の左上隅が常にキャンバス上で正確に(400,400)にあり、画像がその点を中心に回転することです。
私はいくつかの計算を行い、左右のマージンをシフトすることで動作させることができますが、次の式を使用して、象限1と4(0〜90度)および(270〜360度)でのみ正しい計算を行うことができます。
0〜90度の場合:(マージンのTOP部分を変更する必要があります。必要なマージンは(400,400,0,0)Margin =(400-sin(angle)* Image.Height、400、0、0);
270〜360度の場合:(マージンの上部を変更する必要があります。必要なマージンは(400,400,0,0)です。Margin=(400、400 + sin(angle)* Image.Width、0、0);
RotateTransform.Transform(point)とImage.TranslatPoint(point)を使用して実験しましたが、それらを機能させることができないようです。
誰か私に何か提案はありますか?
いつでも画像の結合長方形が何であるかを理解できれば、その幅/高さと画像の幅/高さの違いを理解し、それを使用してマージンを適切にシフトできると思います。
私は自分の問題を示す小さなアプリをまとめました。実行中、アプリは長方形の左上を配置したい場所に赤い点を表示します。画像の代わりにグリッドを使用するように簡略化しました。画面の左上には、回転角を指定できるテキストボックスがあります。テキストボックスの右側には2つのRepeatButtonがあり、クリックして押したままにすると角度が増減します。角度を変更すると、グリッドの左上隅が赤い点から離れる方向にシフトすることに注意してください。左上隅にピンを置き、コーナーが始まるドットからずれることなくピンを中心に回転させたように動作させたいです。
ご協力いただきありがとうございます。
サンプルアプリのコードは次のとおりです。
xaml:
<Window x:Class="RenderTransformTester.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="900" Width="900">
<Canvas x:Name="_canvas">
<Grid x:Name="_gridImage" Width="400" Height="200" Canvas.Left="400" Canvas.Top="400" Background="Navy">
<Grid.LayoutTransform>
<RotateTransform Angle="45" CenterX="0" CenterY="0"/>
</Grid.LayoutTransform>
</Grid>
<Ellipse Fill="Red" Width="20" Height="20" Margin="390,390,0,0"/>
<TextBox x:Name="_textBoxAngle" Width="70" Height="30" TextChanged="_textBoxAngle_TextChanged" Text="0"/>
<RepeatButton x:Name="_buttonUp" Width="30" Height="15" Margin="70,0,0,0" Click="_buttonUp_Click"/>
<RepeatButton x:Name="_buttonDown" Width="30" Height="15" Margin="70,15,0,0" Click="_buttonDown_Click"/>
</Canvas>
</Window>
CodeBehind:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace RenderTransformTester
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
static double _left = -1;
static double _top = -1;
public MainWindow()
{
InitializeComponent();
}
private void _textBoxAngle_TextChanged(object sender, TextChangedEventArgs e)
{
int angle;
int.TryParse(_textBoxAngle.Text, out angle);
angle += 720;
angle %= 360;
_gridImage.LayoutTransform = new RotateTransform(angle, 0, 0);
}
private void _buttonUp_Click(object sender, RoutedEventArgs e)
{
int angle;
int.TryParse(_textBoxAngle.Text, out angle);
angle++;
angle = angle % 360;
_textBoxAngle.Text = angle.ToString();
}
private void _buttonDown_Click(object sender, RoutedEventArgs e)
{
int angle;
int.TryParse(_textBoxAngle.Text, out angle);
angle--;
angle = angle % 360;
_textBoxAngle.Text = angle.ToString();
}
private static double RadiansToDegrees(double radians)
{
return radians * 180 / Math.PI;
}
private static double DegreesToRadians(double degrees)
{
return degrees * Math.PI / 180;
}
}
}