Raheel Khan
Raheel Khan

Reputation: 14787

Overlay geometry objects in WPF such that each has the same dimensions but different transformations

I have been stuck with this issue for a week now and have tried multiple approaches.

I have a drawing of a balance scale as shown below. I have split up this image into two such that the base + vertical shaft represent one image while the horizontal bar represents another. I then extract path geometries from both and try to draw them from within a single custom shape or as a visual layer drawing.

As you can imagine, the base+vertical shaft need to stay static while the horizontal bar needs to rotate on its center point up to a certain degree of freedom. The WPF is simply:

<Canvas>
    <!-- Custom Shape or Visual Layer Drawing here. -->
</Canvas>

Problem: Since I want both geometries to have the same left, top, right, bottom values, I use either a single custom Shape or a single DrawingVisual, try to draw both geometries which works fine. However, when I apply a transform to either one of them, the transform gets applied to both making the base+vertical shaft move as well.

Question: Please note that I am not trying to find a fix to the code I already have since I have tried to ask the question before many times in vain e.g. here. Could someone please explain how to achieve an overlay like this from scratch?

Balance Scale

Upvotes: 1

Views: 1313

Answers (1)

Clemens
Clemens

Reputation: 128061

Maybe your approach with a custom shape and drawing visuals is too complicated. Try the following pure XAML solution (of course with simplified geometries) to get an idea how this could be done with just a Path and a few geometries.

<Canvas>
    <Path Canvas.Left="200" Canvas.Top="100" Fill="Black">
        <Path.Data>
            <GeometryGroup FillRule="Nonzero">
                <PathGeometry Figures="M0,0 L50,200 -50,200 Z"/>
                <GeometryGroup>
                    <GeometryGroup.Transform>
                        <RotateTransform
                            Angle="{Binding Value,ElementName=angleSlider}"/>
                    </GeometryGroup.Transform>
                    <PathGeometry Figures="M-100,-5 L100,-5 100,5 -100,5 Z"/>
                    <PathGeometry Figures="M-100,0 L-75,100 L-125,100 Z">
                        <PathGeometry.Transform>
                            <TransformGroup>
                                <RotateTransform CenterX="-100"
                                    Angle="{Binding Value,ElementName=angleSlider}"/>
                                <ScaleTransform ScaleX="-1" CenterX="-100"/>
                            </TransformGroup>
                        </PathGeometry.Transform>
                    </PathGeometry>
                    <PathGeometry Figures="M100,0 L75,100 L125,100 Z">
                        <PathGeometry.Transform>
                            <TransformGroup>
                                <RotateTransform CenterX="100"
                                    Angle="{Binding Value,ElementName=angleSlider}"/>
                                <ScaleTransform ScaleX="-1" CenterX="100"/>
                            </TransformGroup>
                        </PathGeometry.Transform>
                    </PathGeometry>
                </GeometryGroup>
            </GeometryGroup>
        </Path.Data>
    </Path>        
</Canvas>
...
<Slider x:Name="angleSlider" Minimum="-45" Maximum="45"/>

Edit: in order to make this scalable you may set the Canvas Width and Height to fixed values (those given by the contained geometries) and put the whole thing in a Viewbox:

<Viewbox>
    <Canvas Width="250" Height="205">
        ...
    </Canvas>
</Viewbox>

Upvotes: 2

Related Questions