Home > OS >  Pivot point for positioning Path in C# WPF canvas
Pivot point for positioning Path in C# WPF canvas

Time:10-02

so i have this Path and i need to place it rotated by its center in a coordinate. so i have this static Path in .xaml

        <Path Stroke="Black" RenderTransformOrigin="0.379,0.494" Canvas.Left="30" Canvas.Top="0">
            <Path.RenderTransform>
                <TransformGroup>
                    <RotateTransform Angle="-38.28"/>
                    <TranslateTransform X="-30" Y="-30"/>
                </TransformGroup>
            </Path.RenderTransform>
            <Path.Data>
                <PathGeometry>
                    <PathGeometry.Figures>
                        <PathFigureCollection>
                            <PathFigure StartPoint="75,30">
                                <PathFigure.Segments>
                                    <PathSegmentCollection>
                                        <LineSegment Point="0,0"/>
                                        <LineSegment Point="12,30"/>
                                        <LineSegment Point="0, 60"/>
                                        <LineSegment Point="75, 30"/>
                                    </PathSegmentCollection>
                                </PathFigure.Segments>
                            </PathFigure>
                        </PathFigureCollection>
                    </PathGeometry.Figures>
                </PathGeometry>
            </Path.Data>
        </Path>
        

but then i create it from code the same way and it just doesn't wanna center, it just starts rotating around the point

{
        PathGeometry pathGeom = new PathGeometry();
        Sprite = new Path
        {
            Data = pathGeom,
            RenderTransformOrigin = new Point(0.379, 0.5),
            Stroke = new SolidColorBrush(Color.FromArgb(120, 0, 0, 0)),
            Fill = new SolidColorBrush(Color.FromArgb(120, 30, 200, 7))
        };

        var pf = new PathFigure { StartPoint = new Point(75, 30) };
        pf.Segments.Add(new LineSegment { Point = new Point(0, 0) });
        pf.Segments.Add(new LineSegment { Point = new Point(12, 30) });
        pf.Segments.Add(new LineSegment { Point = new Point(0, 60) });
        pf.Segments.Add(new LineSegment { Point = new Point(75, 30) });
        pathGeom.Figures.Add(pf);
        
        UpdateRotation();
        canvas.Children.Add(Sprite);
        

    }

    private void UpdateRotation()
    {
        Sprite.RenderTransform = new TransformGroup
        {
            Children = new TransformCollection {
                new RotateTransform(Road.Angle   (Direction == -1 ? 90 : 0), -30, -30) , <-- i tried doing this
                new TranslateTransform(-30, -30), <-- and this separately, but they both didn't work
            }
        };
        Canvas.SetLeft(Sprite, Loc.X);
        Canvas.SetTop(Sprite, Loc.Y);
    }

here's what the static path looks like:what it looks like

CodePudding user response:

Arguments for RotateTransform are not the same in C# and xaml.

In xaml

<TransformGroup>
    <RotateTransform Angle="-38.28"/>
    <TranslateTransform X="-30" Y="-30"/>
</TransformGroup>

CenterX and CenterY are not set for RotateTransform, so their values are 0,0 respectively.

To get the identical output in C#, define rotate transform like new RotateTransform(-38.28, 0, 0)

private void UpdateRotation()
{
    Sprite.RenderTransform = new TransformGroup
    {
        Children = new TransformCollection {
            new RotateTransform(-38.28, 0, 0) , 
            new TranslateTransform(-30, -30), 
        }
    };
    Canvas.SetLeft(Sprite, 60);
    Canvas.SetTop(Sprite, 60);
}

CodePudding user response:

You may simplify your drawing by defining the pivot point as origin - with coordinates (0,0). There is no need for a TranslateTransform or a centered RotateTransform. You would also not have to create new transforms on each direction update. Just set the Angle property of the existing RotateTransform.

private Path Sprite { get; }

public MainWindow()
{
    InitializeComponent();

    Sprite = new Path
    {
        Data = Geometry.Parse("M0,0 L-12,-30 63,0 -12,30Z"),
        // or Data = Geometry.Parse("M-13,0 L-25,-30 50,0 -25,30Z"),
        // or whatever corresponds to the original RenderTransformOrigin

        RenderTransform = new RotateTransform(),
        Stroke = new SolidColorBrush(Color.FromArgb(120, 0, 0, 0)),
        Fill = new SolidColorBrush(Color.FromArgb(120, 30, 200, 7))
    };

    canvas.Children.Add(Sprite);

    UpdatePosition(100, 100, 45); // for example
}

private void UpdatePosition(double x, double y, double direction)
{
    ((RotateTransform)Sprite.RenderTransform).Angle = direction;
    Canvas.SetLeft(Sprite, x);
    Canvas.SetTop(Sprite, y);
}
  • Related