Copia con Rotazione (e traslazione)

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
Giuro non è pigrizia, ma magari per qualcuno che ha la geometria in testa è cosa da un quarto d'ora... per me sarebbero due giorni di lavoro (almeno)
Problema (gradita risposta anche solo per la routine sul semplice punto) :
Prendere una superficie 3D, costituita da 3DFACEs
articolate su un piano, faccio esempio, una porzione di porfido a cubetti con relative fughe incise .....
e ...........
ruotare/traslare ogni faccia attorno a un cilindro, creando come un timbro 3D che lavorerà a rotazione (tipo rullo da tappezziere).
Dato che il risultato deve essere modulare e ripetitivo occorre che la lunghezza della superficie sia pari al diametro del cilindro * Pigreco.
Liberi di insultarmi, capisco che chiedo molto :)
Lo scopo è creare "timbri" da modellismo per realizzare superfici 3D su materiali malleabili posti in piano.
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
dimenticavo... in lisp puro, non sono attrezzato per vba e simili
ho cominciato a sviluppare sul punto nel modo più elementare e classico, trovo la lunghezza dell'arco formato dalla rotazione del punto (che è il suo spiazzamento X sul piano su cui giace il disegno), il cui angolo mi porta al seno e al coseno, che saranno rispettivamente la Z e la X del nuovo punto creato (la Y non cambia, dato che l'asse del cilindro ha il vettore 0,1,0)...
spero di essermi avviato giusto ...
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
un'oretta ieri e mezz'ora oggi.. tutto sbagliato ma equivale al classico "hello world" sullo screen ahahah
Dunque, per iniziare ho usato semplici linee, in un quadro sul quadrante positivo (orig. 0,0,0) lato = Pi
Ho dato il comando e, supponevo, nonle ha fatte ruotare sul cilindro, ma sul suo SPICCHIO a 90 gradi
(vedere sviluppo sequenza.. 1 rosso era l'originale, 1 nero la linea creata)
Intanto riposo e lo lascio decantare, poi lo riprendo in mano, ma con 3DFACE sparse, che diventa più leggibile.
Chiaro che è tutto sbagliato, non considera i valori quadrante negativi... e non ho la più pallida idea (per ora) del perché abbia concentrato tutto su uno spicchio di 90 gradi... ma le (false proporzioni) e ricorrenze, ci sono.
Immagine.JPG
Codice:
(defun HPRINT()
 (setq selez nil)
 (setq selez(ssget))
 (if (/= selez nil)
  (progn
        (setq l(sslength selez))
        (setq l(1- l))
        (setq na 0)
        (while(<= na l)
               (setq ename(ssname selez na))
               (setq alist(entget ename))
               (if(= "LINE"(cdr(assoc 0 alist)))
                   (progn
                     (setq A(cdr(assoc 10 alist)))
                     (setq B(cdr(assoc 11 alist)))
       (setq Ax (car A) Ay (cadr A) Az (caddr A))
       (setq Bx (car B) By (cadr B) Bz (caddr B))
                      ; assunto a pi lo sviluppo del nastro da avvolgere, in modo che il D cilindro sia 1
                      ;3,1415926535
                      (setq AngRadA (/ Ax pi))
                      (setq AngRadB (/ Bx pi))

                      (setq newAz (sin AngRadA))
                      (setq newAx (cos AngRadA))
                      (setq newAy Ay) ;solo per leggibilità

                      (setq newBz (sin AngRadB))
                      (setq newBx (cos AngRadB))
                      (setq newBy By) ;solo per leggibilità

                      (setq newA   (list  newAx newAy newAz) )
                      (setq newB   (list newBx newBy newBz) )
                      (command "LINE" newA newB "")
                   )
                ) ;endif
               (setq na(1+ na))
         )
    )
  )
)
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
mi sto avvicinando, codice riscritto un po' a naso senza capire bene cosa stia facendo.
Però funziona, ma con un obbligo che mi piacerebbe rimuovere.
Il "nastro", ossia la lunghezza della pianta, costruita a 3DFACE, che deve ruotare formando esattamente un rullo, con questo codice, deve essere lunga esattamente (PI * Pi * 2) ossia quasi 20.
Lo vorrei a dimensioni libere, anche se per il mio scopo va bene lo stesso.
Ossia mi piacerebbbe che qualsiasi impianto si avvolgesse formando il suo corrispondente anello chiuso.

Clipboard01.jpg


Codice:
(defun HPRINT()
 (setq selez nil)
 (setq selez(ssget))
 (if (/= selez nil)
  (progn
        (setq l(sslength selez))
        (setq l(1- l))
        (setq na 0)
        (while(<= na l)
               (setq ename(ssname selez na))
               (setq alist(entget ename))
               (if(= "3DFACE"(cdr(assoc 0 alist)))
                   (progn
                       (setq A (cdr(assoc 10 alist)) B (cdr(assoc 11 alist)) C (cdr(assoc 12 alist)) D (cdr(assoc 13 alist)))

                       (setq Ax (car A) Ay (cadr A) Az (caddr A) )
                       (setq Bx (car B) By (cadr B) Bz (caddr B) )
                       (setq Cx (car C) Cy (cadr C) Cz (caddr C) )
                       (setq Dx (car D) Dy (cadr D) Dz (caddr D) )

                      ;3.1415926535
                     (setq AngRadA (/ Ax pi))
                     (setq AngRadB (/ Bx pi))
                     (setq AngRadC (/ Cx pi))
                     (setq AngRadD (/ Dx pi))


                      (setq newAz (* (sin AngRadA) pi))
                      (setq newAx (* (cos AngRadA) pi))
                      (setq newAy Ay) ;solo per leggibilità

                      (setq newBz (* (sin AngRadB) pi))
                      (setq newBx (* (cos AngRadB) pi))
                      (setq newBy By) ;solo per leggibilità

                      (setq newCz (* (sin AngRadC) pi))
                      (setq newCx (* (cos AngRadC) pi))
                      (setq newCy Cy) ;solo per leggibilità

                      (setq newDz (* (sin AngRadD) pi))
                      (setq newDx (* (cos AngRadD) pi))
                      (setq newDy Dy) ;solo per leggibilità

                      (setq newA   (list newAx newAy newAz) )
                      (setq newB   (list newBx newBy newBz) )
                      (setq newC   (list newCx newCy newCz) )
                      (setq newD   (list newDx newDy newDz) )

                      (command "3DFACE" newA newB newC newD "")
                   )
                ) ;endif
               (setq na(1+ na))
         )
    )
; 19.7392
  )
)
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
il codice di cui sopra in esercizio vero su superficie porfido (da due blocchi esplosiClipboard01.jpg)
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
Rieccomi di nuovo (avvertitemi se scoccio), ma questo lavoretto mi sta prendendo.
Non posso lasciare il vecchio codice, perché l'ho semplificato, ma soprattutto perché ho dovuto fare un fix importante. Funzionava piegando ad anello (come vedete qui nel post sopra), ma non era in grado di comprendere il rilievo del progetto. Praticamente mi creava un rullo, e ok, ma prelevando le facce dal disegno piano originale come se tutto fosse a quota zero.
Me ne sono accorto inserendo le fughe sul negativo del porfido che sto usando come test, e ho introdotto un correttivo che mi legge il modello base nelle sue tre dimensioni.
Meglio della spiegazione penso valga l'immagine.
Ora però devo aggiustare nuovamente la lunghezza del modello base se si vuole ottenere un perfetto cilindo con la rotazione completa.
Come scrivevo, NON è per ora parametrico, quindi, a mo' di reverse engineering devo trovare l'esatta lunghezza.
Comunque il nuovo codice ora è esatto, ovvero, mi legge un modello non solo bidimensionale.

Clipboard01.jpg

Clipboard02.jpg


Codice:
(defun HPRINT()
 (setq selez nil)
 (setq selez(ssget))
 (if (/= selez nil)
  (progn
        (setq l(sslength selez))
        (setq l(1- l))
        (setq na 0)
        (while(<= na l)
               (setq ename(ssname selez na))
               (setq alist(entget ename))
               (if(= "3DFACE"(cdr(assoc 0 alist)))
                   (progn
                       (setq A (cdr(assoc 10 alist)) B (cdr(assoc 11 alist)) C (cdr(assoc 12 alist)) D (cdr(assoc 13 alist)))

                       (setq Ax (car A) Ay (cadr A) Az (caddr A) )
                       (setq Bx (car B) By (cadr B) Bz (caddr B) )
                       (setq Cx (car C) Cy (cadr C) Cz (caddr C) )
                       (setq Dx (car D) Dy (cadr D) Dz (caddr D) )

                      ;3.1415926535
                     (setq AngRadA Ax)
                     (setq AngRadB Bx)
                     (setq AngRadC Cx)
                     (setq AngRadD Dx)

                      (setq Quota (- 1 Az))
                      (setq newAz (*(sin AngRadA)Quota))
                      (setq newAx (*(cos AngRadA)Quota))
                      (setq newAy Ay) ;solo per leggibilità

                      (setq Quota (- 1 Bz))
                      (setq newBz (*(sin AngRadB)Quota))
                      (setq newBx (*(cos AngRadB)Quota))
                      (setq newBy By) ;solo per leggibilità

                      (setq Quota (- 1 Cz))
                      (setq newCz (*(sin AngRadC)Quota))
                      (setq newCx (*(cos AngRadC)Quota))
                      (setq newCy Cy) ;solo per leggibilità

                      (setq Quota (- 1 Dz))
                      (setq newDz (*(sin AngRadD)Quota))
                      (setq newDx (*(cos AngRadD)Quota))
                      (setq newDy Dy) ;solo per leggibilità

                      (setq newA   (list newAx newAy newAz) )
                      (setq newB   (list newBx newBy newBz) )
                      (setq newC   (list newCx newCy newCz) )
                      (setq newD   (list newDx newDy newDz) )

                      (command "3DFACE" newA newB newC newD "")
                   )
                ) ;endif
               (setq na(1+ na))
         )
    )
; 19.7392
  )
)
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
Clipboard01.jpgRieccomi. Fine della storia, non serve aggiornare l'ultimo listato perché ha superato ogni prova.
Nel caso qualcuno volesse provarlo o servirsene fornisco le definitive indicazioni.
1) Il nastro da avvolgere, per formare poi l'esatto tamburo, deve essere lungo 2Pi sull'asse x. A piacere y e z. Il tutto posto nel quadrante positivo ( io posiziono il nastro a partire da 0,0,0).
2) Non rendo il codice parametrico perché è inutile, il cilindro risultante sarà scalabile già di suo.
3) Le incisioni volute sul tamburo sono da rilevare con Z positivo sul nastro (si avvolge verso l'alto).
4) Prima di lanciare il comando è opportuno creare un nuovo layer per il cilindro e renderlo corrente, per svincolare tra loro nastro e rullo, e poterli manipolare senza difficoltà, avendo entrambi origine 0,0,0 risulteranno parzialmente sovrapposti.
5) Il codice supporta unicamente entità 3DFACE. Altre, saranno ignorate.
 

Gio_S

Utente poco attivo
Professione: architetto
Software: IntelliCAD, SketchUp, MeshLab, PovRay, AutoLisp, Ruby SkUp, RapidQ, XBLite
Regione: Milano
Ritorno in argomento perché mi è venuto lo sfizio, diciamo la necessità, dopo aver creato un rullo, e averlo magari modificato, di riportare tutto su un 3D piano.
Molto più complicato, riportare su un foglio la topografia del cilindro.
Ho litigato un bel po' con l'arcotangente, che in LISP non c'è, imbastendo le formule, poi ho rinunciato, optando per un metodo più rustico che fa lavorare il CAD, in breve facendogli disegnare l'arco di ogni punto sul cilindro, facendomene dire la lunghezza "disteso", e riportando detta misura come valore X di spiazzamento di quel punto rispetto all'origine comune a tutti i punti.
Roba non semplice, soprattutto perché una faccia può starsene sul cilindro a cavallo tra meno di 360 gradi e più di 0 gradi, cosa che mi rende l'arco non di banale sviluppo. Da qui, i controlli; il "pure" che mi dice se una faccia è nel range 0-360 oppure no, se quindi uno o più vertici scavalcano i 360 .
Comunque attenzione, il diametro del cilindro DEVE essere obbligatoriamente 2 (raggio 1), e la sua origine, il centro della base, posta a 0,0,0. Deve essere steso come un tappeto arrotolato, ossia da 0,0,0, l'altezza del cilindro sarà posta secondo un Y positivo.
Questo è proprio perché il risultato sarà come srotolare un tappeto a cilindro sul pavimento, posto lungo l'asse Y, stendendendolo sull'asse X. Come quando lo si è creato.
Anche qui, meglio posizionarsi su un nuovo layer prima di lanciare la routine, perché la nuova forma creata non si intrecci con la prima e risulti facilmente selezionabile.
E' un "timbro", quindi è verificato solo per "incisioni" sul diametro del cilindro, che diventeranno volumi positivi posti sul tappeto. Non ho verificato cosa succeda se "dal" cilindro escano protuberanze, perché non era il mio problema. E' un "timbro continuo" 3D. Ciò che è inciso sul cilindro, risulterà in aggetto sul tappeto srotolato con la sua topografia.
Naturalmente grazie se per caso qualcuno avesse idee con un algoritmo più spiccio!

Codice:
(defun MPRINT()
  (setq selez nil)
  (setq selez(ssget))
  (if (/= selez nil)
     (progn
          (setq l(sslength selez))
          (setq l(1- l))
          (setq na 0)
          (while(<= na l)
               (setq ename(ssname selez na))
               (setq alist(entget ename))
               (if(= "3DFACE"(cdr(assoc 0 alist)))
                   (progn
                       (setq A (cdr(assoc 10 alist)) B (cdr(assoc 11 alist)) C (cdr(assoc 12 alist)) D (cdr(assoc 13 alist)))
                       (setq Ax (car A) Ay (cadr A) Az (caddr A) )
                       (setq Bx (car B) By (cadr B) Bz (caddr B) )
                       (setq Cx (car C) Cy (cadr C) Cz (caddr C) )
                       (setq Dx (car D) Dy (cadr D) Dz (caddr D) )
                       (if (or (< Az 0)(< Bz 0)(< Cz 0)(< Dz 0))   
                              (setq sud 1)
                              (setq sud 0)
                       )
                       (setq cross 0)
                       (if (< Az -0.0001)(setq cross (+ 1 cross)))
                       (if (< Bz -0.0001)(setq cross (+ 1 cross)))
                       (if (< Cz -0.0001)(setq cross (+ 1 cross)))
                       (if (< Dz -0.0001)(setq cross (+ 1 cross)))
                       (if (or (= cross 4)(= cross 0)) (setq pure 1)(setq pure 0))

;................
                      (setq newAz (- 1 (sqrt  (+  (* Ax Ax)  (* Az Az))) ))
                      (setq pointCent   (list 100 0 0) )
                      (setq pointStart   (list 101 0 0) )
                      (setq pointEnd   (list (+ 100 Ax) Az 0) )
                      (if (and (equal Ax 1 0.0001) (= sud 1))
                           (setq newAx 6.28318531)
                           (progn
                                   (command "ARC" "C" PointCent PointStart PointEnd)
                                   (setq selez2 (ssget PointStart))
                                   (setq ename2 (ssname selez2 0))
                                   (setq Nalist (entget ename2))
                                   (setq basArc (cdr(assoc 50 Nalist)))
                                   (setq endArc (cdr(assoc 51 Nalist)))
                                   (setq SvilArc (- endArc basArc))
                                   (entdel ename2)
                                   (setq newAx  SvilArc)
                           )
                      )
                      (setq newAy Ay) ;solo per leggibilità
;............

                      (setq newBz (- 1 (sqrt  (+  (* Bx Bx)  (* Bz Bz))) ))
                      (setq pointCent   (list 100 0 0) )
                      (setq pointStart   (list 101 0 0) )
                      (setq pointEnd   (list (+ 100 Bx) Bz 0) )
                      (if (and (equal Bx 1 0.0001) (= sud 1))
                           (setq newBx 6.28318531)
                             (progn
                                    (command "ARC" "C" PointCent PointStart PointEnd)
                                    (setq selez2 (ssget PointStart))
                                    (setq ename2 (ssname selez2 0))
                                    (setq Nalist(entget ename2))
                                    (setq basArc (cdr(assoc 50 Nalist)))
                                    (setq endArc (cdr(assoc 51 Nalist)))
                                    (setq SvilArc (- endArc basArc))
                                    (setq newBx SvilArc)
                                    (entdel ename2)
                            )
                       )
                       (setq newBy By) ;solo per leggibilità
;............

                      (setq  newCz (- 1 (sqrt  (+  (* Cx Cx)  (* Cz Cz))) ))
                      (setq pointCent   (list 100 0 0) )
                      (setq pointStart   (list 101 0 0) )
                      (setq pointEnd   (list (+ 100 Cx) Cz 0) )
                      (if (and (equal Cx 1 0.0001) (= sud 1))
                                 (setq newCx 6.28318531)
                                 (progn
                                      (command "ARC" "C" PointCent PointStart PointEnd)
                                      (setq selez2 (ssget PointStart))
                                      (setq ename2 (ssname selez2 0))
                                      (setq Nalist (entget ename2))
                                      (setq basArc (cdr(assoc 50 Nalist)))
                                      (setq endArc (cdr(assoc 51 Nalist)))
                                      (setq SvilArc (- endArc basArc))
                                      (setq newCx SvilArc)
                                      (entdel ename2)
                                 )
                      )
                      (setq newCy Cy) ;solo per leggibilità
;............

                      (setq  newDz (- 1 (sqrt  (+  (* Dx Dx)  (* Dz Dz))) ))
                      (setq pointCent   (list 100 0 0) )
                      (setq pointStart   (list 101 0 0) )
                      (setq pointEnd   (list (+ 100 Dx) Dz 0) )
                      (if (and (equal Dx 1 0.0001) (= sud 1))
                                   (setq newDx 6.28318531)
                                   (progn
                                          (command "ARC" "C" PointCent PointStart PointEnd)
                                          (setq selez2 (ssget PointStart))
                                          (setq ename2 (ssname selez2 0))
                                          (setq Nalist(entget ename2))
                                          (setq basArc (cdr(assoc 50 Nalist)))
                                          (setq endArc (cdr(assoc 51 Nalist)))
                                          (setq SvilArc (- endArc basArc))
                                          (setq newDx SvilArc)
                                          (entdel ename2)
                                    )
                         )
                         (setq newDy Dy) ;solo per leggibilità
                         (setq newA   (list newAx newAy newAz) )
                         (setq newB   (list newBx newBy newBz) )
                         (setq newC   (list newCx newCy newCz) )
                         (setq newD   (list newDx newDy newDz) )

                         (if (= 1 pure)

                                   (command "3DFACE" newA newB newC newD "")
                                   (progn
                                           (if (< Ax 0)
                                                   (command "3DFACE" newA newB newC newD "")
                                                   (progn
                                                           (if (< newAx  pi) (setq newAx (+ pi pi  newAx))) 
                                                           (if (< newBx  pi) (setq newBx (+ pi pi  newBx))) 
                                                           (if (< newCx  pi) (setq newCx (+ pi pi  newCx))) 
                                                           (if (< newDx  pi) (setq newDx (+ pi pi  newDx))) 

                                                            (setq newA   (list newAx newAy newAz) )
                                                            (setq newB   (list newBx newBy newBz) )
                                                            (setq newC   (list newCx newCy newCz) )
                                                            (setq newD   (list newDx newDy newDz) )
                                                            (command "3DFACE" newA newB newC newD "")
                                                      )
                                                )
                                     )
                           ) ;  close if pure
                    ) ;  close progn if 3DFACE
                ) ;endif 3DFACE
               (setq na(1+ na))
         ) ;  close while na
       ) ;  close progn selez
    ) ;  close if selez
) ;close defun