Tengo una matriz de grados, [10, 90, 200, 280, 355] para un círculo.Dado un grado x, encuentre el grado más cercano en un conjunto de grados
Me otorgaron un título, digamos 1. ¿Cómo puedo determinar que 1 está más cerca de 355 grados?
Tengo una matriz de grados, [10, 90, 200, 280, 355] para un círculo.Dado un grado x, encuentre el grado más cercano en un conjunto de grados
Me otorgaron un título, digamos 1. ¿Cómo puedo determinar que 1 está más cerca de 355 grados?
Tiene un valor que contendrá el grado de cierre encontrado found_degree
y uno para la diferencia real degree_difference
.
A continuación, itere sobre toda la matriz y calcule dos valores: abs(degree_at_position - target_degree)
y abs(degree_at_position - 360 - target_degree)
. Si uno de esos valores es menor que degree_difference
, tiene un grado más cercano - guárdelo en found_degree
y actualice degree_difference
en consecuencia.
Eso es todo.
Usted tal vez debe inicializar found_degree
con -1 y degree_difference
con 360, sólo para asegurarse de que puede interpretar correctamente el resultado en caso de una matriz dada vacío, así - o simplemente manejar el caso de una matriz de entrada vacía por separado.
¿Es esto una tarea, por cierto?
Reste los dos números. Si la diferencia es mayor por encima de 180 [o por debajo de -180], reste [o agregue] 360. Ahora puede simplemente comparar los valores absolutos de la diferencia.
+1 pero necesita obtener el valor absoluto de la diferencia y compare con 180 (por ejemplo, podría ser -200), luego reste de 360. – RobG
@RobG, buen punto. He editado la respuesta en consecuencia. –
Aquí es una fórmula real:
degreediff = min(abs(x-y),360-abs(x-y))
El método de fuerza bruta sería algo como esto:
var closestElement;
var closestDivergence = 360;
var toCompare = 355;
var choices = [1, 90, 200, 280, 355];
for(i=0;i<choices.length;i++){
var currentDivergence=choices[i] - toCompare;
if (currentDivergence<0) {
currentDivergence+=360;
}
if (currentDivergence < closestDivergence){
closestDivergence = currentDivergence;
closestElement = i;
}
}
if (closestElement != NaN){
alert('Closest value is '+choices[closestElement]);
}
No funcionará para valores cercanos a cero, p. 1 está más cerca de 355 que 10 (por OP). – RobG
Muy bien, he modificado mi respuesta. –
Aquí hay un pequeño polvo rápido
function closest(deg,ar) {
return ar.sort(function(a,b){var c = deg; return Math.min(360 - (a-c),Math.abs(a-c)) - Math.min(360 - (b-c),Math.abs(b-c))})
}
var myArray = [355, 280, 200, 181, 90, 30];
alert(closest(180,myArray));
Clasifica y devuelve el arreglo de acuerdo con cuál es el más cercano al grado proporcionado. El índice 0 es el más cercano. Envuelve haciendo que 355 esté más cerca de 0 que 10.
Primero verifique la matriz (verifique qué elemento está más cerca) usando el grado dado (1 en su ejemplo), luego agregue 360 y verifique con ese grado (361). Comparar qué resultado es mejor:
x el grado dado, y el primer resultado, z el segundo resultado
if (abs(x-y) < 360+x-z)
choose y;
else
choose z;
Si se ordena la matriz se puede comprobar con una especie binario que le da O (log n) tiempo en el peor de los casos. De lo contrario, tiene que navegar por toda la matriz dos veces.
Esta fórmula solo funcionará con círculos. Es pseudo código, por supuesto.
degree diff = min(abs(x-y),360-abs(x-y))
utilizando los comentarios en esta página me las arreglé para llegar a este código:
function closest(deg, degs) {
deg = (deg/360 > 1 ? deg - (Math.floor(deg/360)*360) : deg);
var difference = 360;
var closest = -1;
for(i=0;i<degs.length;i++) {
var x = degs[i];
var diff = Math.min(Math.abs(x-deg),360-Math.abs(x-deg))
if(diff <= difference) {
closest = i;
difference = diff;
}
};
return closest;
}
más cercano (1000, [10, 90, 200, 280, 355]) ;
Esto es más compacto y eficiente:
function difference(a, b) {
var d = Math.abs(a - b);
return d > 180 ? 360 - d : d;
};
function closest(a, bs) {
var ds = bs.map(function(b) { return difference(a, b); });
return bs[ds.indexOf(Math.min.apply(null, ds))];
};
> difference(1, 355)
6
> closest(1, [10, 90, 200, 280, 355])
355
+1, que tenían la misma tarea recientemente y mi solución es libre de errores, así que estoy interesado en ver si hay algunas otras implementaciones antes intente y corrija :-) –