(gile) Posté(e) le 29 juillet 2022 Posté(e) le 29 juillet 2022 Salut, Je propose un challenge pour l'été (profiter des vacances pour apprendre ou se perfectionner en LISP). Tout le monde a entendu parler de la suite de Fibonacci. Une spirale de Fibonacci est une succession d'arcs de cercle de 90° connectés tangentiellement dont les rayons sont les termes de la suite de Fibonacci. Un exemple de spirale de Finonacci composée de 7 arcs : Challenge Il s'agit d'écrire une routine qui prend en argument le point de départ de la spirale et le nombre d'arcs pour dessiner la spirale dans AutoCAD (plusieurs arcs ou une polyligne). La routine (ici nommée spiralFib) devra pouvoir être appelée depuis une commande LISP (ici nommée c:TEST) pour pouvoir être testée dans AutoCAD pour dessiner des spirales ayant au minimum 4 arcs. (defun c:test (/ p i) (and (setq p (getpoint "\nPoint de départ: ")) (setq i (getint "\nNombre d'arcs [4-32]: ")) (< 3 i) (spiralFib p i) ) (princ) ) Un screencast montrant un exemple. Variante On peut, sur le même principe faire une routine pour une "Spirale d'or". 1 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 29 juillet 2022 Posté(e) le 29 juillet 2022 Génial, je n'ai pas d'AutoCAD Full sous la main actuellement, donc je devrais pas être en mesure de proposer quelque chose de suite (pas avant une bonne semaine), mais dès que c'est possible je tenterai un truc, ne serait ce que pour valider les 2 à 3 petites idées qui me viennent en tête à la lecture de l'énoncé :) 1 Apprendre => Prendre => Rendre
Luna Posté(e) le 29 juillet 2022 Posté(e) le 29 juillet 2022 Se serait avec plaisir de participer (de même que le challenge des cercles magiques) mais je manque cruellement de temps en ce moment. Donc je vais devoir passer malheureusement.. Bisous, Luna 1
(gile) Posté(e) le 29 juillet 2022 Auteur Posté(e) le 29 juillet 2022 Il n'y a aucune urgence à répondre et je pense qu'il y a de la place pour de nombreuses réponses différentes. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 30 juillet 2022 Posté(e) le 30 juillet 2022 Bonjour Merci @(gile) de nous faire des devoirs de vacances. Tu crois qu'on n'a pas assez de ceux des petits-enfants qu'il faut corriger, passer au correcteur, rajouter des S pour les pluriels et autres joyeusetés qu'on subit quand on a 9 ans ? Blague à part, j'aime ce qui est beau et il se trouve que cette suite est belle et que la spirale résultante l'est tout autant. Donc, je me m'inscris sur la liste des participants, maintenant, il va falloir ménager du temps entre les siestes et les cahiers de vacances... Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
didier Posté(e) le 30 juillet 2022 Posté(e) le 30 juillet 2022 Coucou Je suis prêt. Je temporise quelque peu pour répondre. Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 1 août 2022 Auteur Posté(e) le 1 août 2022 Ceux qui auraient déjà fini leur devoirs (et qui s'ennuient) peuvent se pencher sur la variante "Spirale d'or". Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 1 août 2022 Posté(e) le 1 août 2022 C'est bon pour moi aussi, j'ai emprunté le poste de travail d'un collègue équipé d'un AutoCAD full, pendant la pause déjeuné. Apprendre => Prendre => Rendre
VDH-Bruno Posté(e) le 3 août 2022 Posté(e) le 3 août 2022 Le 01/08/2022 à 10:47, (gile) a dit : Ceux qui auraient déjà fini leur devoirs (et qui s'ennuient) peuvent se pencher sur la variante "Spirale d'or". Bonjour (gile) Juste une petite précision dans la modélisation pour le premier rayon de la Spirale d'or (qui est infini), tu pars sur une valeur de 1 (comme pour la spirale de Bonifacci)? La petite précision est utile, pour pouvoir superposer aisément les Spirales au moment de la correction 😉. Autre précision lorsque je lis ceci dans le lien sur Wikipédia : Citation En géométrie, une spirale d'or est une spirale logarithmique avec un facteur de croissance de {\displaystyle \varphi ={\frac {1+{\sqrt {5}}}{2}}\simeq 1,618}, appelé nombre d'or.1 Une spirale d'or devient plus large par un facteur de φ pour chaque quart de tour qu'elle fait. L'assertion suivant me dérange "une spirale d'or est une spirale logarithmique", car une spirale logarithmique est une spirale de croissance continue, ce que n'est pas la spirale d'or qui a un facteur de croissance à chaque quart de tour. Ouf heureusement que c'est précisé à la fin de la phrase, pour invalider l'assertion de départ... A+ Bruno Apprendre => Prendre => Rendre
(gile) Posté(e) le 3 août 2022 Auteur Posté(e) le 3 août 2022 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 3 août 2022 Posté(e) le 3 août 2022 Bonsoir, Bientôt en vacances donc j'ouvre le bal: Spirale Bonifacci (version polyligne) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Spirale Fibonacci ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun spiralFib (p i / make_courbe tan) (defun tan (ang) (/ (sin ang) (cos ang))) (defun make_courbe (dxf42 p ang corde1 corde2 i) (if (>= i 0) (cons (cons 10 p) (cons dxf42 (make_courbe dxf42 (polar p ang corde1) (+ ang (* 0.5 pi)) corde2 (+ corde1 corde2) (1- i)) ) ) ) ) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 i) ) (make_courbe (cons 42 (tan (* 0.125 pi))) p (* 0.25 pi) (sqrt 2) (sqrt 2) i) ) ) ) La variante Spirale d'Or (version polyligne) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Spirale d'Or ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun spiralOr (p i / make_courbe tan) (defun tan (ang) (/ (sin ang) (cos ang))) (defun make_courbe (dxf42 p ang corde phi i) (if (>= i 0) (cons (cons 10 p) (cons dxf42 (make_courbe dxf42 (polar p ang corde) (+ ang (* 0.5 pi)) (* corde phi) phi (1- i))) ) ) ) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 i) ) (make_courbe (cons 42 (tan (* 0.125 pi))) p (* 0.75 pi) (sqrt 2) (/ (1+ (sqrt 5)) 2.) i) ) ) ) Salutations Bruno Apprendre => Prendre => Rendre
VDH-Bruno Posté(e) le 3 août 2022 Posté(e) le 3 août 2022 Re, Et pour proposer autre chose, très rapidement une variante de la Spirale Bonifacci (version arc de cercle) (defun SpiralFib (p i / sFib cen ang) (defun make_arc (cen ray angdep angfin) (entmakex (list '(0 . "ARC") (cons 10 cen) (cons 40 ray) (cons 50 angdep) (cons 51 angfin) ) ) ) (setq sFib '(1 1) ang (/ pi 2) cen (polar p (/ pi 2) 1.) ) (make_arc cen 1. (- ang) 0.) (make_arc cen 1. 0. ang) (repeat (- i 2) (setq cen (polar cen (+ ang pi) (cadr sFib)) sFib (cons (+ (car sFib) (cadr sFib)) sFib) ) (make_arc cen (car sFib) ang (setq ang (+ ang (/ pi 2)))) ) ) Apprendre => Prendre => Rendre
(gile) Posté(e) le 4 août 2022 Auteur Posté(e) le 4 août 2022 Super. Des routine dans un style fonctionnel, on n'en attendait pas moins de toi. Tu pars en vacances en Corse ? Ça expliquerait Bonifacci(o) en lieu de Fibonacci. J'attends que d'autres postent des réponse pour voir si je peux proposer quelque chose de différent. 1 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 4 août 2022 Posté(e) le 4 août 2022 il y a 54 minutes, (gile) a dit : Tu pars en vacances en Corse ? Ça expliquerait Bonifacci(o) en lieu de Fibonacci. 😂😂😂 Excellent!!! Non Bretagne, c'est moins loin pour moi et j'ai pas trop envie de traverser toute la France, mais si un jour j'y vais, je m'organiserais pour faire étape à Marseille😉 Apprendre => Prendre => Rendre
didier Posté(e) le 4 août 2022 Posté(e) le 4 août 2022 Bonjour. À mon tour de proposer mes routines, pas toujours dans l'académique, mais ça fait le job. J'ai respecté la demande initiale de faire un testFIB et un testGOLD Fibonacci : (defun spiralfib ( cen nb / b dir li li2 n p pol rac2) (setvar "cmdecho" 0) (defun suitefib (nb) (setq li '(1 0)) (repeat nb (setq li (cons (+ (car li) (cadr li)) li)) ) (reverse li) ) ;(setq li2 '()) (setq li (cdr (suitefib nb))) (setq dir (/ pi 4) rac2 (sqrt 2.0) ) (setq li2 (cons (list (+ (car cen) 1)(cadr cen)) li2)) (foreach ele li (setq li2 (cons (polar (car li2) (setq dir (+ dir (/ pi 2))) (* rac2 ele)) li2)) ) (setq b (/ (sin (/ pi 8))(cos (/ pi 8)))) (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 38 0) (cons 90 (length li2)) (cons 70 0) (cons 62 1) ) (mapcar '(lambda (p) (cons 10 p)) li2) );_ Fin de append ) ;_ Fin de entmake (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 38 0) (cons 90 (length li2)) (cons 70 0)(cons 62 6) ) (mapcar '(lambda (p) (cons 10 p)) li2) );_ Fin de append ) (setq n -1) (setq pol (vlax-ename->vla-object (entlast))) (repeat (cdr (assoc 90 (entget (entlast)))) (vla-SetBulge pol (setq n (1+ n)) -0.414214) ) (vla-Update pol) (setq n 0) (setq li22 (reverse li2)) (setq oldosmode (getvar 'osmode)) (setvar "osmode" 0) (repeat (length li2) (command "_rectang" (nth n li2) (nth (1+ n) li2)) (setq n (+ 1 n)) ) (setvar "osmode" oldosmode) (setq li2 (reverse li2)) ) (defun c:testfib (/ p i) (and (setq p (getpoint "\nPoint de départ: ")) (setq i (getint "\nNombre d'arcs [4-32]: ")) (and (< 3 i)(< i 33)) (spiralFib p i) ) (princ) ) Et maintenant Spirale d'Or (ne faites pas de bruit, la spirale dort) (defun spiralgold ( cen nb / gold b dir li li2 n p pol rac2) (setvar "cmdecho" 0) (setq li '(1)) (setq gold (/ ( + 1 (sqrt 5)) 2)) (repeat nb (setq li (cons (* (car li) gold) li)) ) (setq li (reverse li)) (setq dir (/ pi 4) rac2 (sqrt 2.0) ) (setq li2 (cons (list (+ (car cen) 1)(cadr cen)) li2)) (foreach ele li (setq li2 (cons (polar (car li2) (setq dir (+ dir (/ pi 2))) (* rac2 ele)) li2)) ) (setq b (* (/ (sin (/ pi 8))(cos (/ pi 8)))-1)) (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 38 0) (cons 90 (length li2)) (cons 70 0) (cons 62 1) ) (mapcar '(lambda (p) (cons 10 p)) li2) );_ Fin de append ) ;_ Fin de entmake (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 38 0) (cons 90 (length li2)) (cons 70 0)(cons 62 2) ) (mapcar '(lambda (p) (cons 10 p)) li2) );_ Fin de append ) (setq n -1) (setq pol (vlax-ename->vla-object (entlast))) (repeat (cdr (assoc 90 (entget (entlast)))) (vla-SetBulge pol (setq n (1+ n)) b) ) (vla-Update pol) (setq n 0) (setq li22 (reverse li2)) (setq oldosmode (getvar 'osmode)) (setvar "osmode" 0) (repeat (length li2) (command "_rectang" (nth n li2) (nth (1+ n) li2)) (setq n (+ 1 n)) ) (setvar "osmode" oldosmode) (setq li2 (reverse li2)) ) Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 4 août 2022 Auteur Posté(e) le 4 août 2022 @didier La routine spiralfib génère un arc de plus que demandé, sinon, "elle fait le job", même plus. La routine spiralgold plante, et même après correction du nom d'une variable, "elle ne fait pas le job". Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 4 août 2022 Posté(e) le 4 août 2022 Bonjour @(gile) oops ! je suis une triple buse !!! Une modif de dernière minute qui fût fatale !! Désolé du dérangement, j'ai corrigé le code dans le message de réponse. Je n'ai corrigé que la GOLD, l'arc de trop dans la Fibonacci n'est pas encore corrigé. Est-ce que ça fonctionne mieux maintenant ? Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 4 août 2022 Auteur Posté(e) le 4 août 2022 Pour la spirale de Fibonacci, on avait le choix entre dessiner une polyligne ou des arcs. Jusque là, il semble que la polyligne ait eu un peu plus de succès. Ensuite, on peut adopter un style fonctionnel avec une fonction auxiliaire récursive (comme à fait @VDH-Bruno) ou un style plus impératif avec la fonction repeat (comme a fait @didier) Pour donner quelque chose d'un peu différent des précédentes réponses, je voudrais juste montrer comment on peut calculer les sommets de la polyligne sans utiliser la fonction polar. Dans les routines suivantes, les variables ou arguments n et m stockent deux termes consécutifs de la suite de Fibonacci, les variables ou arguments x et y stockent les signes (+1 ou -1) utilisés pour déplacer le sommet. Style fonctionnel: (defun fibSpiral (p i / loop b) (setq b (- (sqrt 2.) 1.)) (defun loop (i p n m x y) (vl-list* (cons 10 p) (cons 42 b) (if (< 0 i) (loop (1- i) (mapcar '+ p (list (* x m) (* y m))) m (+ n m) (- y) x ) ) ) ) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (+ i 1)) ) (loop i p 0 1 -1 1) ) ) ) Style impératif: (defun fibSpiral (p i / b x y n m l) (setq b (- (sqrt 2.) 1.) n 0 m 1 x -1 y 1 ) (repeat (setq i (1+ i)) (setq l (cons (cons 42 b) (cons (cons 10 p) l)) p (mapcar '+ p (list (* x m) (* y m))) ) (mapcar 'set '(n m x y) (list m (+ n m) (- y) x)) ) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 i) ) (reverse l) ) ) ) Toutes les précédentes réponses utilisent entmake(x) pour créer la polyligne, je ne peux pas résister à poster un exemple (plus concis) avec command: (defun fibSpiral (p i / b x y n m) (setq b (- (sqrt 2.) 1.) n 0 m 1 x -1 y 1 ) (command "_.pline" "_non" p "_arc" "_direction" (mapcar '+ p '(0. 1.))) (repeat i (command "_non" (setq p (mapcar '+ p (list (* x m) (* y m))))) (mapcar 'set '(n m x y) (list m (+ n m) (- y) x)) ) (command "") ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 4 août 2022 Auteur Posté(e) le 4 août 2022 il y a 6 minutes, didier a dit : Je n'ai corrigé que la GOLD, l'arc de trop dans la Fibonacci n'est pas encore corrigé. Est-ce que ça fonctionne mieux maintenant ? Ça fonctionne (toujours avec un arc de trop) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
didier Posté(e) le 4 août 2022 Posté(e) le 4 août 2022 Bonjour @(gile) Merci d'avoir testé, maintenant tout doit être OK, car j'ai corrigé l'arc superflu. Merci aussi pour les explications concernant tes versions. On sait que ça existe, tu en es la preuve, mais je n'ai pas le niveau pour "penser" comme ça. Je cherche encore à m'améliorer, mais je pense avoir atteint un palier. Amicalement Éternel débutant... Mon site perso : Programmer dans AutoCAD
(gile) Posté(e) le 4 août 2022 Auteur Posté(e) le 4 août 2022 Avec des arcs: (defun spiralFib (p i / loop a) (defun loop (i c n m s e x y) (entmake (mapcar 'cons '(0 10 40 50 51) (list "ARC" c m s e))) (if (< 1 i) (loop (1- i) (mapcar '+ c (list (* x n) (* y n))) m (+ n m) e (+ e a) (- y) x) ) ) (setq a (* 0.5 pi)) (loop i (mapcar '+ p '(-1. 0.)) 0. 1. 0. a 0. -1.) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 4 août 2022 Auteur Posté(e) le 4 août 2022 Pour la spirale d'or, on peut, comme l'ont fait Bruno et Didier, multiplier le terme précédent par le nombre d'or pour obtenir le suivant, mais ce qui caractérise le nombre d'or, c'est qu'on peut aussi obtenir le terme suivant avec la somme des deux termes précédents, comme avec la suite de Fibonacci. D'ailleurs le rapport entre deux termes successifs de la suite de Fibonacci tend vers le nombre d'or quand cette suite tend vers l'infini. On peut donc reprendre une des routines ayant servi à la suite de Fibonacci en remplaçant les deux premiers termes (0 et 1) par 1 et le nombre d'or. Style fonctionnel : (defun goldenSpiral (p i / loop b) (setq b (- (sqrt 2.) 1.)) (defun loop (i p n m x y) (vl-list* (cons 10 p) (cons 42 b) (if (< 0 i) (loop (1- i) (mapcar '+ p (list (* x n) (* y n))) m (+ n m) (- y) x ) ) ) ) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (+ i 1)) ) (loop i p 1 (+ (sqrt 1.25) 0.5) -1 1) ) ) ) Impératif : (defun goldenSpiral (p i / b x y n m l) (setq b (- (sqrt 2.) 1.) n 1. m (+ (sqrt 1.25) 0.5) x -1. y 1. ) (repeat (setq i (1+ i)) (setq l (cons (cons 42 b) (cons (cons 10 p) l)) p (mapcar '+ p (list (* x n) (* y n))) ) (mapcar 'set '(n m x y) (list m (+ n m) (- y) x)) ) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 i) ) (reverse l) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 4 août 2022 Posté(e) le 4 août 2022 Il y a 11 heures, (gile) a dit : mais ce qui caractérise le nombre d'or, c'est qu'on peut aussi obtenir le terme suivant avec la somme des deux termes précédents, comme avec la suite de Fibonacci. Merci je prends, j'étais passé à coté de cette propriété. Joli codes comme toujours 🙂 Apprendre => Prendre => Rendre
bonuscad Posté(e) le 5 août 2022 Posté(e) le 5 août 2022 Alors la spirale d'or à ma façon (moins gracieux que Gilles et Bruno), mais j'ai essayé d'éviter la trigonométrie, juste de l'arithmétique. (defun c:test ( / phi l_r cnt opx opy l) (setq phi (* (1+ (sqrt 5)) 0.5) l_r '(1.0) cnt 0 ) (initget 7) (repeat (getint "\nNombre de répétion?: ") (setq l_r (cons (expt phi (setq cnt (1+ cnt))) l_r)) ) (setq l_r (reverse l_r) cnt 0 l '((1.0 0.0))) (while l_r (cond ((zerop cnt) (setq opx - opy +)) ((zerop (rem cnt 4)) (setq opx - opy + cnt 0)) ((zerop (rem cnt 3)) (setq opx + opy +)) ((zerop (rem cnt 2)) (setq opx + opy -)) ((zerop (rem cnt 1)) (setq opx - opy -)) ) (setq l (cons (list ((eval opx) (caar l) (car l_r)) ((eval opy) (cadar l) (car l_r))) l) l_r (cdr l_r) cnt (1+ cnt) ) ) (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length l)) (cons 70 0) ) (apply 'append (mapcar (function (lambda (x) (list (cons 10 x) (cons 42 (1- (sqrt 2))) ) ) ) (reverse l) ) ) ) ) ) Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
(gile) Posté(e) le 5 août 2022 Auteur Posté(e) le 5 août 2022 @bonuscad Super, une nouvelle approche. Comme je disais plus haut, la caractéristique du nombre d'or, c'est qu'il permet de générer une suite géométrique : Un+1 = Un * phi qui est aussi une suite de type Fibonacci : Un+2 = Un+1 + Un. Autrement dit, avec n0 = 1, n+1 = phi, on a n+2 = phi * phi ou n+2 = 1 + phi Ce qui permet de simplifier le calcul en remplaçant les appels à la fonction expt par de simples additions. (setq phi (* (1+ (sqrt 5)) 0.5) l_r '(1.0) cnt 0 ) (initget 7) (repeat (getint "\nNombre de répétion?: ") (setq l_r (cons (expt phi (setq cnt (1+ cnt))) l_r)) ) par (setq l_r (list (* (1+ (sqrt 5)) 0.5) 1.0)) (initget 7) (repeat (1- (getint "\nNombre de répétion?: ")) (setq l_r (cons (+ (car l_r) (cadr l_r)) l_r)) ) 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