The solution is to add a translation which cancels the move of the center of canvas after a rotation: so i have done some modification to you method UpdateResizeArea (mathematic solution)
private void UpdateResizeArea(Point currentMousePoint)
{
:
:
switch (_activeResizeAreaSide)
{
case SelectionArea.ResizeSide.LEFT:
{
_activeResizeArea.OffsetX = _activeResizeAreaXbeforeStart + deltaX;
_activeResizeArea.AreaWidth = _activeResizeAreaWidthbeforeStart - deltaX;
var tg = new TransformGroup();
var rad = _activeResizeArea.Rotation * Math.PI / 180;
var cx = _activeResizeArea.CalculateCenterPoint().X - _activeRotateAreaCenterPointBeforeStart.X;
var cy = _activeResizeArea.CalculateCenterPoint().Y - _activeRotateAreaCenterPointBeforeStart.Y;
var tx = cx * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d + cy * Math.Sin(rad);
var ty = cx * Math.Sin(rad) - cy * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d;
var t = new TranslateTransform(-tx, ty);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
case SelectionArea.ResizeSide.TOP:
{
_activeResizeArea.OffsetY = _activeResizeAreaYbeforeStart + deltaY;
_activeResizeArea.AreaHeight = _activeResizeAreaHeightbeforeStart - deltaY;
var tg = new TransformGroup();
var rad = _activeResizeArea.Rotation * Math.PI / 180;
var cx = _activeResizeArea.CalculateCenterPoint().X - _activeRotateAreaCenterPointBeforeStart.X;
var cy = _activeResizeArea.CalculateCenterPoint().Y - _activeRotateAreaCenterPointBeforeStart.Y;
var tx = cy * Math.Sin(rad) + cx * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d;
var ty = cy * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d - cx * Math.Sin(rad);
var t = new TranslateTransform(-tx, -ty);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
case SelectionArea.ResizeSide.RIGHT:
{
_activeResizeArea.AreaWidth = _activeResizeAreaWidthbeforeStart + deltaX;
var tg = new TransformGroup();
var rad = _activeResizeArea.Rotation * Math.PI / 180;
var cx = _activeResizeArea.CalculateCenterPoint().X - _activeRotateAreaCenterPointBeforeStart.X;
var cy = _activeResizeArea.CalculateCenterPoint().Y - _activeRotateAreaCenterPointBeforeStart.Y;
var tx = cx * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d + cy * Math.Sin(rad);
var ty = cx * Math.Sin(rad) - cy * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d;
var t = new TranslateTransform(-tx, ty);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
case SelectionArea.ResizeSide.BOTTOM:
{
_activeResizeArea.AreaHeight = _activeResizeAreaHeightbeforeStart + deltaY;
var tg = new TransformGroup();
var rad = _activeResizeArea.Rotation * Math.PI / 180;
var cx = _activeResizeArea.CalculateCenterPoint().X - _activeRotateAreaCenterPointBeforeStart.X;
var cy = _activeResizeArea.CalculateCenterPoint().Y - _activeRotateAreaCenterPointBeforeStart.Y;
var tx = cy * Math.Sin(rad) + cx * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d;
var ty = cy * Math.Sin(rad / 2d) * Math.Sin(rad / 2d) * 2d - cx * Math.Sin(rad);
var t = new TranslateTransform(-tx, -ty);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
}
you could adapt the solution to your project.. because i have just added some lines of coding without changing the logic of your program
__________________________________________________________________________________
Another solution (without math calculus) is to precalculate the difference betwwen the position of one point of canvas with the initial Center of rotation and the new position of same point with the new center:
switch (_activeResizeAreaSide)
{
case SelectionArea.ResizeSide.LEFT:
{
_activeResizeArea.OffsetX = _activeResizeAreaXbeforeStart + deltaX;
_activeResizeArea.AreaWidth = _activeResizeAreaWidthbeforeStart - deltaX;
var ir = new RotateTransform(_activeResizeArea.Rotation, _activeRotateAreaCenterPointBeforeStart.X, _activeRotateAreaCenterPointBeforeStart.Y);
var fr = new RotateTransform(_activeResizeArea.Rotation, _activeResizeArea.CalculateCenterPoint().X, _activeResizeArea.CalculateCenterPoint().Y);
var ip = ir.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var fp = fr.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var tg = new TransformGroup();
var txx = ip.X - fp.X;
var tyy = ip.Y - fp.Y;
var t = new TranslateTransform(txx, tyy);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
case SelectionArea.ResizeSide.TOP:
{
_activeResizeArea.OffsetY = _activeResizeAreaYbeforeStart + deltaY;
_activeResizeArea.AreaHeight = _activeResizeAreaHeightbeforeStart - deltaY;
var ir = new RotateTransform(_activeResizeArea.Rotation, _activeRotateAreaCenterPointBeforeStart.X, _activeRotateAreaCenterPointBeforeStart.Y);
var fr = new RotateTransform(_activeResizeArea.Rotation, _activeResizeArea.CalculateCenterPoint().X, _activeResizeArea.CalculateCenterPoint().Y);
var ip = ir.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var fp = fr.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var tg = new TransformGroup();
var txx = ip.X - fp.X;
var tyy = ip.Y - fp.Y;
var t = new TranslateTransform(txx, tyy);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
case SelectionArea.ResizeSide.RIGHT:
{
_activeResizeArea.AreaWidth = _activeResizeAreaWidthbeforeStart + deltaX;
var ir = new RotateTransform(_activeResizeArea.Rotation, _activeRotateAreaCenterPointBeforeStart.X, _activeRotateAreaCenterPointBeforeStart.Y);
var fr = new RotateTransform(_activeResizeArea.Rotation, _activeResizeArea.CalculateCenterPoint().X, _activeResizeArea.CalculateCenterPoint().Y);
var ip = ir.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var fp = fr.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var tg = new TransformGroup();
var txx = ip.X - fp.X;
var tyy = ip.Y - fp.Y;
var t = new TranslateTransform(txx, tyy);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
case SelectionArea.ResizeSide.BOTTOM:
{
_activeResizeArea.AreaHeight = _activeResizeAreaHeightbeforeStart + deltaY;
var ir = new RotateTransform(_activeResizeArea.Rotation, _activeRotateAreaCenterPointBeforeStart.X, _activeRotateAreaCenterPointBeforeStart.Y);
var fr = new RotateTransform(_activeResizeArea.Rotation, _activeResizeArea.CalculateCenterPoint().X, _activeResizeArea.CalculateCenterPoint().Y);
var ip = ir.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var fp = fr.Transform(new Point(_activeResizeArea.OffsetX, _activeResizeArea.OffsetY));
var tg = new TransformGroup();
var txx = ip.X - fp.X;
var tyy = ip.Y - fp.Y;
var t = new TranslateTransform(txx, tyy);
tg.Children.Add(_activeResizeArea.RotateTransform);
tg.Children.Add(t);
_activeResizeArea.AreaCanvas.RenderTransform = tg;
}
break;
}
Result: