Invité ingoenius Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 commenrt est possible de fair e un test de valeurs possibles pour l'attribution d'un nombre au plus proche?? j'explique j'ai des valeur possibles de sections de ponts que sont (2 2.5 3 3.5 4 4.5 5 5.5 ) apres je demande a saisir une distance avec getdist , l'utilisateur peut donc saisir par exeple une distance de 2.62 etc comment fair attribuer a la valet getdist la valeur plus proche contenue dans la liste cité plus haut cette a dire dans ce ca 2.5 avec fix c'est pas possible parce que il va la reduire a 2 et pas 2.5 merci
bonuscad Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 Vu le peu de nombre de valeur que tu as a proposer, je te conseille de passer par (getkword)En plus de cette manière tu pourras choisir directement ta valeur dans le menu contextuel (click-droit) ou valider la valeur par défaut proposée (ici 4.5, on peut en mettre une autre) Voici un exemple: ((lambda ( / old_shmnu val) (setq old_shmnu (getvar "SHORTCUTMENU")) (setvar "SHORTCUTMENU" 11) (initget "2 2.5 3 3.5 4 4.5 5 5.5") (setq val (getkword "\nValeur de la section du pont [2/2.5/3/3.5/4/4.5/5/5.5]? < 4.5 >: ")) (if (not val) (setq val 4.5) (setq val (atof val))) (setvar "SHORTCUTMENU" old_shmnu) (princ "\nLa largeur de la section est de ") (princ val) (prin1) )) Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
Tramber Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 (setq li1 '(2 2.5 3 3.5 4 4.5 5 5.5 )) ; application de la soustraction à toutes les valeurs, et valeur absolue, puis classement avec vl-sort-i (setq lisclassee(vl-sort-i (mapcar '(lambda(x)(abs(- x 2.62))) li1) '; la première valeur correspond à l'index dans la liste, donc : (nth(car lisclassee) li1) ; donne la valeur la plus proche Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
Invité ingoenius Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 ma'heureusement j'ai beaucoup plus de valeurs, j'avais posté seulement une petite partie de la liste, sisons que j'ai une liste qui va de 2.0 a 55.0 par ecart de 0.5 ex 2.0 2.5 3.0 3.5 .......... e que je veux che a partir de getdist exemple 35.44 autolisp me retourn la valeur plus proche qui est dan la liste , dans ce cas 35.5 .....j'avais fait cela en python avec for etc etc mais en lisp je trouve pas meme une fonctions d'arrondissement de la distance par 0.5 en 0.5 serait la bienvenue ;-)
Invité ingoenius Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 j'ai assaye avec ta fonction mapcar, mais c'et pas encore ca parce que ex avec 2.62 il arrondi a 2 et pas a 2.5 comme le devrait ;-( il y a pas une fonction de arrondir avec ecart chosi??
Tramber Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 Je regrette mes bouts de code marchent très bien. Poste au moins ta routine pour qu'on puisse la modifier. Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
Invité ingoenius Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 alors c'est moi qui doit avoir commis un erreur (setq DIAMETRE (getdist "\nDiametre ?\n")); dimensioni utilizzatore (setq li1 '(2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8 8.5 9 9.5 10 10.5 11 11.5 12 12.5 13 13.5 14 14.5 15 15.5 16)) ; application de la soustraction à toutes les valeurs, et valeur absolue, puis classement avec vl-sort-i (setq lisclassee(vl-sort-i (mapcar '(lambda(x)(abs(- x DIAMETRE))) li1) '<)) ; la première valeur correspond à l'index dans la liste, donc : (nth(car lisclassee) li1) (setq DIAMETRE li1) je peut etre fait erreur a l'applique, merci pour l'aide le but est d'avoir dans DIAMETRE la bonne valeur ;-)
bonuscad Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 Et ceci te conviendrais mieux? ((lambda ( / prec val) (defun round_number (xr n / ) (* (fix (atof (rtos (* xr n) 2 0))) (/ 1.0 n)) ) (setq prec (/ 1 0.5)) (initget 7) (setq val 60.0) (while (> val 55.0) (setq val (getdist "\nLargeur de la section?: ")) (setq val (round_number val prec)) (if (> val 55.0) (progn (princ "\nLargeur trop importante, doit être inférieur à 55 maxi!") (initget 7) ) ) ) (princ "\nLa largeur de la section est de ") (princ val) (prin1) )) Copie-colle directement en ligne de commande pour essayer NB:(setq prec (/ 1 0.5)) 0.5 représente la valeur d'arrondi que l'on souhaite, tu peut mettre 0.25 pour arondir à tous les quarts d'unité [Edité le 4/4/2006 par bonuscad] Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
Invité ingoenius Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 trés bien maintenat'cest ok je aprés recuperé la valeur de val a l'exterieur de lambda en l'enlevant de parenteses au debut du codeet en la mettant comme variable globale et pas locale c'est correct comme demarche??
Tramber Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 je peut etre fait erreur a l'applique, merci pour l'aide le but est d'avoir dans DIAMETRE la bonne valeur ;-) (setq DIAMETRE (nth(car lisclassee) li1)) est mieux Je précise, sans avoir el temps de regarder plus en avant, que je ne comprends pas le rapport de tes routines, Bonus !? *****Je rectifie, maintenant je comprends que la liste de valeurs possibles est limitée. Ce qui n'était pas précisé au début du sujet. Hop, je replonge dans mon boulot. [Edité le 4/4/2006 par Tramber] [Edité le 4/4/2006 par Tramber] Bureau d'études dessin. Spécialiste Escaliers Développement - Formation ./__\. (.°=°.)
Invité ingoenius Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 Tu merites une explications, c'est une routine qui a partire d'une librerie de blocs 3d (ce sont des blocs pour assembler des pont lumiere en rond , a former des cercles ) donc les diametres possibles sont de nombre finit et selon le diametre choisi il faut insere le bloc correct et cree le resaux polaire correspondant (qui est constitue de 4 8 16 ou 24 element selon le diametre ) il faut nien entendu' que la librerie des bloc soit danl le parcorus donc la routine finale me donnera cerce , insere les diametre, et ensuite il insere tout ce qu'il faut (defun C:CERCE () ;insere les bloc de en H30V Triangulaire a former une cerce selon le diametre choisi (setq DTR (/ PI 180)) ;fattore di moltiplicazione x gradi verso radianti pi é Pi greco! (setq DESTRA (* 0 DTR)) ;traduzione del comando polar (setq SINISTRA (* 180 DTR)) ;traduzione del comando polar (setq SU (* 90 DTR)) ;traduzione del comando polar (setq GIU (* 270 DTR)) ;traduzione del comando polar (setq DIAG (* 45 DTR)) ;traduzione del comando polar x 45 gradi (SETQ OSN (GETVAR "OSMODE")) ;salva gli snap (SETVAR "OSMODE" 3) ;salva gli snap ;----------------------------- ;(setq DIAMETRE (getdist "\nDiametre ?\n")); dimensioni utilizzatore ;recuperato sul forum cadxp ((lambda ( / prec) (defun round_number (xr n / ) (* (fix (atof (rtos (* xr n) 2 0))) (/ 1.0 n)) ) (setq prec (/ 1 0.5)) (initget 7) (setq val 60.0) (while (> val 16.0) (setq val (getdist "\Diametre?: ")) (setq val (round_number val prec)) (if (> val 16.0) (progn (princ "\nDiametre trop importante, doit être inférieur à 16 maxi!") (initget 7) ) ) ) (princ "\nLe Diametre est de ") (princ val) (prin1) )) (setq DIAMETRE val) (setq P0 (getpoint "\nSelectionner un Point pour le Centre ? ")) (setvar "osmode" 0) ;________________________CONDITION POSSIBLES_______________________________________________________ (cond ((= DIAMETRE 2.0) (setq Blocco "H30D-R100-A090-3D") (setq N 4) );fine COND 01 ((= DIAMETRE 2.5) (setq Blocco "H30D-R125-A090-3D") (setq N 4) );fine COND 01 ((= DIAMETRE 3.0) (setq Blocco "H30D-R150-A090-3D") (setq N 4) );fine COND 01 ((= DIAMETRE 3.5) (setq Blocco "H30D-R175-A090-3D") (setq N 4) );fine COND 01 ((= DIAMETRE 4.0) (setq Blocco "H30D-R200-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 4.5) (setq Blocco "H30D-R225-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 5.0) (setq Blocco "H30D-R250-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 5.5) (setq Blocco "H30D-R275-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 6.0) (setq Blocco "H30D-R300-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 6.5) (setq Blocco "H30D-R325-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 7.0) (setq Blocco "H30D-R350-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 7.5) (setq Blocco "H30D-R375-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 8.0) (setq Blocco "H30D-R400-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 8.5) (setq Blocco "H30D-R425-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 9.0) (setq Blocco "H30D-R450-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 9.5) (setq Blocco "H30D-R475-A045-3D") (setq N 8) );fine COND 01 ((= DIAMETRE 10.0) (setq Blocco "H30D-R500-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 10.5) (setq Blocco "H30D-R525-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 11.0) (setq Blocco "H30D-R550-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 11.5) (setq Blocco "H30D-R575-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 12.0) (setq Blocco "H30D-R600-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 12.5) (setq Blocco "H30D-R625-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 13.0) (setq Blocco "H30D-R650-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 13.5) (setq Blocco "H30D-R675-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 14.0) (setq Blocco "H30D-R700-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 14.5) (setq Blocco "H30D-R725-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 15.0) (setq Blocco "H30D-R750-A022_5-3D") (setq N 16) );fine COND 01 ((= DIAMETRE 15.5) (setq Blocco "H30D-R775-A022_5-3D");errore prolite l'angolo é 15 gradi (setq N 24) );fine COND 01 ((= DIAMETRE 16.0) (setq Blocco "H30D-R800-A022_5-3D");errore prolite l'angolo é 15 gradi (setq N 24) );fine COND 01 );fine tutte le cond (command "_insert" Blocco P0 "" "" "") ;inserisce il primo blocco in P0 (setq OB2 (entlast)) ;salva la selezione (command "_array" OB2 "" "p" P0 N "" "" ) );fine script
bonuscad Posté(e) le 4 avril 2006 Posté(e) le 4 avril 2006 Je pense que tu devrais présenter ton code comme ceci. ((lambda...)) ne servait que pour le test. Et IMPORTANT, pense à déclarer tes variables en globale NB:Juste l'extrait essentiel (defun C:CERCE ( / DRT DESTRA SINISTRA SU GIU DIAG OSN DIAMETRE P0) ;....ET LES AUTRES ;insere les bloc de en H30V Triangulaire a former une cerce selon le diametre choisi(defun round_number (xr n / )(* (fix (atof (rtos (* xr n) 2 0))) (/ 1.0 n)))(setq DTR (/ PI 180)) ;fattore di moltiplicazione x gradi verso radianti pi é Pi greco!(setq DESTRA (* 0 DTR)) ;traduzione del comando polar(setq SINISTRA (* 180 DTR)) ;traduzione del comando polar(setq SU (* 90 DTR)) ;traduzione del comando polar(setq GIU (* 270 DTR)) ;traduzione del comando polar(setq DIAG (* 45 DTR)) ;traduzione del comando polar x 45 gradi (SETQ OSN (GETVAR "OSMODE")) ;salva gli snap (SETVAR "OSMODE" 3) ;salva gli snap;-----------------------------(initget 7)(setq DIAMETRE 60.0)(while (> DIAMETRE 16.0)(setq DIAMETRE (getdist "\Diametre?: "))(setq DIAMETRE (round_number DIAMETRE (/ 1 0.5)))(if (> DIAMETRE 16.0)(progn(princ "\nDiametre trop importante, doit être inférieur à 16 maxi!")(initget 7))))(setq P0 (getpoint "\nSelectionner un Point pour le Centre ? "))(setvar "osmode" 0) ;________________________CONDITION POSSIBLES_____ Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
Invité ingoenius Posté(e) le 5 avril 2006 Posté(e) le 5 avril 2006 merci pour les aides, mais j'ai une question pourquoi est il important de mettre les variables en globale?
bonuscad Posté(e) le 5 avril 2006 Posté(e) le 5 avril 2006 IMPORTANt J'ai exagéré le terme, disons que c'est une bonne habitude à prendre. En déclarant celles-ci, lors de l'achévement de ta routine, elles seront remise à "nil" (rien, vide), ca fait plus propre! Imagine que tu ais des variables stockant des listes de données énormes, si elles ne sont pas déclarées, elles vont rester présentes en mémoire pendant toutes la session de ton dessin. par exemple au message commande tapes !DIAMETRE la valeur te sera retourné même si ta routine est achevée. Pour peu que tu utilises (append ou (cons pour rajouter des éléments à une variable, et bien ta liste risque de s'allonger à chaque utilisation (et créer des bugs) Et puis lors de l'execution cela peut éviter des surprises: Tiens mon code que je suis en train de construire fonctionnait bien hier mais me retourne un message d'erreur aujourd'hui. Cause hier la variable était en mémoire pendant les tests aujourd'hui elle est à "nil" et cause un message ; erreur: type d'argument incorrect: numberp: nil par exemple. Mais il peut être interressant de garder une variable en mémoire pour éviter de demander celle-ci à chaque fois. Ex:(if (not diametre) (setq diametre (getdist))) Dans ce cas le diamètre te sera demandé lors de la 1ere utilisation de la routine, mais lors de nouvelles execution (pendant la même session) elle ne sera plus demandée. [Edité le 5/4/2006 par bonuscad] Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
(gile) Posté(e) le 5 avril 2006 Posté(e) le 5 avril 2006 Petite précision, il me semble qu'on parle de variables globales quand elles ne sont pas déclarées (et conservent leurs valeurs pendant toutes la session du dessin) et de variables locales pour les variables déclarées. De plus amples expilcations, en anglais, dans Aide aux dévellopeurs -> AutoLISP Developer's Guide ->Using the AutoLISP Language -> AutoLISP Basics -> Symbol and Function Handling -> Local Variables in Functions -> Local Variables versus Global Variables et, en français dans le Didactitiel AutoLISP -> Utilisation des outils de débogage Visual LISP -> Différenciation entre les variables locales et les variables globales Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant