Как можно выполнить сужение или растяжение отрезка, определенного двумя точками, с помощью JavaScript на канвасе?

Как можно адаптировать JavaScript функцию для регулирования смещения двух точек на Canvas так, чтобы она корректно работала даже если отрезок между ними не параллелен верхней горизонтальной границе? В настоящее время функция меняет значение X для каждой точки в зависимости от их расположения: при уменьшающемся расстоянии левая точка смещается вправо, а правая — влево, и наоборот. Однако это работает только когда обе точки находятся на одной горизонтали. Как мне рассчитать пропорции смещения для координат X и Y в зависимости от угла между отрезком и горизонтом? Возможно, есть другие подходы к решению этой задачи? Я рассматриваю использование угла и пропорциональное распределение значения смещения между координатами X и Y.
  • 23 октября 2024 г. 10:33
Ответы на вопрос 2
Для сужения или растяжения отрезка, определенного двумя точками, на Canvas с учетом угла между отрезком и горизонтальной осью, вам нужно учесть следующие моменты:

1. **Определение угла** между отрезком и горизонтом. Это можно сделать с помощью функции `Math.atan2`.

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

Пример решения задачи в JavaScript может выглядеть следующим образом:

```javascript
function stretchSegment(pointA, pointB, scale) {
    // Вычисляем вектор от точки A к точке B
    const dx = pointB.x - pointA.x;
    const dy = pointB.y - pointA.y;

    // Длина отрезка
    const length = Math.sqrt(dx * dx + dy * dy);

    // Если длина отрезка нулевая, ничего не делаем
    if (length === 0) return;

    // Вычисляем новый вектор
    const newLength = length * scale;
    const unitX = dx / length; // Нормализованный вектор по X
    const unitY = dy / length; // Нормализованный вектор по Y

    // Определяем новые координаты для точек A и B
    const newDx = unitX * newLength;
    const newDy = unitY * newLength;

    // Для растяжения отрезка с вершиной A
    pointB.x = pointA.x + newDx;
    pointB.y = pointA.y + newDy;
}

// Пример использования
const pointA = { x: 100, y: 100 };
const pointB = { x: 200, y: 150 };

// Состояние - растянуть отрезок в 1.5 раза
stretchSegment(pointA, pointB, 1.5);

// Ваша функция для рисования на Canvas
function drawLine(ctx, pointA, pointB) {
    ctx.beginPath();
    ctx.moveTo(pointA.x, pointA.y);
    ctx.lineTo(pointB.x, pointB.y);
    ctx.stroke();
}

// Пример рисования на Canvas
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, canvas.width, canvas.height);
drawLine(ctx, pointA, pointB);
```

### Пояснение к коду:
- **stretchSegment**: Эта функция принимает две точки и коэффициент масштабирования (scale). Она вычисляет разницу между координатами двух точек, нормализует их и масштабирует вектор.
- **drawLine**: Эта функция рисует линию между двумя точками на канвасе.

Если вы хотите, чтобы отрезок сужался, вам просто нужно передать значение scale меньше 1 в функцию `stretchSegment`.

### Примечания:
- Убедитесь, что вы корректно обрабатываете ситуации, когда точки совпадают, так как в этом случае не имеет смысла проводить сужение или растяжение.
- Используйте вызовы `ctx.clearRect()` и `ctx.stroke()` для обновления канваса при каждом изменении отрезка.
Находите среднюю точку и начальное смещение 
Xc = (X1 + X2) / 2
Yc = (Y1 + Y2) / 2
dX = Xc - X1
dY = Yc - Y1
Затем просто домножаете смещение на коэффициент растяжения и прибавляете/вычитаете от центральной точки
X1' = Xc - dX * k
Y1' = Yc - dY * k
X2' = Xc + dX * k
Y2' = Yc + dY * k
Коэффициент k = 1 соответствует начальному положению точек
Похожие вопросы