2
votes

Let's suppose I have an element that I want to rotate and scale in a visual designer: A user should be able to drag the edges and the graphics should scale appropriately.
The rotation is entered in degree.



Following fact is an issue with rotated element:
When the top left point is dragged not only the width and height will change, but the top left position as well. When the top right point is dragged then the size changes, and the Y-Position as well

If the element is rotated however (WPF RenderTransform, rotated around it's center) then the behaviour must change accordingly, and I dont know how. Assuming the element is rotated 90° then the point that was top left previously is the top right one.
Which means that I have to transform something, but I'm totally stumped I'm afraid

I'm looking for a behaviour that is implemented in any graphical program.
The user basically drags points of the bounding box and the graphic should be projected inside the box.

How can this problem be solved in WPF?
The elements that are drawn derive from UIElement, so I can access all the transform properties needed. The solution should work for any rotation entered.
I'd appreciate if you could help me, or point me in the right direction.

Edit:
I know how to scale and rotate the elements. The desired result is that the element perfectly fits in the box the user dragged. So this problem is more math related than WPF related.

Edit:
Thanks for downvoting without providing me a suggestion on what I could improve.
In order to understand the problem try the following:
Create a new WPF Project, add ANY UIElement and rotate it, 90° for example.
Now remember the margin BEFORE you drag, and drag the bottom right point somewhere. As you can see the margin (= position) changes as well. My question would be how to calculate this compensation to give the user the desired result when dragging. Because if I do not change the position to compensate the scale, than the result is just weird and doesn't behave as expected.
The compensation depends on the scale of the element. Obviously.
Please refer to the following picture:
What you see here is the Canvas.Top and Canvas.Left property before I dragged the bottom right point, and below after I dragged the bottom right point.
http://imageshack.us/photo/my-images/268/beforeaftert.png/?sa=0

2

2 Answers

1
votes

You should use a TransformGroup.

In a TransformGroup you can have a ScaleTransform, RotateTransform, TranslateTransform, and SkewTransform at the same time (in that order, this is important).

This way you can map every action to a different transform.

You don't actually need to take into account the different points, you just need to map mouse movements to different transforms. For example:

If one of the corners is clicked, every mouse move will trigger a change in the ScaleTransform. If you click a rotation-point, you can trigger changes in the RotateTransform.

If you need to scale, skew or rotate around different points of the center, you will need a compensation transformation for the one you are currently executing:

  • A ScaleTransform will need a translateTransformation to compensate for the lateral / vertical difference caused by the scaling.
  • When rotating around a different center point, you can just alter the centerX / centerY of the rotatetransform
1
votes

Maybe have a look at http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-1 The resize part covers these issues. The basic idea is to recognize the element where you click for resizing (left corner, right corner etc.) Then there is the 'math' stuff to set Left and Top of your Canvas.