Правильный алгоритм изменения размера прямоугольника при перетаскивании мышью - PullRequest
1 голос
/ 03 августа 2020

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

В настоящее время я делаю что-то вроде:

 rect.onMouseDrag = event => {
    let selectedNode = rect.selectedNode;
      selectedNode.point.x += event.delta.x;
      selectedNode.point.y += event.delta.y;
      switch (rect.selectedNode.index) {
        case 0:
          rect.segments[1].point.x += event.delta.x;
          rect.segments[3].point.y += event.delta.y;
          break;
        case 1:
          rect.segments[0].point.x += event.delta.x;
          rect.segments[2].point.y += event.delta.y;
          break;
        case 2:
          rect.segments[3].point.x += event.delta.x;
          rect.segments[1].point.y += event.delta.y;
          break;
        case 3:
          rect.segments[selectedNode.index - 1].point.x += event.delta.x;
          rect.segments[selectedNode.index - 3].point.y += event.delta.y;
          break;
  };

Поэтому я просто проверяю соседние точки и перемещаю их в соответствии с событием мыши. Он отлично работает для AABB

enter image description here

But as soon as the rectangle is rotated, everything breaks введите описание изображения здесь

Может ли кто-нибудь объяснить или просто связать меня, каков правильный алгоритм изменения размера прямоугольника и сохранения его прямоугольником? Думаю, этот вопрос уже задан, но я не могу найти ничего полезного.

Спасибо :)

1 Ответ

0 голосов
/ 03 августа 2020

Сделайте проекцию вектора перемещения мыши на векторы сторон прямоугольника (они зависят от угла поворота) и примените соответствующие изменения к длинам сторон прямоугольника.

Одна сторона прямоугольника имеет единичный вектор направления (cos(fi), sin(fi)), другая (сосед) сторона - (-sin(fi), cos(fi)) и для сдвига мыши (mx, my) применяется к вершине между этими сторонами:

delta_width = mx * cos(fi) + my * sin(fi)
delta_height = -mx * sin(fi) + my * cos(fi)

Обратите внимание, что знаки зависят от того, какая вершина перемещается

...