Insérer un point dans un NSBezierPath
UniX
Membre
Salut.
Je créé un NSBezierPath avec la souris (je récupère les coordonnées de chaque points dans mouseDown, et je les ajoute au NSBezierPath).
Maintenant, je souhaiterais pouvoir insérer des points dans ce NSBezierPath. L'idéal serait d'avoir une méthode qui, avec les coordonnées du point cliqué, détecte si il se trouve sur la trajectoire du NSBezierPath, et renvoie le point précédent par exemple ....
Comment faire ?
Je créé un NSBezierPath avec la souris (je récupère les coordonnées de chaque points dans mouseDown, et je les ajoute au NSBezierPath).
Maintenant, je souhaiterais pouvoir insérer des points dans ce NSBezierPath. L'idéal serait d'avoir une méthode qui, avec les coordonnées du point cliqué, détecte si il se trouve sur la trajectoire du NSBezierPath, et renvoie le point précédent par exemple ....
Comment faire ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
( fp pour le premier point, sp pour le second).
Normalement, ca devrait suffire
Imagine que tu ais un NSBezierPath avec un angle fermé comme ci-contre :
Si tu cliques sur le NSBezierPath à côté du point 3, ben le point le plus proche, c'est pas le 2, mais le 1 ....
Le but est d'insérer un point dans le bezier. Donc, si je clique à côté du point 3, c'est que je veux insérer un point entre le 2 et le 3, mais si je ne fais que tester le point plus proche, c'est le 1 qu'il va trouver, pas le 2 ...
Mais je suis d'accord avec toi, ça va pas être simple ...
Dans ce cas, en tant que apôtre de la non-mathémathique, voilà ce que je te suggère :
En fait, le code est simple : je récupère chaque élément du bezier-path. Ensuite, je construits un bezier-path temporaire ne contenant que cet élément. Via containsPoint:, je vérifie si le point de ma souris est dans ce bezier-path temporaire. Si c'est le cas, j'arrête tout, sinon, je continue en scannant les autres éléments.
Je n'ai pas implémenté tous les NSBezierPathElement (je te laisse un peu de travail)...
D'autre part, je ne sais pas si c'est la meilleur (ou plus efficace) méthode, mais ça devrait marcher.
.
Le code de Bru est dans le genre de ce que j'allais proposer après avoir relu l'énnoncé, mais je ferais juste une remarque. La méthode containsPoint marche évidemment pour les traits, mais il faut cliquer très très précisément (en fait ça ne marche même pas à tous les coups, vu que la position de la souris est donnée avec des valeurs entières, mais dans le cas d'une ligne non horizontale (ou verticale) et la ligne ne passe pas forcément par ces valeurs). Je pense que ce problème peut se résoudre avec un [tt][path setFlatness:1.0];[/tt] (ou éventuellement par la moitié de l'épaisseur de ton trait - la valeur par défaut est 0.6), mais je n'ai pas testé.
J'avais résolu ça en testant les 9 points (via une seconde boucle) autour du point de ma souris... Je ne l'ai pas mis, afin que UniX travaille un peu...
.
Je vais regarder ça, et dès que j'ai un résultat, je vous tiens au courant ....!
Pour trouver la solution au problème, j'ai plusieurs questions qui me viennent à l'esprit :
1) containsPoint teste-t'il tous les points du bezier, ou seulement ceux de construction (dans notre cas le départ et l'arrivée), c'est juste pour être sûr car la doc est pas trop claire ...
2) les coordonnées des points du bezier sont-ils des entiers ? Car mes points de test ont des coordonnées entières, mais par exemple les points de construction (point1, point[0] dans l'exemple de Bru) ne sont pas entiers ...
Il est préférable de travailler en float, car les membres de la structure NSPoint sont définis en float.
Quand je vais dans le debbuger, je vois les coordonnées des points de construction du bezier qui sont du style :
Si les coordonnées des points peuvent avoir des décimales, moi quand je teste mes points, c'est des coordonnées du style :
donc forcemment, il ne les trouve pas identiques ....
Mais, si c'est bien ça, comment faire ...?
Tu as essayé ça (en mettant éventuellement plus que 1)?
Dans ce cas au lieu de comparer x et y aux coordonnées de la souris, tu compares floorf(x), floorf(y), ceilf(x) et ceilf(y) aux coordonnées de la souris...
Quand à floorf et ceilf, je ne peux pas le faire, car je cherche à déterminer si le clic de la souris est sur le bezier ou non avec containsPoint.
Le désespoir me guette ... :-\\
Ce n'est pas ce que je voulais dire, mais c'est pas grave.
Va jeter un coup d'oeil ici : http://www.cocoadev.com/index.pl?HitDetection
.
Le pb n'est pas là . Cette méthode ne fonctionne pas, car, visiblement, les coordonnées des points composant un NSBezierPath, ne sont pas des entiers ou des float sans décimales (voir mes posts précédants) ..... Donc containsPoint: ne renvoie jamais YES.
Eddy58, je viens de jeter un oeil rapide à ton lien, ça peut être intéressant. Je vais le regarder de plus près.
[Fichier joint supprimé par l'administrateur]
Je pense que tu as un cas particulier (ou c'est moi qui en ai un) avec peut être des coordonnées de points entiers. Moi, en fait, j'ai un coef de zoom appliqué à ma vue, donc je dois avoir des coordonnées décimales, et dans ce cas, ça ne fonctionne pas ... Je ne vois que cette explication.
Essayes peut être la manip en mettant des coordonnées à 6 décimales pour les points de construction de ton bezier, pour voir.
Merci à vous de vous être penché sur le problème.