Рефакторинг алгоритма облака слов

В рамках алгоритма рендеринга облака слов (вдохновленного этим вопросом) я создал функцию Javascript / Processing.js, которая перемещает прямоугольник слова по постоянно увеличивающейся спирали, пока больше не будет столкновения с ранее помещенными словами. Работает, но качество кода меня не устраивает.

Итак, мой вопрос: как я могу реструктурировать этот код, чтобы он был:

  • читаемый + понятный
  • быстро (без бесполезных вычислений)
  • элегантный (с использованием нескольких строк кода)

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

Rectangle moveWordRect(wordRect){
    // Perform a spiral movement from center
    // using the archimedean spiral and polar coordinates
    // equation: r = a + b * phi

    // Calculate mid of rect
    var midX = wordRect.x1 + (wordRect.x2 - wordRect.x1)/2.0;
    var midY = wordRect.y1 + (wordRect.y2 - wordRect.y1)/2.0;

    // Calculate radius from center 
    var r = sqrt(sq(midX - width/2.0) + sq(midY - height/2.0));

    // Set a fixed spiral width: Distance between successive turns
    var b = 15; 

    // Determine current angle on spiral
    var phi = r / b * 2.0 * PI;

    // Increase that angle and calculate new radius
    phi += 0.2;
    r = (b * phi) / (2.0 * PI);

    // Convert back to cartesian coordinates
    var newMidX = r * cos(phi);
    var newMidY = r * sin(phi);

    // Shift back respective to mid
    newMidX += width/2;
    newMidY += height/2;

    // Calculate movement 
    var moveX = newMidX - midX;
    var moveY = newMidY - midY;

    // Apply movement
    wordRect.x1 += moveX;
    wordRect.x2 += moveX;
    wordRect.y1 += moveY;
    wordRect.y2 += moveY;

    return wordRect;
}

person kadrian    schedule 24.08.2013    source источник
comment
Может быть, codereview.stackexchange.com будет более подходящим сайтом для ответа на этот вопрос?   -  person Barmar    schedule 25.08.2013


Ответы (2)


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

  • Вычислить середину прямоугольника
  • Рассчитать радиус
  • Определить текущий угол
  • Преобразовать полярные координаты в декартовы координаты

Вы также можете рассмотреть возможность использования более описательных имен переменных. 'b' и 'r' требуют поиска кода, чтобы увидеть, для чего они нужны, а 'spiralWidth' и 'radius' - нет.

person Stephen Hewlett    schedule 24.08.2013
comment
Итак, общая идея такова: меньше комментировать и вместо этого использовать функции? - person kadrian; 25.08.2013
comment
Это скорее разделение чего-либо на отдельные функции, которые могут быть, что, вероятно, приведет к меньшему количеству комментариев, но я не думаю, что это должно быть самоцелью. Имена функций определяют намерение, а не реализацию, что мгновенно делает код более читабельным. - person Stephen Hewlett; 25.08.2013

В дополнение к ответу Стивена упростите эти две строки:

var midX = wordRect.x1 + (wordRect.x2 - wordRect.x1)/2.0;
var midY = wordRect.y1 + (wordRect.y2 - wordRect.y1)/2.0;

Лучшие утверждения:

var midX = (wordRect.x1 + wordRect.x2)/2.0;
var midY = (wordRect.y1 + wordRect.y2)/2.0;
person MNZ    schedule 25.08.2013