10
votes

Position des cercles redimensionnables les uns des autres

Je travaille sur cette expérience basée sur le navigateur où je reçois n cercles spécifiques (disons qu'ils ont une image unique en eux) et doivent les positionner ensemble, laissant aussi peu d'espace que possible entre eux. Il ne doit pas nécessairement être arrangé dans un cercle, mais ils devraient être "regroupés" ensemble.

Les tailles de cercle sont personnalisables et qu'un utilisateur sera en mesure de modifier les tailles en faisant glisser un curseur JavaScript, en modifiant certaines tailles de cercles (par exemple, dans 10% du curseur, le cercle 4 aura une rayon de 20px, cercle 2 10px, cercle 5 reste le même, etc ...). Comme vous l'avez peut-être déjà deviné, je vais essayer de "transition" le redimensionnant-repositionnement en douceur lorsque le curseur est déplacé.

L'approche que j'ai essayée a essayé jusqu'à présent: au lieu d'essayer manuellement de les positionner, j'ai essayé d'utiliser un moteur de physique -

Mon exemple d'approche

L'idée:

  1. Placez une sorte de tirage gravitationnel au centre de l'écran
  2. utilisez un moteur physique pour prendre soin de la collision des boules
  3. pendant l'événement "Faites glisser l'heure", je voudrais simplement définir différents tailles boule et laisser le soin de prendre du moteur du reste

    Pour cette tâche, j'ai utilisé "Box2DWeb". J'ai placé une poitrine gravitationnelle au centre de l'écran, cependant, il fallait très longtemps jusqu'à ce que les balles soient placées au centre et elles flottaient. Ensuite, j'ai mis un petit morceau de balle statique au centre afin de pouvoir le frapper puis s'arrête. Cela ressemblait à ceci:

    Essai Box2D

    Les résultats étaient un peu meilleurs, mais les cercles ont toujours déplacé pendant un certain temps avant de se rendre statique. Même après avoir joué avec des variables comme la frottement de la balle et des tirages gravitivement gravitationnels, tout simplement flotté autour et se sentait très "wobbly", alors que je voulais que les balles ne se déplacent que lorsque je fais glisser le curseur de temps (quand ils changent de tailles). De plus, Box2D ne permet pas de changer la taille des objets et je devrais pirater ma voie pour une solution de contournement.

    Ainsi, l'approche Box2D m'a fait comprendre que peut-être laisser un moteur de physique pour gérer cela n'est pas la meilleure solution pour le problème. Ou peut-être que je dois inclure une autre force que je n'ai jamais pensée. J'ai trouvé Cette question similaire à mien sur Stackoverflow. Cependant, la différence très importante est qu'elle génère simplement des cercles non spécifiques "à la fois" et ne permet pas de complément de la taille de la balle et de la manipulation de position spécifique.

    Je suis vraiment coincé maintenant, quelqu'un a-t-il des idées comment aborder ce problème?

    Mise à jour : Cela fait presque un an maintenant et j'ai totalement oublié ce fil. Ce que j'ai fait à la fin consiste à coller au modèle physique et à réinitialiser les forces / arrêt dans des conditions presque inactives. Le résultat peut être vu ici ici http://stateofwealth.net/ les triangles que vous voyez sont à l'intérieur de ces cercles. Les lignes restantes sont connectées via "Algorithme de triangulation Delaunay"


2 commentaires

Essayez l'amortissement linéaire et angulaire. Et Box2D prend en charge le redimensionnement via recrée (c'est que votre piratage?).


Oui, je détruisez et crée les objets dans Box2D. Cependant, cela produit des résultats très "numeux". Je me sens comme si j'avais choisi un mauvais cadre pour cette tâche. Je vais google pour l'amortissement linéaire / angulaire de Box2D pour moins d'un modèle Wobbly, mais je suis un peu sceptique, cela résoudra mes problèmes ATM


3 Réponses :


1
votes

(pas un commentaire car il ne serait pas adapté)

Je suis impressionné que vous ayez apporté sur Box2D pour aider avec le levage lourd, mais c'est vrai que malheureusement, ce n'est probablement pas bien adapté à vos besoins, car Box2D est à son meilleur lorsque vous êtes après simulation rigide objets et leur dynamique de collision.

Je pense que si vous considérez vraiment ce que vous avez besoin, ce n'est pas tant de problème de dynamique corporelle rigide du tout. Vous ne voulez réellement aucune de la complexité de Box2D car toute votre géométrie est constituée de sphères (que je vous assure que vous êtes beaucoup plus simple à modéliser que les polygones convexes arbitraires, ce qui est la complexité de la box2D iMo de), et comme vous mentionnez, incapacité de Box2D à Modification en douceur Les paramètres géométriques ne vous aident pas, car il va tourner le navigateur avec des allocations de géométrie inutiles et des translocations et ne parviennent pas à appliquer toute sorte d'animation en douceur.

Ce que vous recherchez probablement est un algorithme ou une méthode pour évoluer les positions d'un ensemble de coordonnées (chacune avec un rayon qui change également potentiellement) afin de rester séparé par leurs rayons et de minimiser leur distance au centre. position. Si cela doit être lisse, vous ne pouvez pas simplement appliquer la solution minimale à chaque fois, car vous risquez de «se déformer» car la configuration optimale pourrait se déplacer considérablement à des points particuliers sur le mouvement de votre curseur. Il suffit de dire qu'il y a beaucoup de peaufie à faire, mais pas vraiment plus difficile que ce que l'on doit faire face à l'intérieur de Box2D.

Quelle est l'importance que vos cercles ne se chevauchent pas? Je pense que vous devriez juste faire un simple "solutionneur" itératif qui tente d'abord d'apporter les cercles vers leur cible (centre d'écran?), Puis essaie de les séparer en fonction des rayons.

Je crois que si vous essayez de trouver un modèle mathématique simplifié pour la motion que vous souhaitez, ce sera mieux que d'essayer d'obtenir une boîte à faire. Box2D est magique, mais ce n'est que bon à ce que c'est bon.


5 commentaires

Je ne m'attendais pas à impressionner quelqu'un avec l'idée: D Je pensais en fait que c'est une approche "muette" pour utiliser la physique pour résoudre mes problèmes. Je vois votre argument que Box2D est une sorte de surkilleuse pour mon problème, car je veux vraiment m'occuper de cercles et non rigides aussi. Cependant, lorsque j'utilise seulement des cercles, les calculs Box2D sont assez rapides, car je n'utilise aucun autre complexe polygones. J'ai même réussi à "sorte de douceur" redimensionner les formes en les détruisant et en les créant très rapidement, mais voici là que le framerate a chuté massivement et c'est le problème que je traite maintenant. [Commentaire trop long, TBC ..]


[..commenter continue] C'est assez important pour moi pour les cercles de ne pas se chevaucher, comme cela est fait pour un plaisir visuel. Mais il n'est pas important du tout d'avoir une solution minimale, un autre critère est la transition en douceur (c'est pourquoi j'ai choisi un moteur de physique). J'ai effectivement essayé de coder ma propre logique de cercle de collision simple au début, mais elle a échoué. Les cercles se chevauchent, il vient de sauter autour, etc. C'est pourquoi j'ai décidé de choisir un moteur de quelqu'un qui sait comment le faire correctement (et a trouvé Box2D). Connaissez-vous d'un autre moteur de physique qui conviendrait au problème?


Je ne considère toujours pas cela un problème de physique. Quel genre de choses physiques élargissent et contracter de comme ça? Vous devez probablement développer une nouvelle branche de maths pour le modeler. En utilisant quelque chose de poids lourd comme Box2D dans le navigateur (ce qui viendra simplement vous lancer dans votre navigateur pauvre dans votre navigateur pauvre, car vous créez et détruisez des choses dans des boucles) ne vous rapprocheront pas du but du mouvement en douceur.


Le modèle de physique ne signifie pas simuler la physique de la vie réelle, il peut également être des atomes, des ressorts, tout. Jusqu'à présent, le modèle Box2D était la fermeture de ce que je veux. La bibliothèque D3.JS que quelqu'un a mentionné ici (qui utilise également un modèle de physique) était également très bon pour cela, cependant, il a le problème de se chevaucher qui est crucial pour moi. Le problème avec le pauvre box2D framerate est la récréation d'objet en raison de son modèle de corps rigide. Donc, à moins que je trouve un meilleur modèle pour la tâche, je suis coincé avec Box2D. Mais si vous connaissez ce "modèle mathématique", je serais seulement heureux de l'utiliser. Après tout, je suis ici parce que je suis coincé


Eh bien, je suppose que mon point est que Box2D n'a apporté aucune sorte d'effort pour intégrer sa formulation de géométrie la notion de rayons dynamiques. C'est tout à fait possible de le faire, et s'il y avait cette capacité, il serait parfait pour votre utilisation. J'ai fait ma propre creuser dans son architecture et je crois qu'il existe une façon raisonnable de modéliser de telles géométries de cercle "à ballon"; C'est juste une caractéristique qui ne serait accompagnée que de situations très spécifiques comme la vôtre. Il peut également fonctionner pour modéliser une forme d'onde d'explosion, mais même avec cela, je préférerais une réponse d'impact plus douce.



5
votes

Je me souviens de voir un D3.js Démo très similaire à ce que vous décrivez. Il est écrit par Mike Bostock lui-même: http://bl.ocks.org/mbostock/1747543

Capture d'écran de D3.JS Circle Emballage

Il utilise quadrachees pour une détection de collision rapide et utilise un graphique basé sur la force, qui sont tous deux des utilitaires D3.JS.

Dans la fonction coche , vous devez être capable d'ajouter un .attr ("r", fonction (d) {retour d.radius;}) qui va Mettez à jour le rayon chaque fois que vous modifiez les données noeuds . Juste pour commencer, vous pouvez la définir pour retourner aléatoire et les cercles devraient gêner comme un fou.


4 commentaires

Merci pour cette suggestion. J'ai testé ce moteur et c'est assez bon! Cependant, il y a une chose qui m'accroche lorsque vous utilisez ce moteur et c'est une telle honte, car il est bon - que d'être: quand j'ai déménagé / redimensionné les cercles, ils se chevauchent :( C'est assez important pour moi pour les cercles de ne pas se chevaucher, Comme l'aspect principal de l'expérience est une expérience esthétique. J'ai essayé de chercher une sorte de variable / de paramètres pour une détection de collision précise, même lorsque vous déplacez les cercles, mais malheureusement trouvé aucun: / savez-vous comment pouvez-vous faire face à ce problème? du moteur?


Sans connaître le code moi-même, il semble que les cercles se chevauchent dus à cluster () et à la disposition de la force, mais éventuellement les cercles distincts lorsqu'il est réglé au fil du temps via collision () . Peut-être que si vous appelez collision () plus souvent par coche ou simplement en boucle jusqu'à ce qu'il n'y ait plus de collisions détectées. Il y a aussi une variable alpha ( Github.com / Mbostock / D3 / Wiki / Force-Disposition # Wiki-Alpha ) qui pourrait être pratique pour modifier.


De plus, si vous avez plus de problèmes, je vous recommanderais de créer une démonstration de votre problème et de poster sur la liste de diffusion D3.JS. Ils sont généralement très utiles.


Merci pour vos suggestions, je jouerai certainement avec la collision (). J'espère juste que ça ne sera pas trop puissant après



0
votes

Au moins pour moi, on dirait que la solution la plus facile est de créer d'abord les cercles d'un cluster. Donc, d'abord définir le plus grand cercle du centre, mettez le deuxième cercle à côté du premier. Pour le troisième, vous pouvez simplement le mettre à côté du premier cercle, puis le déplacer le long du bord jusqu'à ce qu'il frappe le deuxième cercle. Entrez la description de l'image ici

Tous les autres cercles peuvent suivre la même méthode: placez-le à côté d'un cercle arbitraire et déplacez-le le long du bord jusqu'à ce qu'il touche, mais pas intersectant, un autre cercle. Notez que cela ne fera pas le regroupement le plus efficace, mais cela fonctionne. Après cela, lorsque vous développez, dites, encerclez 1, vous déplacez tous les cercles adjacents vers l'extérieur et déplacez-les pour re-grappe.


1 commentaires

Merci pour votre suggestion, l'idée du placement du cercle est très fine mais l'approche est plus appropriée pour une approche statique "définie et une image". L'approche ne peut pas gérer la nécessité de la transition dynamique / lisse lors du redimensionnement ou du déplacement des cercles.