Comparer deux NSPoint

CoreCore Membre
00:03 modifié dans API AppKit #1
Bonjour,

J'aimerais comparer deux NSPoint p et q, Naà¯vement j'ai fait

<br />if (p == q)<br />{<br />}<br />


et j'ai une erreur :
error: invalid operands to binary ==


Comment puis je les comparer ?

Réponses

  • muqaddarmuqaddar Administrateur
    janvier 2005 modifié #2
    Avec isEqualTo puisque ce sont des pointeurs non ?

    if ([p isEqualTo: q]) {<br /><br />}
    


    Mais je n'en suis vraiment pas sûr... ;)
  • CoreCore Membre
    janvier 2005 modifié #3
    dans 1106128040:

    Avec isEqualTo puisque ce sont des pointeurs non ?

    if ([p isEqualTo: q]) {<br /><br />}
    


    Mais je n'en suis vraiment pas sûr... ;)


    Et bien non ca ne marche pas non plus
  • VeillardVeillard Membre
    00:03 modifié #4
    Il y a p'têt quelque chose à  faire :
    if (p.x == q.x &amp;&amp; p.y == q.y)
    

    C'est peut-être un peu lourd, mais essaie...
  • ChachaChacha Membre
    00:03 modifié #5
    Salut,

    C'est normal que == ne marche pas directement, car l'opérateur == n'est pas défini en C pour les struct. Or, NSPoint est une struct.
    Donc (p.x == q.x) && (p.y ==  q.y) est en théorie la seule solution
    Sinon, il y a
    BOOL NSEqualPoints(NSPoint p, NSPoint q) que tu peux utiliser, mais elle ne fera sans doute pas mieux que le truc précédent. Enfin, je pense.

    +
    Chacha
  • CoreCore Membre
    00:03 modifié #6
    Merci  !!!

  • maconnectmaconnect Membre
    00:03 modifié #7
    tu dois impérativement utiliser NSEqualPoints. La méthode du == ne va pas marcher, pas toujours.
    En effet les float ne sont pas des nombres précis, ce sont des nombres arrondis (à  6 décimales). Donc deux nombres peuvent très bien être égaux mais le test == échouera.

    Au pire des cas, tu peux faire:
    if (p.x > pp.x-0.0001 && p.x < pp.x+0.0001)

    Mais utilises NSEqualPoints, c'est plus facile :)
  • ChachaChacha Membre
    00:03 modifié #8
    Ouh là , je suis pas d'accord, là  !

    Il est vrai que comparer l'égalité entre deux float est un peu hasardeuse, à  cause des arrondis qui sont fait dans les calculs. Il vaut mieux, effectivement, utiliser une marge de sécurité sous forme d'un test par intervalle.
    Cependant, on ne peut pas dire que les float sont limités à  6 décimales, ce sont des nombres à  virgule "flottante", justement ! Donc il est arbitraire de se fixer un intervalle de taille 1e-6, ou 1e-4, ou 1.234e-5 pour la comparaison.
    Donc NSEqualPoints ne peut pas se permettre de fixer pour nous une limite de validité de l'égalité, et par conséquent n'a pas de raison de faire mieux qu'un ==.
    Voilà .

    Sinon, oui, il est plus simple d'utiliser NSEqualPoints, sauf si, justement, on veut contrôler l'intervalle de validité de l'égalité.

    Test pour prouver mes dires :
      NSPoint p1 = NSMakePoint(1,2);
      NSPoint p2 = NSMakePoint(1+1e-7,2);
    Et bien NSEqualPoints(p1, p2) renvoie bien FAUX.

    +
    Chacha
  • maconnectmaconnect Membre
    00:03 modifié #9
    Salut!
    Ok, merci pour l'info. J'ai mis des intervalles car à  l'époque, quand je programmais en C, il m'était arrivé que le test == échoue pour deux même nombres (dont l'un obtenu par calcul, d'où l'imprécision) et depuis je mets des intervalles.
    De plus, toute littérature sur le sujet déconseille de comparer directement deux floats. On peut imaginer qu'il y ait des cas pour lesquels NSEqualPoints() échoue. C'est pour ça que je pensais qu'ils avaient mis des marges.
    Finalement, l'utilisation de NSEqualPoints est-elle vraiment "sûre" ?

    vala :)
  • ChachaChacha Membre
    00:03 modifié #10
    dans 1106322127:

    Finalement, l'utilisation de NSEqualPoints est-elle vraiment "sûre" ?


    Ben non, t'as raison, d'un certain point de vue, NSEqualPoints n'est pas "sûre". Par contre, cette fonction fait exactement ce qu'on attend d'elle, elle compare deux float avec ==. Donc tant qu'on sait ce qu'on fait et que l'on n'en attend pas plus, alors oui, ça reste une bonne fonction bien pratique. Et il y a quand même beaucoup de cas où le test sera correct, ne serait-ce que si on ne stocke que des valeurs entières (pas immenses toutefois) dans le NSPoint.
  • maconnectmaconnect Membre
    00:03 modifié #11
    ok, trps bien  8)

    Je souligne en passant les fonctions NSPointInRect et NSLocationInRange qui sont pratiques aussi! C'est vraiment des fonctions toutes bêtes, mais ça évite d'écrire 2 lignes de plus (ben oui, je suis flemmard)

    ++
Connectez-vous ou Inscrivez-vous pour répondre.