Comment effacer un dessin ?

macvelottemacvelotte Membre
06:41 modifié dans API AppKit #1
Salut les champions ...

J'ai "dessiné" sur un fond d'image ; je voudrais remplacer ce dessin (commande par NSTimer ...) pour obsrver son évolution au cours du temps : est-il possible de l'effacer sans modifier l'image de fond ?

Réponses

  • Eddy58Eddy58 Membre
    06:41 modifié #2
    Salut macvelotte :)

    Donne plus de précisions sur ce que tu veux faire, c'est une animation en faites ? Quelles sont les techniques de dessin que tu emploies (drawRect: ?), comment est ton fond (image, ou bien fond uni) ?
  • macvelottemacvelotte Membre
    06:41 modifié #3
    Le fond : une image (planisphere)

    Le dessin : dans un rectangle (NSRect) des courbes (NSBezierPath)

    Oui, c'est en somme une animation (qui évolue sur 24 heures ...)
  • cbrandtcbrandt Membre
    06:41 modifié #4
    je pense qu'il suffit de redessiner d'abord l'image du planisphère puis les courbes de bézier à  la nouvelle position
  • macvelottemacvelotte Membre
    06:41 modifié #5
    Je crois qu'il faut que je m'explique un peu mieux ! Mais il serait bon que je montre une copie de ma fenêtre avec quelques commentaires : comment faire pour joindre cette copie ? (au format .jpg)
  • muqaddarmuqaddar Administrateur
    06:41 modifié #6
    Quand tu crée ton message, clique sur "options supplémentaires" et joints ton image.
  • macvelottemacvelotte Membre
    06:41 modifié #7
    fenetre.jpg
    Le fond de la fenetre est une NSImageWiew (le planisphere)
    Par dessus, une CustomView (StretchView) avec un rectangle aux dimensions de la fenêtre, clearColor (transparence pour le planisphere) et les courbes de Bezier remplis de nooir avec différentes transparences pour indiquerr successivement crépuscules civil, nautique, astronomique puis nuit (pas complètement noire ...)
    Le disque jaune représente le soleil au dessus du point de la terre où il est au zénit.

    J'aimerais donc retracer les crépuscules ; ceux-ci avancnt de droite à  gauche à  raison d'un pixel toutes les 2 minutes.
  • macvelottemacvelotte Membre
    06:41 modifié #8
    Je m'perrçois que je n'ai pas cliqué au bon endroit pour joindre mon image !
    Qulle est l'icone "options" ?
  • muqaddarmuqaddar Administrateur
    06:41 modifié #9
    C'est pas une icone !!!
    Dessous ton message, il y  un lien "options supplémentaires".
  • macvelottemacvelotte Membre
    06:41 modifié #10
    Voici donc l'image en question ...
    Les écrans sont toujours trop petits !

    [Fichier joint supprimé par l'administrateur]
  • cbrandtcbrandt Membre
    06:41 modifié #11
    et si tu utilisais une seule view, dans laquelle tu dessine d'abord le planisphère et ensuite les courbes de Bezier ?
  • mpergandmpergand Membre
    06:41 modifié #12
    Je pense qu'il te suffit de faire un setNeedsDisplay dans la méthode appelée par ton timer:

    -(void) methodeTimer:(NSTimer*) timer
    {
      [stretchView setNeedsDisplay:YES];
    }
  • macvelottemacvelotte Membre
    06:41 modifié #13
    Pas de succès jusqu'à  maintenant : est-il possible d'effacer le rectangle dans lequel est fait le dessin (équivalent du clearsreen ou clrscr d'autrefois ...?)
  • mpergandmpergand Membre
    06:41 modifié #14
    J'ai comme une impression de déjà  vu :
    http://www.objective-cocoa.org/forum/index.php?topic=387.0
  • Eddy58Eddy58 Membre
    06:41 modifié #15
    Je pense comme cbrandt, tout faire dans une seule view est suffisant non ? :)
  • macvelottemacvelotte Membre
    06:41 modifié #16
    Je vais essayer une seule NSView ...
    Mais je n'arrive pas à  y mettre mon planisphere ..
    et je suis un clampin : quid du code correct pour NSEraseRect ???
  • mpergandmpergand Membre
    06:41 modifié #17
    Ne les écoute pas  :)

    As tu regardé le lien que je t'indique ?

    En gros: fais-tu un removeAllPoints sur ton bezierpath avant de faire un nouveau tracé ?
  • macvelottemacvelotte Membre
    06:41 modifié #18
    removeAllPoints  ...
    dans le style [macourbe removeAllPoints] ???

    J'essaye
  • CéroceCéroce Membre, Modérateur
    06:41 modifié #19
    dans 1110795126:

    et si tu utilisais une seule view, dans laquelle tu dessine d'abord le planisphère et ensuite les courbes de Bezier ?



    Il me semble que Cocoa ne possède pas de méthode pour plaquer une bitmap directement, il faut donc faire appel aux fonctions Quartz (bref, se taper la doc). C'est long. J'aurais fais comme toi MacVelotte.
    Par contre, je ne comprends pas pourquoi faire un setNeedsDisplay: ne marche pas.
  • macvelottemacvelotte Membre
    06:41 modifié #20
    merci à  tous (ça évite d'oublierun nom ...)

    Bon, je n'ai pas encore de solution ; il faut donc conculter les documents ...à’
  • mpergandmpergand Membre
    06:41 modifié #21
    Un exemple valant mieux qu'un long discours, voici BezierPathAnimé:

    J'ai utilisé une vue séparée pour le soleil et pour l'ombre.
    Cela permet de montrer deux techniques différentes:
    - déplacement de l'origine de la vue pour le soleil
    - translation d'un bezier Path pour l'ombre

    Je ne fait aucun test de dépassement des vues, et j'entrevois un petit problème à  ce niveau: pour l'ombre si le bord de la planisphere est atteint, il faut dessiner la partie qui dépasse de l'autre coté de la planisphère ! Une solution simple serait de dessiner deux fois la partie dans l'ombre : NJN (nuit-jour-nuit) ainsi une simple translation permet de positionner correctement l'ombre dans la planisphère.



    [Fichier joint supprimé par l'administrateur]
  • Eddy58Eddy58 Membre
    06:41 modifié #22
    dans 1110872235:

    Il me semble que Cocoa ne possède pas de méthode pour plaquer une bitmap directement, il faut donc faire appel aux fonctions Quartz (bref, se taper la doc). C'est long. J'aurais fais comme toi MacVelotte.
    Par contre, je ne comprends pas pourquoi faire un setNeedsDisplay: ne marche pas.

    Ha bon ? ???
    Il s'agit ici, dans la méthode drawrect de ta view, d'afficher ton image en début de tracé, ensuite tu traces tes NSBezierPaths à  la suite....pas besoin d'aller chercher dans les APIs Quartz pour faire ça...:)
  • macvelottemacvelotte Membre
    06:41 modifié #23
    OK mpergand : je vais étudier ce petit programme qui correspond à  ce que je cherche !

    N.B. : le soleil se déplace dans l'autre sens ... ce qui ne change rien au problème !
  • Eddy58Eddy58 Membre
    06:41 modifié #24
    Bon, voici un projet qui reprend le même principe que celui de mpergand ci-dessus, mais tout se fait dans une seule custom view. :)


    [Fichier joint supprimé par l'administrateur]
  • CéroceCéroce Membre, Modérateur
    06:41 modifié #25
    dans 1110894410:

    dans 1110872235:

    Il me semble que Cocoa ne possède pas de méthode pour plaquer une bitmap directement, il faut donc faire appel aux fonctions Quartz (bref, se taper la doc). C'est long. J'aurais fais comme toi MacVelotte.
    Par contre, je ne comprends pas pourquoi faire un setNeedsDisplay: ne marche pas.

    Ha bon ? ???
    Il s'agit ici, dans la méthode drawrect de ta view, d'afficher ton image en début de tracé, ensuite tu traces tes NSBezierPaths à  la suite....pas besoin d'aller chercher dans les APIs Quartz pour faire ça...:)


    Comment fais-tu pour "afficher l'image en début de tracé" sans les API Quartz ? C'est ce que j'appelle plaquer la bitmap.

    La solution de MacVelotte est d'utiliser une NSImageView en fond et de dessiner les courbes de Bézier dans la drawRect: d'un custom view non-opaque.
  • Eddy58Eddy58 Membre
    06:41 modifié #26
    Regardes dans le projet inclus avec mon poste ci-dessus, et tu trouveras réponse....:)
    Tu as toutes les méthodes nécessaires dans NSImage.
  • WIMPWIMP Membre
    06:41 modifié #27
    Tu devrais trouver la solution à  ton problème dans le projet "SimpleAnimation" que je joins à  ce message.

    [Fichier joint supprimé par l'administrateur]
  • macvelottemacvelotte Membre
    06:41 modifié #28
    OK WIMP : la solution est bien là  !

    Donc, plutot qu'effacer une NSBezierPath, on met pardessus l'image de fond, et on recommence !

    cette "simple animation" est un trésor !
  • macvelottemacvelotte Membre
    06:41 modifié #29
    suite ...

    ça marche, mais j'obtiens à  l'éxecution le messaage suivant :

    2005-03-21 10:32:00.906 planisphere[4734] *** NSTimer discarding exception 'NSInternalInconsistencyException' (reason 'lockFocus sent to a view whose window is deferred and does not yet have a corresponding platform window') that raised during firing of timer with target 337980 and selector 'retracer:'

    et je n'en comprends pas le sens ???
  • Eddy58Eddy58 Membre
    06:41 modifié #30
    Tu as un exemple nettement plus simple et adapté a ton projet dans ce poste Macvelotte... ;) :
    http://www.objective-cocoa.org/forum/index.php?topic=751.msg8641#msg8641
Connectez-vous ou Inscrivez-vous pour répondre.