Нахождение угла и расстояния между отрезками


Я собираю короткое демо на две вещи:

  1. Найти угол между двумя линейными сегментами и направление (вправо или влево), как вы путешествуете против часовой стрелки вокруг какой-то фигуры
  2. Используя новый синтаксис в ECMAScript (например .карта, классы, const, то пусть (не ВАР) обратные кавычки в консоли лесозаготовки)

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

И отзывы о синтаксисе/методов. Пожалуйста, имейте в виду, что, так как это демо, код подробно в выходные. (Я намеренно использую консоль.предупреждают на каждом углу просто, чтобы сделать их легче обнаружить, поэтому никаких комментариев по этому нужны :-)).

Для этого набора точек, начиная с верхнего левого угла и работая против часовой стрелки, ожидается выход 45°, 45°, -90°, 45°, 45°, -90°.

graph showing points

Есть два класса, постоянный перевести Градусы/радианы и небольшого набора данных:

class Vector {

    constructor(x, y, z) {
        this.x = x || 0;
        this.y = y || 0;
        this.z = z || 0;
    }
}

class Point {
    constructor(x, y) {
        this.x = x || 0;
        this.y = y || 0;
    }
}

const degRad = 180 / Math.PI;

const testCoordSet = [
    [-5, 15],
    [- 5, 0],
    [0, 5],
    [5, 0],
    [5, 15],
    [0, 10]
];

Затем:

// Generate our test set of points - using map because we need to return a new collection
const testPts = testCoordSet.map(coord => new Point(coord[0], coord[1]));
console.log(testPts);

// Using forEach because we're not returning anything. In practice, further
//  operations could benefit from map because we can chain
testPts.forEach((pt, index, array) => {

    console.log(`\r\n${index}`);

    let pointA, pointC;

    const pointB = pt;

    // Determine which points will make up left, center and right points
    if (index === 0) { // If at beginning, left is the last point in the array

        pointA = array[array.length - 1];
        pointC = array[index + 1];

    } else if (index === array.length - 1) { // If at end, right is the first point in the array

        pointA = array[index - 1];
        pointC = array[0];

    } else {

        pointA = array[index - 1];
        pointC = array[index + 1];
    }

    const vectorAB = new Vector(pointA.x - pointB.x,
        pointA.y - pointB.y);

    const vectorCB = new Vector(pointC.x - pointB.x,
        pointC.y - pointB.y);

    console.log("vectorAB:", vectorAB);
    console.log("vectorCB:", vectorCB);

    // Stay in radians until the final result is calculated
    const absAngleABRad = Math.atan2(vectorAB.y, vectorAB.x);
    console.log(`absAngleABRad: ${absAngleABRad}`);

    const absAngleCBRad = Math.atan2(vectorCB.y, vectorCB.x);
    console.log(`absAngleCBRad: ${absAngleCBRad}`);

    const angularDiffRad = absAngleABRad - absAngleCBRad;
    console.log(`angularDiffRad: ${angularDiffRad}`);

    const angleDeg = angularDiffRad * degRad;
    console.warn(`angleDeg: ${angleDeg}`);
});

Для сравнения, я брошен в традиционной для следующего цикла:

for (let i = 0; i < testPts.length; i++) {

    console.log(`\r\n${i}`);

    let pointA, pointC;

    const pointB = testPts[i];

    // Determine which points will make up left, center and right points
    if (i === 0) { // If at beginning, left is the last point in the array

        pointA = testPts[testPts.length - 1];
        pointC = testPts[i + 1];

    } else if (i === testPts.length - 1) { // If at end, right is the first point in the array

        pointA = testPts[i - 1];
        pointC = testPts[0];

    } else {

        pointA = testPts[i - 1];
        pointC = testPts[i + 1];
    }

    const vectorAB = new Vector(pointA.x - pointB.x,
        pointA.y - pointB.y);

    const vectorCB = new Vector(pointC.x - pointB.x,
        pointC.y - pointB.y);

    console.log("vectorAB:", vectorAB);
    console.log("vectorCB:", vectorCB);

    // Stay in radians until the final result is calculated
    const absAngleABRad = Math.atan2(vectorAB.y, vectorAB.x);
    console.log(`absAngleABRad: ${absAngleABRad}`);

    const absAngleCBRad = Math.atan2(vectorCB.y, vectorCB.x);
    console.log(`absAngleCBRad: ${absAngleCBRad}`);

    const angularDiffRad = absAngleABRad - absAngleCBRad;
    console.log(`angularDiffRad: ${angularDiffRad}`);

    const angleDeg = angularDiffRad * degRad;
    console.warn(`angleDeg: ${angleDeg}`);
}

Полный, обновленный код может быть найден здесь: https://gist.github.com/stonetip/e79254e001bda862119e97d7646e4c66



Комментарии
1 ответ

Вектор

В z не нужен. Вы работаете исключительно в 2D, очки в 2D, и это никогда не устанавливается или на которые ссылается. Избавиться от него.

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

class Vector {
constructor(a, b) {
if(a instanceof Point && b instanceof Point) {
this.x = b.x - a.x;
this.y = b.y - a.y;
}
else {
this.x = a || 0;
this.y = b || 0;
}
}
}

Я бы переименовал аргументы, чтобы сделать его легче следовать. Затем вы можете использовать его, как это

const vectorAB = new Vector(pointA, pointB);
const vectorCB = new Vector(pointC, pointB);

Преобразование угла

Я хотел бы использовать функцию вместо этого. Что вы должны делать с этим постоянное значение? Умножьте это? Добавить это? Разделить с ним? С функцией вы знаете, что у вас есть. Вы поставите значение, вы получите отдачу. Имя также может быть немного более описательное.

function degToRad(deg) {
return deg * 180 / Math.PI;
}

Остальные параметры

Если вы хотите больше ЕС6 вы можете использовать спред оператора при создании точек.

const testPts = testCoordSet.map(coord => new Point(...coord));

Сухой

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

const pointA = array[index === 0 ? array.length-1 : index-1];
const pointB = pt;
const pointC = array[index === array.length-1 ? 0 : index+1];

2
ответ дан 14 февраля 2018 в 12:02 Источник Поделиться