Coordinate circolari su array in Javascript
-
03-07-2019 - |
Domanda
Qual è il modo migliore per aggiungere le coordinate di un cerchio a un array in JavaScript? Finora sono stato in grado di fare solo un semicerchio, ma ho bisogno di una formula che ritorni l'intero cerchio su due matrici diverse: xValues ??
e yValues ??
. (Sto cercando di ottenere le coordinate in modo da poter animare un oggetto lungo un percorso.)
Ecco quello che ho finora:
circle: function(radius, steps, centerX, centerY){
var xValues = [centerX];
var yValues = [centerY];
for (var i = 1; i < steps; i++) {
xValues[i] = (centerX + radius * Math.cos(Math.PI * i / steps-Math.PI/2));
yValues[i] = (centerY + radius * Math.sin(Math.PI * i / steps-Math.PI/2));
}
}
Soluzione
Il tuo loop dovrebbe essere impostato in questo modo invece:
for (var i = 0; i < steps; i++) {
xValues[i] = (centerX + radius * Math.cos(2 * Math.PI * i / steps));
yValues[i] = (centerY + radius * Math.sin(2 * Math.PI * i / steps));
}
- Inizia il ciclo da 0
- Attraversa l'intera gamma 2 * PI, non solo PI.
- Non dovresti avere
var xValues ??= [centerX]; var yValues ??= [centerY];
- il centro del cerchio non fa parte di esso.
Altri suggerimenti
L'algoritmo di Bresenham è molto più veloce. Ne senti parlare in relazione al disegno di linee rette, ma esiste una forma dell'algoritmo per i cerchi.
Sia che lo usi o continui con i calcoli del trig (che sono incredibilmente veloci in questi giorni), devi solo disegnare 1/8 del cerchio. Scambiando x, y puoi ottenere un altro 1/8, quindi il negativo di x, di y e di entrambi - scambiati e non scambiati - ti dà punti per tutto il resto del cerchio. Una velocità di 8x!
Modifica:
Math.PI * i / steps
a:
2*Math.PI * i / steps
Un cerchio completo è 2pi radianti, e tu stai solo per pi radianti.
Se hai già mezzo cerchio, rispondi ai punti per ottenere l'altra metà
assicurati di farlo nell'ordine giusto.
più specificamente, per l'altra metà sostituisci semplicemente " + sin (...)
" con un " - sin (...)
"
Devi usare una funzione parziale per inserire i radianti in cos e sin; quindi prendi i valori che ottieni per un quarto o metà del cerchio e riflettili sull'asse dei punti centrali per ottenere il tuo cerchio completo.
Detto questo peccato e cos di JavaScript non sono così schizzinosi, quindi devi aver dimezzato il tuo radiante o qualcosa del genere; Lo scriverei come:
function circle(radius, steps, centerX, centerY){
var xValues = [centerX];
var yValues = [centerY];
var table="<tr><th>Step</th><th>X</th><th>Y</th></tr>";
var ctx = document.getElementById("canvas").getContext("2d");
ctx.fillStyle = "red"
ctx.beginPath();
for (var i = 0; i <= steps; i++) {
var radian = (2*Math.PI) * (i/steps);
xValues[i+1] = centerX + radius * Math.cos(radian);
yValues[i+1] = centerY + radius * Math.sin(radian);
if(0==i){ctx.moveTo(xValues[i+1],yValues[i+1]);}else{ctx.lineTo(xValues[i+1],yValues[i+1]);}
table += "<tr><td>" + i + "</td><td>" + xValues[i+1] + "</td><td>" + yValues[i+1] + "</td></tr>";
}
ctx.fill();
return table;
}
document.body.innerHTML="<canvas id=\"canvas\" width=\"300\" height=\"300\"></canvas><table id=\"table\"/>";
document.getElementById("table").innerHTML+=circle(150,15,150,150);
Supponevo che per qualsiasi motivo tu volessi che xValues ??[0] e yValues ??[0] fossero centerX e centerY. Non riesco a capire perché lo vorresti, dato che i loro valori sono già passati alla funzione.
Sono stato in grado di risolverlo da solo moltiplicando il numero di passaggi per 2:
circle: function(radius, steps, centerX, centerY){
var xValues = [centerX];
var yValues = [centerY];
for (var i = 1; i < steps; i++) {
xValues[i] = (centerX + radius * Math.cos(Math.PI * i / steps*2-Math.PI/2));
yValues[i] = (centerY + radius * Math.sin(Math.PI * i / steps*2-Math.PI/2));
}
}