J'ai écrit une fonction qui calcule les points d'une courbe b-spline, en dessinant la courbe sur l'écran lorsque les points sont générés en utilisant la fonction setinterval()
intégrée. Le problème est que lorsque ces points sont dessinés à l'écran, il y a simplement une partie ou un petit segment de la courbe visible le long de la courbe interpolée, mais la courbe entière ne persiste pas lorsque la courbe est tracée. En plus de cela, la courbe va traîner l'écran une fois qu'il atteint un certain point. Le code semble être conçu de telle sorte que la fonction se termine (l'intervalle sera effacé) une fois que la valeur de t atteint 1, mais pour une raison quelconque, la fonction continue d'être appelée, ce qui provoque l'animation de la courbe hors écran. Inversement, j'ai une autre fonction qui utilise simplement une boucle for pour dessiner la courbe avec les mêmes points, mais avec cette fonction, une petite courbe est tracée une fois, clairement à l'écran. Voici le code pour les deux fonctions:Problème avec l'animation de rendu b-spline en javascript
//function that draws the spline one time
function bspline(context, points) {
context.beginPath();
for (var t = 0; t < 1; t += 0.1) {
var ax = (-points[0].x + 3 * points[1].x - 3 * points[2].x + points[3].x)/6;
var ay = (-points[0].y + 3 * points[1].y - 3 * points[2].y + points[3].y)/6;
var bx = (-points[0].x - 2 * points[1].x + points[2].x)/2;
var by = (-points[0].y - 2 * points[1].y + points[2].y)/2;
var cx = (-points[0].x + points[2].x)/2;
var cy = (-points[0].y + points[2].y)/2;
var dx = (points[0].x + 4 * points[1].x + points[2].x)/6;
var dy = (points[0].y + 4 * points[1].y + points[2].y)/6;
context.moveTo(
ax*Math.pow(t,3) + bx*Math.pow(t,2) + cx*t + dx,
ay*Math.pow(t,3) + by*Math.pow(t,2) + cy*t + dy
);
context.lineTo(
ax*Math.pow(t+0.1, 3) + bx*Math.pow(t+0.1, 2) + cx*(t+0.1) + dx,
ay*Math.pow(t+0.1,3) + by*Math.pow(t+0.1,2) + cy*(t+0.1) + dy
);
//m.translate(ax * Math.pow(t + 0.1, 3) + bx * Math.pow(t + 0.1, 2) + cx * (t + 0.1) + dx, ay * Math.pow(t + 0.1, 3) + by * Math.pow(t + 0.1, 2) + cy * (t + 0.1) + dy,0);
}
context.stroke();
}
var interval;
//sets the interval for the spline to be animated over
function drawSpline(context, points, newpts) {
interval = setInterval(splineAnim(context, points, newpts), 1600.67);
console.log("interval set");
}
var t = 0;
//determines and draws the points of the spline
function splineAnim(context, points, newpts) {
// Draw curve segment
var ax = (-points[0].x + 3 * points[1].x - 3 * points[2].x + points[3].x)/6;
var ay = (-points[0].y + 3 * points[1].y - 3 * points[2].y + points[3].y)/6;
var bx = (-points[0].x - 2 * points[1].x + points[2].x)/2;
var by = (-points[0].y - 2 * points[1].y + points[2].y)/2;
var cx = (-points[0].x + points[2].x)/2;
var cy = (-points[0].y + points[2].y)/2;
var dx = (points[0].x + 4 * points[1].x + points[2].x)/6;
var dy = (points[0].y + 4 * points[1].y + points[2].y)/6;
context.beginPath();
context.moveTo(
ax * Math.pow(t, 3) + bx * Math.pow(t, 2) + cx * t + dx,
ay * Math.pow(t, 3) + by * Math.pow(t, 2) + cy * t + dy
);
var ax2 = ax * Math.pow(t + 0.1, 3) + bx * Math.pow(t + 0.1, 2) + cx * (t + 0.1) + dx;
var ay2 = ay * Math.pow(t + 0.1, 3) + by * Math.pow(t + 0.1, 2) + cy * (t + 0.1) + dy;
context.lineTo(
ax * Math.pow(t + 0.1, 3) + bx * Math.pow(t + 0.1, 2) + cx * (t + 0.1) + dx,
ay * Math.pow(t + 0.1, 3) + by * Math.pow(t + 0.1, 2) + cy * (t + 0.1) + dy
);
context.stroke();
//m.translate(ax * Math.pow(t + 0.1, 3) + bx * Math.pow(t + 0.1, 2) + cx * (t + 0.1) + dx, ay * Math.pow(t + 0.1, 3) + by * Math.pow(t + 0.1, 2) + cy * (t + 0.1) + dy, 0);
//console.log("ax2: " + ax2 + ", ay2: " + ay2);
var arr = [ax2, ay2];
newpts.push(arr);
t += 0.02;
//Reached end of curve
if (t > 1) clearInterval(interval);
}
Merci pour la réponse! Juste quelques questions cependant. Premièrement, quel est le but de e à l'intérieur des instructions for et if et comment obtenez-vous les valeurs x et y pour p? Il semble seulement qu'il y ait une composante de p étant définie. De même, comment devrais-je déterminer quels points de contrôle devraient être utilisés pour tenir sur l'écran? merci – loremIpsum1771
@ loremIpsum1771 'e' est juste la condition de fin si' t' est hors de portée alors 't' est fixé sur' 1.0' et 'e' est réinitialisé pour que la boucle s'arrête après avoir rendu le dernier point (' t = 1.0 ') vous pourriez utiliser' bool' au lieu de 'int' aussi. L'algèbre vectorielle est simple ... '3.0 * p0' est la même chose que' (3.0 * p0.x, 3.0 * p0.y) 'vous faites juste le fing par axe ... donc' p0, p1, p2, p3' est le même que vos 'points []' et 'a0, a1, a2, a3' est le même que votre' (ax, ay), (bx, par), ... ' – Spektre