Изменение размера уже нарисованных мазков в InkCanvas

Я рисую границу прямоугольника после выбора определенного штриха, который я нарисовал щелчком мыши. После этого я хочу изменить размер прямоугольника, перетаскивая углы прямоугольника. В то же время я хочу также изменить размер обводки, ограниченной прямоугольником.

Для масштабирования я пытался использовать Matrix3x2 scale1 = Matrix3x2.CreateScale(2.0f); foreach(var stroke in strokes) { stroke.PointTransform = scale1; }

Но как я понял, при масштабировании. он использует исходную систему координат. (Я отметил исходную систему координат в верхнем левом углу второго изображения)

Есть ли способ изменить систему координат при масштабировании? Может быть какой-то матричный расчет?

Если кто-то понижает оценку моего вопроса, скажите, пожалуйста, почему, чтобы я мог исправиться и перефразировать вопрос. [Примечание. Я использую Custom Drying и Win2D для рендеринга InkStrokes, приложение написано на C# для UWP]

введите здесь описание изображения


person Gayashan Rathnavibushana    schedule 24.04.2020    source источник


Ответы (2)


Вы хотите использовать координату «А» при масштабировании? Судя по второму рисунку, вы, кажется, хотите масштабировать штрихи на основе нижнего левого угла «А», затем вы можете создать матрицу масштабирования, которая смещена на заданную центральную точку. Например:

var container = inkCanvas.InkPresenter.StrokeContainer;

var bounds = container.BoundingRect;
var center = new Vector2((float)bounds.Left, (float)bounds.Bottom);
var transform = Matrix3x2.CreateScale(2.0f, 2.0f, center);

foreach (var stroke in strokes)
{
    stroke.PointTransform = transform;
}
person Faywang - MSFT    schedule 27.04.2020
comment
Да, спасибо за ответ. Я также добавляю ответ при изменении размера с правым нижним углом. Я взял центр как Верхний левый угол. Дело в том, что когда я двигаю указатель мыши слишком быстро, масштабирование лагает. Вы имеете какое-нибудь представление об этом? Я получаю коэффициент масштабирования x, получая координату смещения x при перемещении указателя относительно исходной ширины ограничивающего Rect. Это проблема масштабирования или что-то связанное с движением указателя? - person Gayashan Rathnavibushana; 27.04.2020
comment
Я заметил, что вы упомянули, что с движением указателя вы будете перерисовывать обводку и ограничивающий прямоугольник. Возможно, несколько рендеров за короткое время вызовут задержку, вы можете попробовать использовать таймер и принудительно перерисовывать с фиксированным интервалом времени (например, 80 мс) при перемещении мыши, это уменьшит количество рендеров и сделает их более плавными. - person Faywang - MSFT; 27.04.2020

Я смог найти способ сделать это. Предположим, мы перемещаем нижний правый угол для изменения размера.

  1. Получите и нарисуйте ограничивающий прямоугольник, используя функции SelectWithLine или SelectWithPolyLine. (Это также установит для параметра Selected штрихов значение True)
  2. Получите коэффициенты масштабирования xScale и yScale с помощью OnPointerMoved.
  3. Движением указателя перерисуйте обводку и ограничивающий прямоугольник.
  4. Масштабирование должно производиться следующим образом. (Поддерживайте переменные [xScalePrev, yScalePrev], чтобы отслеживать, масштабируются ли обе оси при движении указателя)

                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;
                }
    

Вот как я добился изменения размера нижнего правого угла. Точно так же это можно реализовать и в других углах.

person Gayashan Rathnavibushana    schedule 27.04.2020