Search code examples
uwpdirectxtransforminkcanvaswin2d

Resize an already drawn Inkstrokes in InkCanvas


I am drawing a rectangle boundary after selecting a specific stroke that I have drawn with a mouse click. After that, I want to resize the rectangle via dragging the corners of the rectangle. At the same time, I want to resize the stroke bounded by the rectangle as well.

For scaling, I tried to use Matrix3x2 scale1 = Matrix3x2.CreateScale(2.0f); foreach(var stroke in strokes) { stroke.PointTransform = scale1; }

But As I understood, When scaling. it uses the original coordinate system. ( I have marked the original coordinate system in the upper left corner of the second picture)

Is there a way to change the coordinate system when scaling? May be any matrix calculation?

If someone is downgrading my question, Please tell me why, So I can improve myself and rephrase the question. [Note: I'm using Custom Drying and Win2D to render InkStrokes, Application is written in C# for UWP]

enter image description here


Solution

  • I was able to find a way to do this. Let assume, we are moving the bottom right corner for resizing.

    1. Get and Draw the bounding Rect using SelectWithLine or SelectWithPolyLine functions. (This will set the Selected parameter of strokes to True as well)
    2. Get the scaling factors of xScale and yScale with the OnPointerMoved.
    3. With the movement of Pointer, redraw the stroke and bounding Rect.
    4. Scaling should be done as follows. (Maintain variables[xScalePrev, yScalePrev] to track whether both axes scaled with the pointer movement)

                  if (xScalePrev != xScale & yScalePrev != yScale)
                  {
                      Matrix3x2 scale1 = Matrix3x2.CreateScale(1 + (float)xScale, 1 + (float)yScale);
                      Matrix3x2 a = stroke.PointTransform * scale1;
                      float xOffset = a.M31 - (float)boundingRect.Left * (float)xScale;
                      float yOffset = a.M32 - (float)boundingRect.Top * (float)yScale;
                      stroke.PointTransform = new Matrix3x2(a.M11, a.M12, a.M21, a.M22, xOffset, yOffset);
      
                      xScalePrev = xScale;
                      yScalePrev = yScale;
                  }
                  else if (xScalePrev != xScale)
                  {
                      Matrix3x2 scale1 = Matrix3x2.CreateScale(1 + (float)xScale, 1);
                      Matrix3x2 a = stroke.PointTransform * scale1;
                      float xOffset = a.M31 - (float)boundingRect.Left * (float)xScale;
                      stroke.PointTransform = new Matrix3x2(a.M11, a.M12, a.M21, a.M22, xOffset, a.M32);
      
                      xScalePrev = xScale;
                  }
                  else if (yScalePrev != yScale)
                  {
                      Matrix3x2 scale1 = Matrix3x2.CreateScale(1, 1 + (float)yScale);
                      Matrix3x2 a = stroke.PointTransform * scale1;
                      float yOffset = a.M32 - (float)boundingRect.Top * (float)yScale;
                      stroke.PointTransform = new Matrix3x2(a.M11, a.M12, a.M21, a.M22, a.M31, yOffset);
      
                      yScalePrev = yScale;
                  }
      

    This is how I achieved resizing with the Bottom-Right corner. Similarly, this can be implemented in other corners as well.