29/09/2012 - 23:20
J'ai créé un git Repo ici:
https://github.com/ArthurWulfWhite/Bezier-Distance/
Vous pouvez télécharger les fichiers source sous forme de zip à partir de là. Il comprend également une démo que vous pouvez compiler à l'aide de FlashDevelop. Pour utiliser la démo, ouvrez le projet dans Flash Develop et cliquez sur 'Test Project'. Pendant l'exécution de la démo, cliquez sur le LMB pour randomiser une nouvelle courbe de Bézier et un nouveau cercle.
Bonne chance!
Le lien zip est difficile à voir - utilisez simplement Ctrl + F et tapez zip. Cette source représente quelques semaines de recherche et de programmation, j'espère qu'elle vous plaira.
Si vous prévoyez de diviser le bezier de manière récursive en segments et de vérifier les collisions avec eux, je suggère de créer un tableau de 100100 (grille) et de placer chaque segment dans les quatre carrés les plus proches, de sorte que vous n'avez qu'à vérifier les collisions avec 4/10 000 des segmente chaque image.
Je pense que vous bénéficierez de box2d à la fois en tant que programmeur et en tant que créateur de jeux, car il y a beaucoup de petits obstacles cachés dans la création d'un moteur physique `` simple '' qui rend le mouvement un peu cahoteux et moins fluide qu'il pourrait l'être.
Ancienne réponse: la voie pure.
Vous pouvez réellement voir si un cercle entre en collision avec une courbe de Bézier, en vérifiant la distance entre la distance entre le centre du cercle et le point le plus proche sur la courbe.
L'équation de la distance (en général)
expliqué:
Équation de Bézier:
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Cela peut se résumer à (avec une algèbre) - je vais omettre. (X, y) pour plus de lisibilité (ce sont toujours des points, pas un nombre)
q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start
La distance du point (x, y) est:
sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)
Pour trouver le point le plus proche sur le bezier de la balle, vous devez dériver et trouver tous les points où la dérivée est égale à zéro (les racines). Il s'agit d'un polynôme du troisième degré, vous pouvez donc utiliser une formule fermée, mais il peut ne pas être fiable car la précision des fractions représentées par virgule flottante de l'ordinateur peut ne pas être suffisante. Il est préférable d'utiliser Newton ou quelque chose de ce genre.
Le dérivé dont vous avez besoin pour trouver les racines est:
En supposant: a = début b = contrôle c = fin d = point central de cercle
La partie délicate consiste à multiplier ces points, vous devez utiliser le produit scalaire.
Si vous le souhaitez, j'ai le code pour cela et je peux le partager ici sous la forme d'une fonction qui renvoie simplement un booléen s'il y a ou non collision et un angle de collision. Certains problèmes pourraient apparaître dans la mise en œuvre naïve d'un moteur de collision comme celui-ci, par exemple une balle en mouvement rapide pourrait se coincer entre deux courbes.
Je recommande de l'éviter pour l'instant, résumez simplement les coefficients pour l'axe x et pour l'axe y et additionnez-les.
Utilisez n'importe quelle méthode fiable que vous pouvez choisir comme Newton pour trouver les racines, vérifiez la distance entre les points de racine sur le bezier, 0 <= t <= 1 au centre du cercle et vérifiez la distance pour les deux extrémités du bezier (commencez et fin) au centre du cercle, celui qui est le plus proche, vous dira s'il y a une collision.
Si le rayon est inférieur à la distance minimale, il y a collision.
L'angle est approximativement celui entre le centre du cercle et le point le plus proche sur le bezier.
Cela étant dit, si vous souhaitez vraiment faire un jeu avec la physique des collisions, je vous suggère de parcourir le bezier
q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))
Divisez chaque pièce au milieu de manière récursive jusqu'à ce qu'elle soit suffisamment petite, disons 10 pixels ou moins, puis construisez grossièrement le bezier à partir de boîtes et utilisez Box2d pour la physique, car il est possible que l'écriture de tout ce code de détection de collision se révèle être une excellente un temps qui n'améliore pas beaucoup le gameplay. L'utilisation de Box2d a fait ses preuves dans d'innombrables projets dans le passé.
Pour ce faire, je voudrais:
Brisez la courbe de Bézier en plusieurs segments de ligne et stockez-les.
Placez tous ces segments dans un cadre de délimitation aligné sur l'axe pour toute la courbe.
Détection de collision :
1) Vérifiez si la sphère se trouve à l'intérieur du cadre de sélection principal. sinon, pas de collision.
2) sinon, vérifiez si l'un des segments individuels calculés ci-dessus entre en collision avec la sphère. Voir l' article sur l'intersection ligne-sphère de Wikipedia .
EDIT: si vous avez besoin d'une grande précision et que vous souhaitez de bonnes performances, vous pouvez également créer un cadre de délimitation principal pour toute la courbe, puis subdiviser la courbe en deux segments (par exemple:
[0.0 - 0.5]
et[0.5 - 1.0]
). Créez une boîte boudante pour chacun d'eux, puis subdivisez à nouveau chacun de ces segments en deux segments (donnant ainsi[0 - 0.25]
,[0.25 - 0.5]
et[0.5 - 0.75]
,[0.75 - 1.0]
). Continuez ainsi jusqu'à ce que vous atteigniez suffisamment de précision. à la fin, vous aurez unbinary tree
des cadres de délimitation avec un cadre de délimitation de la courbe principale à la racine et des segments de ligne aux feuilles. la recherche dans l'arborescence vous donneraO(log n)
au lieu deO(n)
(oùn
= nombre de segments de ligne pour la courbe)la source
L'intersection entre une ligne et une courbe de Bézier est obtenue mathématiquement en subdivisant la courbe. Cela signifie s'appuyer sur la propriété de coque convexe de la courbe et la diviser en arcs plus petits avec différents polygones de contrôle de façon divisée et impera.
Cet article le couvre jusqu'à un certain point: http://students.cs.byu.edu/~tom/557/text/cic.pdf .
La bonne partie est que l'algorithme fonctionne avec n'importe quelle ligne, il vous suffit d'appliquer une transformation rigide à la courbe afin que vous puissiez considérer votre ligne cible comme parallèle à l'axe Ox.
De même, vous pouvez comparer le cercle et le polygone de chacun de ces arcs de Bézier lorsque vous subdivisez un arc de Bézier en deux sous-arcs. Le cercle doit intersecter le polygone de contrôle d'un arc pour qu'un test de courbe à cercle ait un sens.
la source