Dzień dobry,
Napisałem nieporadnie taką oto funkcję. Funkcja zwraca numer progu i numer struny na gitarze, po kliknięciu w odpowiednie miejsce na podstrunnicy. Jednym słowem zamienia współrzędne myszki po kliknięciu, na współrzędne na gryfie gitary (nr struny i progu). Niestety ma ona 2 wady:
- źle wygląda
- nie działa do końca tak, jak po testowaniu doszedłem do wniosku.
Mianowicie teraz, funkcja wybiera próg, względem którego najbliżej nastąpiło kliknięcie. To jednak nie jest dla gitarzysty intuicyjne, bo, jak każdy kto gra na gitarze wie, wystarczy docisnąć strunę przed danym progiem i już uzyska się dany dźwięk.
Podsumowując, jak można napisać (wskazówki ;) ) algorytm, który będzie zwracał próg n
, jeżeli kliknięcie było 10px
lub więcej za n-1
progiem, jednak nie więcej niż 10px
za progiem n
.
function getClickedNoteFromC(x, y) {
var startX = 0; // posta struna
var startY = 0; // struna 6
var endX = 13; // za 12 progiem (max 12 progów)
var endY = 6; // przed struną 1
var diff = 10000; // początkowa odległość między kliknięciem a współrzędną progu
var times = 0; // jakby algorytm się zapętlił, to pętla wykona się max 5x
var result = []; // wynik
while (true) {
var actXPlus = parseInt((endX + startX) / 2); // dzielimy przedział na 2
var newDiff = x - xy[0][actXPlus]; // odległość między współrzędną x (argument), a współrzędną progu
if (diff > Math.abs(newDiff)) { // jeśli nowa odległość jest mniejsza, podmieniamy ją z zapisaną i zmieniamy wynik
diff = Math.abs(newDiff);
result[0] = actXPlus;
}
if (newDiff < 0) // zawężamy przedział
endX = actXPlus;
else if (newDiff > 0) // zawężamy przediał
startX = actXPlus;
else { // bingo, ale to się rzadko zdaża
result[0] = actXPlus;
break;
}
if (startX == endX) // kończymy pętlę
break;
if ((startX + 1) == endX) // odliczamy
times += 1;
if (times > 5) // jak odliczyliśmy ponad 5, kończymy
break;
console.log(1, actXPlus, newDiff, diff, startX, endX, times);
}
diff = 10000;
times = 0;
while (true) { // to samo dla y, tyle, że y są posortowane malejąco w tablicy
var actYPlus = parseInt((endY + startY) / 2);
var newDiff = xy[1][actYPlus] - y; // tu różnica, (malejące sortowanie)
if (diff > Math.abs(newDiff)) {
diff = Math.abs(newDiff);
result[1] = actYPlus;
}
if (newDiff < 0)
endY = actYPlus;
else if (newDiff > 0)
startY = actYPlus;
else {
result[1] = actYPlus;
break;
}
if (startY == endY)
break;
if ((startY + 1) == endY)
times += 1;
if (times > 5)
break;
console.log(2, actYPlus, newDiff, diff, startY, endY, times);
}
return result;
}
wiem, że mógłbym się nie bawić i napisać na pałę sprawdzanie wszystkiego po kolei, w końcu tablica jest tylko [6][13]
, ale chcę się nauczyć optymalnego podejścia.
Dziękuję
M.