Dessin d'un damier

fouffouf Membre
21:43 modifié dans API AppKit #1
Je souhaite créer une vue qui fait un damier grace à  2 couleurs. Comment faut-il que je m'y prenne ? En utilisant NSFillRect() ? Quelqu'un aurait-il un exemple pour moi ?

Réponses

  • Eddy58Eddy58 Membre
    avril 2005 modifié #2
    Oui, tu utilises NSRectFill, tu fais deux boucles imbriquées pour dessiner, dans ce genre là  : :)
    [tt]
    int x,y
    float largeur,hauteur;
    x=0;
    y=0;
    largeur=100.0;
    hauteur=100.0;
    for (y=0;y<7;y=y+1)
    {
    for (x=0;x<7;x=x+1)
    {
    NSRectFill(NSMakeRect (x*largeur,y*hauteur,(x*largeur)+largeur,(y*hauteur)+hauteur))
    }
    }
    [/tt]
    C'est vraiment pour le principe, l'important est les deux itérations, ensuite il faut rajouter le code pour choisir la couleur du carreau avant NSRectFill.
  • fouffouf Membre
    21:43 modifié #3
    Ok, merci beaucoup Eddy.

    Juste une question : x et y sont bien le nombre de carreaux dessinés (x carreaux en longueur et y en largeur) ? Et largeur et hauteur sont bien les mesures des cotés du rectangle à  remplir ? Je ne me trompe pas ?

    Par contre, j'ai peur que pour le changement de couleur, faire un [color set] soit un peu lourd pour le proc. Est-ce le cas ou non ?

    Re-merci
  • Eddy58Eddy58 Membre
    21:43 modifié #4
    Oui Fouf, x et y sont les compteurs de carreaux, et largeur et hauteur les dimensions d'un carreau. Je ne sais pas si le choix de couleur prend bcp de temps proc, mais je ne pense pas, c'est une méthode couramment employée... :)
  • fouffouf Membre
    21:43 modifié #5
    Bon, j'ai fait une petite appli d'essai grace à  ton code Eddy. C'est parfait. J'ai fait plusieurs choses : damier avec un nombre déterminé de cases, avec une taille déterminé des cases, ... tout marche. Mais, du coté performance, c'est pas trop ca. Même avec CacheDoubler (merci oxitan  ;)) , lorsque j'étire la vue au max, ca dure. Pour un petit test, voila l'appli.

    Je me demandais si faire un NSBezierPath avec tous les carrés d'une couleur, puis une autre avec l'autre couleur, puis faire un fill de l'une, changer la couleur une fois et dessiner la deuxieme ne serait pas mieux. Manque de peau, on ne peu pas (à  ma connaissance) faire un NSBezierPath qui remplit un rectangle. Quelqu'un a une idée ?

    [Fichier joint supprimé par l'administrateur]
  • Eddy58Eddy58 Membre
    avril 2005 modifié #6
    C'est vrai que ça rame au resizing de la fenêtre...
    Une chose à  faire, est de tracer un rect de la taille de ton damier d'une couleur, et ensuite, dans les boucles, tu dessines un carré sur deux avec l'autre couleur. Si tu n'utilises pas la transparence, tu peux aussi recouvrir la méthode isOpaque en retournant YES. :)

    [EDIT]
    En faites, le mieux est d'employer la fonction NSRectFillList(), tout à  fait adaptée à  ce genre de cas. Je ne l'ai jamais utilisée, mais apparemment, de par son fonctionnement, elle permet une vitesse d'affichage 10 fois supérieure à  NSRectFill(). :)
  • fouffouf Membre
    21:43 modifié #7
    J'était en train de travailler sur la première approche, mais je pense que je vais utiliser NSRectFillList. Merci Eddy.
  • Eddy58Eddy58 Membre
    21:43 modifié #8
    Voici un projet issu de CocoaProgramming, qui montre plusieurs techniques de tracé (dont NSRectFillList), notamment en cache : :)

    [Fichier joint supprimé par l'administrateur]
  • fouffouf Membre
    21:43 modifié #9
    Merci beaucoup, je vais m'en servir.
  • ChachaChacha Membre
    avril 2005 modifié #10

    Par contre, j'ai peur que pour le changement de couleur, faire un [color set] soit un peu lourd pour le proc. Est-ce le cas ou non ?

    Si tu veux faire un code vraiment efficace, tu peux faire la chose suivante:
    Tu remplis toute ta grille avec un rectangle de couleur A
    ensuite tu dessines par dessus les rectangles de couleur B; ça te fait un seul [color set], et tu dessines deux fois moins de choses.
    +
    Chacha

    [edit]
    Je viens de voir qu'Eddy58 a dit la même chose, j'avais raté le post. Du coup je viens de pondre le code suivant pour rien; bô, pas grave, je te le file quand même

    <br />-(void) drawRect:(NSRect)rect<br />{<br />  //remplit le fond<br />  NSColor* colorA = [NSColor redColor];<br />  [colorA set];<br />  NSRectFill(rect);<br />  <br />  //prepare la deuxième couleur<br />  NSColor* colorB = [NSColor blueColor];<br />  [colorB set];<br />  <br />  //Calcule les rectangles à  tracer en fonction du rect courant<br />  const float rectSize = 50; //taille d&#39;un carreau du damier<br />  const int minXIndex = (int) (rect.origin.x / rectSize);<br />  const int maxXIndex = (int) ceil((rect.origin.x + rect.size.width) / rectSize);<br />  const int minYIndex = (int) (rect.origin.y / rectSize);<br />  const int maxYIndex = (int) ceil((rect.origin.y + rect.size.height) / rectSize);<br />  const int nbRects = (maxXIndex-minXIndex+1)*(maxYIndex-minYIndex+1); //à  peaufiner (surévalué ici)<br />  NSRect* rectList = nbRects ? (NSRect*) malloc(nbRects*sizeof(NSRect)) : NULL;<br />  int exactNbRects = 0;<br />  int i = 0;<br />  int j = 0;<br />  for(j=minYIndex ; j&lt;=maxYIndex ; ++j)<br />  {<br />    for(i=minXIndex + (j%2) ; //le coup du %2, c&#39;est pour décaler d&#39;une ligne sur l&#39;autre<br />        i&lt;=maxXIndex ; i += 2)<br />    {<br />      rectList[exactNbRects++] = NSMakeRect(i*rectSize, j*rectSize, rectSize, rectSize);<br />    }<br />  }<br />  <br />  //trace les rectangles<br />  NSRectFillList(rectList, exactNbRects);<br />  <br />  //ménage<br />&nbsp; if (rectList)<br />&nbsp;   free(rectList);<br />}<br />
    
  • fouffouf Membre
    21:43 modifié #11
    Ouah, Chacha, t'es un pote. C'est promis, j'essaye ca demain.
  • gifagifa Membre
    21:43 modifié #12
    Essai cet exemple et dit moi ce que tu en pense

    [Fichier joint supprimé par l'administrateur]
  • fouffouf Membre
    21:43 modifié #13
    Il ne s'ouvre pas. T'as du oublier de le recompiler en mode Deployment.
  • gifagifa Membre
    21:43 modifié #14
    Oui j'avais oublié

    [Fichier joint supprimé par l'administrateur]
  • fouffouf Membre
    21:43 modifié #15
    Merci Gifa pour le calcul du temps. C'est sur, c'est plus rapide que le NSRectFill de mon premier Damier.

    Ya un truc marrant que j'ai observer, c'est que ca "flash" un peu quand on utilise pas isFlipped. Enfin, ca ne change pratiquement rien. Merci beaucoup les gars.
  • CéroceCéroce Membre, Modérateur
    21:43 modifié #16
    Une autre possibilité qui pourrait t'intéresser, c'est la méthode +colorWithPatternImage: de NSColor.

    Tu peux dessiner une image bitmap de 4 cases de ton damier et remplir un rectangle avec.
Connectez-vous ou Inscrivez-vous pour répondre.