Функция угла отражения


Я разработал функцию для расчета угла выхода снаряда после того, как он столкнется с границы/края внутри прямоугольного пространства, исходя из угла входа и оси его столкновения с.

Учитывая эти два фактора, фактическая граница подразумевается, так как снаряд движется на угол 315° (где 0°/360° сидеть в 3 часа) и сталкиваясь с горизонтальной границы (ось X) должна быть столкновения с верхней границей.

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

function reflectAngle(angle, axis) {

    if (angle % 90 === 0)
        return (angle + 180) % 360;

    let reflected;
    let segment = (angle % 90) * 2;

    if (axis === 'X')
        reflected = angle + (180 - segment);

    else if (axis === 'Y')
        reflected = angle - segment;

    if (angle < 90)
        reflected += 180;

    return reflected % 360;
}

Эта функция может быть упрощена и улучшена для читабельности?



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

Комментарий

Немного неоднозначная, и слишком сложным. Вы должны ознакомить себя с радианы и забыть о степени

Стиль

Блок-меньше блоков

Блок-это часть кода, разделенных {...} многие с подобным синтаксисом языков позволит вам пропустить блок разделителей для одной линии блоков через условные операторы.

Это может быть основным источником жизни разочарования, и есть не программист жив, что не знал коварный характер ошибок, которые могут возникнуть, когда вы вносите изменения в код и забыл {...}

// worst
if (foo === bar)
foo = poo

// bad
if (foo === bar)
foo = poo;

// better but be consistent never mix this with above
if (foo === bar) foo = poo;

// best
if (foo === bar) { foo = poo } // note that ; and } denote the end of
// an expression, you don't need to use both

// or
if (foo === bar) {
foo = poo;
}

Константы

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

const A90  = 90;
const A180 = 180;
const A360 = 360;

Затем если вы хотите изменить в радианы

const A90  = Math.PI / 2;
const A180 = Math.PI;
const A360 = Math.PI * 2;

или часы углами

const A90  = 3;
const A180 = 6;
const A360 = 12;

Нет необходимости искать каждый номер в базовый код.


Логика


  1. Аргумент оси неоднозначно. Оси? это ось отражения или оси рефлекс. Также можно использовать строку и для человека "x", "X" и "y", "Y" имеют тот же смысл, но код их видит по-другому, это никогда не хорошая вещь. Он будет платить проверить оба (верхний и нижний) или конвертировать в нижний регистр, или лучше использовать определенные константы,

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

  3. Код является слишком сложным для чего-то настолько простого. Проблема является одной из отрицая скаляр, связанные с направлением отражения. И. Е. Вектор имеет две скаляры x,y если вы размышляете по Х вы отрицаете xесли вы рефлекторной вдоль y вы отрицаете y.

    Возиться с цикловой угол не нужен. У меня есть общее правило, что если я когда-нибудь найти себя необходимости нормализовать циклические значение Е. Г. (angle
    % 360)
    я делаю это неправильно и есть лучший способ.



Рерайт

Это как я бы написал функцию. Я бы никогда не использовала градусов, то есть только когда-либо нуждался только для просмотра. Что делает эту функцию гораздо проще.

// defined axis names
const AXIS = {x : 0, y : 1}

// function computes the reflected angle
// rad Incoming angle in radians
// dir direction of reflection. Any of AXIS, defaults to AXIS.y
function reflectAngle(rad, dir) {
return dir === AXIS.x ? Math.acos(-Math.cos(rad)) : Math.asin(-Math.sin(rad));
}

// usage
var reflected = reflectAngle(1, AXIS.x);

И версия для Радиан не любите цветы

// Use the constants to convert degree to radians and back
const deg2Rad = Math.PI / 180;
const rad2Deg = 1 / deg2Rad;

function reflectAngleDegrees(deg, dir) {
const rad = deg * deg2Rad;
return (dir === AXIS.x ?
Math.acos(-Math.cos(rad)) :
Math.asin(-Math.sin(rad))
) * rad2Deg;
}

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