2
votes

obtenir un point sur une courbe de Bézier sans deviner ni force brute

À l'origine, je voulais utiliser quatre points (car une courbe de Bézier est définie avec 4 points), mais cela me force à forcer brutalement la position, j'ai donc essayé une approche différente avec laquelle j'ai maintenant besoin d'aide:

J'ai un point de départ P0, un point final P1 et des pentes m0 et m1 qui sont censées me donner la pente de début / fin pour calculer une courbe de Bézier entre elles.
La courbe est censée être sous la forme d'une fonction (3ème degré), car j'ai besoin d'obtenir la hauteur y d'un point x donné.

En utilisant le HTML5Canvas , je peux dessiner une courbe de Bézier sans problème et en utilisant cette fonction

 entrez la description de l'image ici

qui me permet de calculer n'importe quel point donné en fonction d'un pourcentage de la façon dont je peux obtenir le point central de la courbe. Mais je n'en ai pas besoin en fonction de t mais plutôt du y dépendant de x, donc pas à mi-chemin de la courbe mais à mi-chemin de la distance x entre P0 et P1.

Image à visualiser:
entrez la description de l'image ici
À gauche, ce que je peux calculer, à droite, ce dont j'ai besoin.

J'ai essayé de calculer la fonction cubique étant donné les deux points P0, P1 ainsi que les pentes m0, m1, ce qui donne quatre équations que je n'arrive pas à résoudre avec seulement des entrées variables. J'ai également essayé d'utiliser la fonction ci-dessus pour calculer le t en utilisant la valeur x (qui est connue), mais pas de dés non plus.

Je dois éviter d'utiliser des approximations ou des boucles coûteuses pour ces calculs car ils sont effectués plusieurs fois par seconde pour de nombreux objets, donc cette réponse n'est pas faisable pour moi.

Toute aide est appréciée.


0 commentaires

3 Réponses :


1
votes

J'ai rencontré le même problème dans un projet sur lequel je travaille. Je ne connais pas de formule pour obtenir la coordonnée y à partir du x , et je suppose que vous aurez des problèmes avec cet itinéraire car une courbe de Bézier peut avoir jusqu'à 3 points qui ont tous la même valeur x.

Je recommanderais d'utiliser la bibliothèque BezierEasing, qui a été conçue pour ce cas d'utilisation et utilise diverses techniques d'amélioration des performances pour effectuer des recherches aussi rapidement que possible: https://github.com/gre/bezier-easing


0 commentaires

1
votes

Pour résoudre ce problème, vous devez réécrire l'équation de Bézier sous forme de polynôme de puissance

a*t^3 + b*t^2 + c*t + d = 0

et résoudre équation cubique pour t inconnu

X(t) = t^3 * (P3.X-3*P2.X+3*P1.X-P0.X) + 
       t^2 * (3*P0.X + 6*P1.X+3*P2.X) + 
       t * (3*P1.X - 3P2.X) +
       P0.X 

if X(t) = P0.X*(1-ratio) + P3.X*ratio 
then
let d = ratio * (P0.X - P3.X)

Code JS ici

Ensuite, appliquez le paramètre t calculé (il peut y avoir jusqu'à trois solutions) au composant Y et obtenir les coordonnées des points. Notez que les formules sont proches (pas de boucles) et devraient fonctionner assez vite


0 commentaires

0
votes

Merci à tous ceux qui ont répondu auparavant, ce sont généralement d'excellentes solutions.

Dans mon cas, je peux être sûr à 100% de pouvoir convertir la courbe en une fonction cubique, qui sert d'approximation de la courbe de Bézier en utilisant le résultat de ce calcul .

Étant donné que je contrôle mes points dans mon cas, Je peux forcer le P0 à être sur x = 0, ce qui simplifie les calculs du système linéaire et me permet donc de calculer la fonction cubique beaucoup plus facilement comme ceci:

let startPoint: Utils.Vector2 = new Utils.Vector2(0, 100);
let endPoint: Utils.Vector2 = new Utils.Vector2(100, 100);


let a: number, b: number, c: number, d: number;

function calculateFunction() {
    let m0: number = 0;
    let m1: number = 0;

    a = (-endPoint.x * (m0 + m1) - 2 * startPoint.y + 2 * endPoint.y) / -Math.pow(endPoint.x, 3);
    b = (m1 - m0 - 3 * a * Math.pow(endPoint.x, 2)) / (2 * endPoint.x);
    c = m0;
    d = startPoint.y;
}


0 commentaires