2013-02-21 4 views
4

В принципе, я хочу сгенерировать угол (0 - 360 градусов), который не находится в указанном диапазоне других углов. Я уже сделал эту функцию, чтобы проверить два угла:Мне нужна помощь в оптимизации функции

function check(angle1, angle2, range) { 
    var diff = angle1 - angle2; 

    if(Math.abs(diff % 360) <= range || (360-Math.abs(diff % 360)) <= range) { 
     return true; 
    } else { 
     return false; 
    } 
} 

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

Я думаю, что это будет работать:

var others = [array of objects]; 

... 

for(var i = 0; i < 360; i++) { 
    var pass = true; 
    for(var n = 0; n < others.length; n++) { 
     if(check(i, others[n].angle, 5)) { 
      pass = false; 
      break; 
     } 
    } 
    if(pass) return i; 
} 

return false; 

Однако это является много из цикла, и я предпочел бы случайный угол, а не приращение. Есть ли более быстрый и лучший способ сделать это? Благодарю.

Редактировать: решил сделать что-то подобное, получил идею от ответа @ TheBronx.

var angles = []; 

var range = 5; 

function alterAngle(a, n) { 
    var angle = a + n; 
    if(angle < 0) angle = 360 + angle; 
    if(angle > 360) angle = angle - 360; 
    return angle; 
} 



// in the function 

var angle = Math.floor(Math.random() * 360); 

if(angles.indexOf(angle) == -1) { 
    for(var i = -range; i <= range; i++) 
    angles.push(alterAngle(angle, i)); 
} 
+1

Возможно [Просмотр Кода. se] может быть более подходящим местом для этого вопроса? –

+0

Любопытно, что диапазон небольшой стоимости? как 5º? Сколько углов вы можете иметь в худшем случае? – TheBronx

+0

Ваши углы целых чисел? –

ответ

3

Идея. Представьте, что ваши углы - это карты в колоде. Когда вы создаете случайный угол, вы удаляете этот угол из колоды, а также углы внутри вашего диапазона. Когда вам нужно создать новый угол, вместо генерации случайного значения между 0..360 вам просто нужно «выбрать карту». Это всегда будет работать, если у вас не будет больше доступных «карт».

Проблема в том, что у вас много карт? У вас есть достаточно времени для инициализации «карт» при запуске?

Просто идея ... Не знаю, хорошо это или нет, но кажется многообещающим.

+0

Это отличная идея! Я просто проверю это, я опубликую его, если он сработает. Благодарю. – Suffick

+0

Управление диапазонами оказывается довольно сложным. Я думал, что могу просто соединить кусок из массива, но потом вы в конечном итоге сплайсируете прыжки, где вы ранее сплайсировали. Это может сработать, если я это выясню. – Suffick

+0

yep, удаление проблема. Как только вы выберете угол, вы должны проверить и удалить до углов 'range * 2'. Но проверка занимает не очень много времени, и вы можете сразу удалить все углы (когда вы знаете, с чего начать и закончить сращивание) ... это может сработать. – TheBronx

1

Это один

if(Math.abs(diff % 360) <= range || (360-Math.abs(diff % 360)) <= range) { 
    return true; 
    } else { 
    return false; 
} 

вы могли бы сделать таким образом, это приведет к снижению операции

return Math.abs(diff % 360) <= range || (360-Math.abs(diff % 360)) <= range; 
+1

, и если вы храните 'Math.abs (diff% 360)' в var, вам не нужно его вычислять дважды.Скорее всего, это не то решение, которое он хочет, но поскольку он использует функцию проверки функций много раз, оптимизация имеет смысл. – TheBronx

+0

Не передумал, спасибо. – Suffick

0

Основываясь на предыдущем мой вопрос: Fischer Yates shuffle in coffee-script

var counter, i, permutations, shuffle, x, _i; 

// Fischer Yates shuffle algorithm 
shuffle = function(arr, required) { 
    var i, index, randInt, _i, _ref, _ref1, _ref2; 
    if (required == null) { 
    required = arr.length; 
    } 
    randInt = function(n) { 
    return Math.floor(n * Math.random()); 
    }; 
    if (required > arr.length) { 
    required = arr.length; 
    } 
    if (required <= 1) { 
    return arr[randInt(arr.length)]; 
    } 
    for (i = _i = _ref = arr.length - 1, _ref1 = arr.length - required; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = _ref <= _ref1 ? ++_i : --_i) { 
    index = randInt(i + 1); 
    _ref2 = [arr[i], arr[index]], arr[index] = _ref2[0], arr[i] = _ref2[1]; 
    } 
    return arr.slice(arr.length - required); 
}; 


// generate array of all possible angles 
var angles = [] 
for(i=0;i<360;i++){ angles.push(i) } 

// shuffle as many as you need (20 in this example) 
var shuffled = shuffle(angles,20) 

// check the result 
console.log(shuffled) 

// simply deal off values from this shuffled array as needed