66110


環境/言語：Windows10 Professional, Visual Studio 2019 / WPF, C#

下記の様にCanvas子要素として追加したRectangleを、RotateTransformで角度を指定して回転させています。  
この時、Canvas上における、回転後のRectangleの各頂点座標を取得したいのですが、適当な方法が分からず質問させていただきました。  
Canvas.GetTopなどのメソッドを使っても、取得できるのは回転していない状態での座標となり、見た目状の頂点座標が  
取得できません。  
何か良い方法はないでしょうか？よろしくお願いいたします。

[code]

       <Canvas Name="TestCanvas">
                <Rectangle Name="TestRectangle" Fill="Red" Width="100" Height="100" Canvas.Left="100" Canvas.Top="100" RenderTransformOrigin="0.5,0.5">
    
                    <Rectangle.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="45"/>
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
    
        </Canvas>
    
[/code]

2020.04.30追記：  
v..snow様からの回答を元に、目的の座標が取得できるようになりました。  
確認用のコードを下記します。

[code]

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
    
            Testrect.RenderTransformOrigin = new Point(0.5, 0.5);
    
            Point xRenderTopLeftPt = GetTopLeftVertex(Testrect);
        }
    
        public Point GetTopLeftVertex(Rectangle dRectangle)
        {
            //Rectangle中心からみた回転前左上座標
            Point RectTopLeftFromRectCenter = new Point(-1 * dRectangle.Width / 2, -1 * dRectangle.Height / 2);
            //Canvas原点からみたRectangle中心座標
            Point RectCenterFromCanvasOrigin = new Point(Canvas.GetLeft(dRectangle) + dRectangle.Width / 2, Canvas.GetTop(dRectangle) + dRectangle.Height / 2); 
    
            var rendertransform = dRectangle.RenderTransform; //対象のRectangleのTransform情報
            var renderlocalTopLeft = rendertransform.Transform(RectTopLeftFromRectCenter); //Rectangle中心からみた回転後左上座標
    
            //Canvas原点からみた座標に変換
            var renderCanvasTopLeft = renderlocalTopLeft + new Vector(RectCenterFromCanvasOrigin.X, RectCenterFromCanvasOrigin.Y);
    
            //確認用ﾏｰｶｰ
            Ellipse marker = new Ellipse();
            marker.Fill = Brushes.Blue;
            marker.Width = 10;
            marker.Height = 10;
    
            Canvas.SetLeft(marker, renderCanvasTopLeft.X - marker.Width / 2);
            Canvas.SetTop(marker, renderCanvasTopLeft.Y - marker.Height / 2);
    
            TestCanvas.Children.Add(marker);
    
            return renderCanvasTopLeft;
    
        }
    
[/code]

[![実行後画像](https://i.stack.imgur.com/xCDT4.png)](https://i.stack.imgur.com/xCDT4.png)


CC BY-SA 4.0
2020-04-29T07:16:19.647
66097
2020-04-30T02:46:37.123
2020-04-30T02:46:37.123
39873
39873
question
c# wpf
Canvas子要素のRectangleオブジェクトを回転させた後で、見た目上のRectangleの各頂点座標を取得したい


トランスフォームの Transform メソッドで座標変換計算を行うことができます。  
<https://docs.microsoft.com/ja-
jp/dotnet/api/system.windows.media.generaltransform.transform>

例:

[code]

    <Window ... >
        <Grid>
            <Canvas Name="TestCanvas">
                <Rectangle Name="TestRectangle" Fill="Red" 
                           Width="100" Height="100" 
                           Canvas.Left="100" Canvas.Top="100" 
                           RenderTransformOrigin="0.5,0.5">
                    <Rectangle.RenderTransform>
                        <TransformGroup x:Name="TestTransform">
                            <RotateTransform Angle="45"/>
                        </TransformGroup>
                    </Rectangle.RenderTransform>
                </Rectangle>
                <Ellipse Name="TopLeftMarker" Fill="Blue" Width="10" Height="10"/>
            </Canvas>
        </Grid>
    </Window>
    
[/code]

[code]

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            ShowTopLeft();
        }
    
        void ShowTopLeft()
        {
            // (-50,-50): 長方形中心から見た変換前の左上の座標
            // (150,150): キャンバス原点から見た長方形中心の座標
            var renderlocalTopLeft = TestTransform.Transform(new Point(-50, -50));
            var renderCanvasTopLeft = renderlocalTopLeft + new Vector(150, 150);
    
            Trace.WriteLine($"{renderCanvasTopLeft.X} {renderCanvasTopLeft.Y}");
            Canvas.SetLeft(TopLeftMarker, renderCanvasTopLeft.X - TopLeftMarker.Width / 2);
            Canvas.SetTop(TopLeftMarker, renderCanvasTopLeft.Y - TopLeftMarker.Height / 2);
        }
    }
    
[/code]


CC BY-SA 4.0
2020-04-29T11:14:57.310
66110
2020-04-29T11:14:57.310
20885
66097
answer