Обновление четырех точек, чтобы они оставались в форме прямоугольника при перемещении одной из них

Я пытаюсь нарисовать прямоугольный объект, который позволяет пользователю щелкнуть угловую точку, чтобы изменить размер, а также повернуть прямоугольник в 2D-пространстве.

Поэтому я использую массив из четырех точек, упорядоченных A, B, C, D (или 0, 1, 2, 3) от верхнего левого до нижнего левого по часовой стрелке.

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

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

ИСХОДНЫЙ КОД ЗДЕСЬ

https://www.assembla.com/code/moozhe-testing/subversion/nodes/rotateRectangle

ВЫДЕРЖКА КОДА ПРОБЛЕМЫ

private void MovePoint(int id, PointF newPoint)
{
    PointF oldPoint = points[id];
    PointF delta = newPoint.Substract(oldPoint);

    PointF pointPrevious = points[(id + 3) % 4];
    PointF pointNext = points[(id + 1) % 4];

    PointF sidePrevious = pointPrevious.Substract(oldPoint);
    PointF sideNext = pointNext.Substract(oldPoint);

    PointF previousProjection = Projection(delta, sidePrevious);
    PointF nextProjection = Projection(delta, sideNext);

    pointNext = pointNext.AddPoints(previousProjection);
    pointPrevious = pointPrevious.AddPoints(nextProjection);

    points[(id + 3) % 4] = pointPrevious;
    points[(id + 1) % 4] = pointNext;
    points[id] = newPoint;
}

private PointF Projection(PointF vectorA, PointF vectorB)
{
    PointF vectorBUnit = new PointF(vectorB.X, vectorB.Y);
    vectorBUnit = vectorBUnit.Normalize();

    float dotProduct = vectorA.X * vectorBUnit.X + vectorA.Y * vectorBUnit.Y;
    return vectorBUnit.MultiplyByDecimal(dotProduct);
}

person Trevor Elliott    schedule 18.09.2011    source источник


Ответы (1)


Похоже, вы, возможно, захотите использовать матрицу преобразования вместо обновления координат X/Y вручную. Пожалуйста, проверьте эту ссылку:

Сравнение режимов отображения GDI с преобразованиями GDI+

Вот ссылка MSDN:

https://docs.microsoft.com/en-us/dotnet/api/system.drawing.graphics.transform

person paulsm4    schedule 18.09.2011
comment
Я использую матричные преобразования для рисования, но не для перевода пользовательского ввода. Мне нужно иметь возможность определить, нажата ли конкретная точка. Не все будет вращаться, у меня может быть много объектов, каждый со своими углами поворота. Есть ли для меня реальный способ сделать это? Разве я не приду к той же математике, только на лету, а не заранее? - person Trevor Elliott; 18.09.2011