Autore |
Discussione |
aforza
Utente Master
Regione: Italia
Prov.: Padova
Città: Cavarzere(VE)-Monselice(PD)
1798 Messaggi |
Inserito il - 04 novembre 2010 : 12:38:57
|
Ciao,
qualcuno per caso ha un lispetto per trasformare una polilinea fatta di linee ed archi in polilinea di sole linee avente lunghezza ben precisa ex. 3m
p.s. con divide/misura non funziona
Nell'immagine la poli rossa è l'originale la poli bianca quella nuova
ciao
Immagine inserita:
28,12 KB
|
Andrea Forza
CadWorx 2014 & Plant3D AutoCAD 2014 su Seven 64bit - Dell Vostro i7 ram 8gb - doppio monitor Hanns-g 22" |
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 04 novembre 2010 : 13:27:54
|
Ho buttato giù questo:
(defun C:DIVPOL (/ poly grupunti index numero)
(if (or (= (ver) "Visual LISP 2011(it)") (= (ver) "Visual LISP 2010(it)") ) (setq numero 6) (setq numero 5) ) (setq poly (car (entsel "\nSelezionare polilinea: "))) (command "_MEASURE" poly 3)
(setq grupunti (ssget "p"))
(command "_PLINE") (command (cdr (assoc 10 (entget poly))))
(setq index 0) (repeat (sslength grupunti) (command (cdr (assoc 10 (entget (ssname grupunti index))))) (setq index (1+ index)) )
(command (append (cdr (nth (- (length (entget poly)) numero) (entget poly))) (list (cdr(assoc 38 (entget poly)))) ) "" ) (command "_CHPROP" (entlast) "" "LA" (cdr(assoc 8 (entget poly))) "") (entdel poly) (command "_ERASE" grupunti "") (princ) )
Premetto comunque alcune cose: 1) Mi servirebbe la tua versione di AutoCAD. I codici AutoLISP per le polilinee cambiano leggermente a seconda delle versioni 2) Il programma così come è stato scritto funziona solo sull'UCS globale 3) Manca la classica gestione degli errori 4) Il programma non tiene conto dei punti iniziali e finali delle entità che lo compongono. Dipende se è una tua esigenza averli nella nuova polilinea oppure no |
Modificato da - Terminator in data 04 novembre 2010 14:17:52 |
|
|
aforza
Utente Master
Regione: Italia
Prov.: Padova
Città: Cavarzere(VE)-Monselice(PD)
1798 Messaggi |
Inserito il - 04 novembre 2010 : 15:08:05
|
ciao,
ti chiedo scusa ma come precisato con divide e misura non funziona perchè tu misuri una lunghezza lungo un percorso in realtà devi posizionare gli estremi di una linea di lunghezza nota su un percorso
in questo caso se misuri i tratti lungo l'arco non sono giusti sono 2.99 se però usi 5 l'errore diventa 0.20 tutto dipende dal raggio dell'arco
cioè nel caso dell'arco la lunghezza rchiesta è la corda e non lo sviluppo del tratto di arco
p.s. questo succede anche se è una spezzata
p.s.s. mi sembrava ci fosse già stata una discussione ma la ricerca non da esiti...
p.s.s.s. per costruire a amno la cosa bisogna fare un cerchio di raggio uguale alla lunghezza richiesta con centro nel primo punto della poli poi sucessivamente altro cerchio con centro nell'intersezione dello stesso con la poli e così via
forse bisogna capire come indiuviduare l'intersezione di un cerchio con una poly (la funzione inters del lisp va per punti.....)
grazie ciao
|
Andrea Forza
CadWorx 2014 & Plant3D AutoCAD 2014 su Seven 64bit - Dell Vostro i7 ram 8gb - doppio monitor Hanns-g 22" |
Modificato da - aforza in data 04 novembre 2010 15:14:43 |
|
|
Jotar
Utente Master
Regione: Lazio
Prov.: Roma
Città: Roma
799 Messaggi |
Inserito il - 04 novembre 2010 : 15:55:32
|
Solo per capire meglio...
La lunghezza dei tratti la imponi tu? Perché così vuol dire che ci può essere anche uno scarto finale. Cioé ci possono essere tutti tratti lunghi 3 metri e l'ultimo lungo 2,58 metri. Oppure, i tratti devono essere tutti per forza uguali tra loro? |
Jotar |
|
|
aforza
Utente Master
Regione: Italia
Prov.: Padova
Città: Cavarzere(VE)-Monselice(PD)
1798 Messaggi |
Inserito il - 04 novembre 2010 : 16:02:41
|
ciao,
si fisso la lunghezza, quel che resta resta non è un problema se guardi l'immagine iniziale rimane un pezzettino
ciao |
Andrea Forza
CadWorx 2014 & Plant3D AutoCAD 2014 su Seven 64bit - Dell Vostro i7 ram 8gb - doppio monitor Hanns-g 22" |
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 04 novembre 2010 : 19:28:31
|
Chiedo scusa se sono stato poco attento, infatti l'immagine parlava chiaramente. Peccato che la funzione inters vada per punti, si, ma con due segmenti. Qui invece abbiamo l'intersezione fra un arco/cerchio e un segmento. Ci ragionerò su... |
|
|
joseph
Utente Master
Regione: Lombardia
Prov.: Cremona
Città: Casalmaggiore
1884 Messaggi |
Inserito il - 04 novembre 2010 : 22:59:16
|
Si può anche usare VisualLisp e in particolare il gruppo di funzioni che inizia con vlax-curve-... per percorrere la polilinea lungo gli archi e non sulle corde corrispondenti.
|
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 05 novembre 2010 : 16:23:11
|
Ecco fatto:
(defun C:DIVPOL (/ punto1 punto2 dist distanza) (setvar "CMDECHO" 0) (setvar "OSMODE" 0) (setq vlpoly (vlax-ename->vla-object (car (entsel "\nSelezionare la polilinea: ")) ) lung (vlax-curve-getdistatpoint vlpoly (vlax-curve-getendpoint vlpoly) ) dist 0.00 P10poli (vlax-curve-getStartPoint vlpoly) punto1 P10poli ) (command "_PLINE" P10poli)
(while (< dist lung) (setq punto2 (vlax-curve-getPointAtDist vlpoly dist) distanza (distance punto1 punto2) )
(if (equal distanza 3 0.0001) (progn (command punto2) (setq punto1 punto2) ) )
(setq dist (+ dist 0.0001)) )
(command "")
)
Sto lavorando per trovare il sistema di velocizzare il tutto. |
|
|
Giuseppe Mauro
Amministratore
Regione: Campania
Prov.: Napoli
2705 Messaggi |
Inserito il - 05 novembre 2010 : 17:06:49
|
Bravo Terminator
Ho inserito delle piccole modifiche per renderlo piu user friendly
Riporto le modifiche/aggiunte in rosso
(defun C:DIVPOL (/ punto1 punto2 dist distanza corda oldosmode precision toll) (setq OLDOSMODE (getvar "OSMODE")) (setvar "CMDECHO" 0) (setvar "OSMODE" 0) (setq vlpoly (vlax-ename->vla-object (car (entsel "\nSelezionare la polilinea: ")) ) lung (vlax-curve-getdistatpoint vlpoly (vlax-curve-getendpoint vlpoly) ) dist 0.00 P10poli (vlax-curve-getStartPoint vlpoly) punto1 P10poli ) (initget 7) (setq corda (getreal "\nLunghezza della corda desiderata: ")) (initget 7) (setq precision (getreal "\nTolleranza (decimillesimi di unita'): ")) (setq toll (* 0.0001 precision))
(command "_PLINE" P10poli)
(while (< dist lung) (setq punto2 (vlax-curve-getPointAtDist vlpoly dist) distanza (distance punto1 punto2) )
(if (equal distanza corda toll) (progn (command punto2) (setq punto1 punto2) ) )
(setq dist (+ dist 0.0001)) )
(command "")
(setvar "OSMODE" OLDOSMODE)
);; chiusura defun
(princ "\nDiscretizza una polilinea a distanze di corda prefissate - usare DIVPOL") |
|
|
aforza
Utente Master
Regione: Italia
Prov.: Padova
Città: Cavarzere(VE)-Monselice(PD)
1798 Messaggi |
Inserito il - 05 novembre 2010 : 17:31:57
|
ciao,
mi segnala questo errore
Selezionare la polilinea: ; errore: no function definition: VLAX-ENAME->VLA-OBJECT
ora guardo
ciao |
Andrea Forza
CadWorx 2014 & Plant3D AutoCAD 2014 su Seven 64bit - Dell Vostro i7 ram 8gb - doppio monitor Hanns-g 22" |
|
|
arri
Utente Master
Regione: Lombardia
14951 Messaggi |
Inserito il - 05 novembre 2010 : 17:33:45
|
Messaggio inserito da aforza
ciao,
mi segnala questo errore
Selezionare la polilinea: ; errore: no function definition: VLAX-ENAME->VLA-OBJECT
ora guardo
ciao
(vl-load-com)
aggiungere all'inizio |
Modificato da - arri in data 05 novembre 2010 17:36:44 |
|
|
aforza
Utente Master
Regione: Italia
Prov.: Padova
Città: Cavarzere(VE)-Monselice(PD)
1798 Messaggi |
Inserito il - 05 novembre 2010 : 17:38:19
|
ciao,
grazie...
mi sa che è andato in loop non si muove più niente...
ciao |
Andrea Forza
CadWorx 2014 & Plant3D AutoCAD 2014 su Seven 64bit - Dell Vostro i7 ram 8gb - doppio monitor Hanns-g 22" |
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 05 novembre 2010 : 17:44:24
|
Ti ringrazio, Giuseppe Mauro
Hai fatto bene ad inserire quelle modifiche e comunque il programma non aveva assolutamente la pretesa di essere completo ultima release, anzi... Il programma lascia spazio per ulteriori, eventuali miglioramenti come ad esempio una DCL di dialogo, Un'altro miglioramento che ho in mente, devo ancora buttarlo sulla carta. Infatti ora il programma è lento da far paura, questo perché viene esaminato ogni punto sulla polilinea, anche i punti distanti dalla famigerata lunghezza della corda. Infatti, prima di arrivare 3.00 unità con l'incremento di 0.0001, stiamo freschi! Finché abbiamo una o due polilinee, poco male, si può aspettare, ma nel momento in cui bisogna trattare 50 o più polilinee... |
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 05 novembre 2010 : 17:47:22
|
Stai tranquillo aforza, sta lavorando... |
|
|
aforza
Utente Master
Regione: Italia
Prov.: Padova
Città: Cavarzere(VE)-Monselice(PD)
1798 Messaggi |
Inserito il - 05 novembre 2010 : 17:53:10
|
ciao,
si si vedo, i miei COMPLIMENTI, soprattutto perchè non avete perso l'entusiamo.. io l'ho un pò perso...
ho esagerato avevo una polilinea grande e con 3m ho esagerato....
qui si stava provando con un modo un pò fantaLISP partendo da presupposto che a mano faccio così...
----------------- ;;;DISCretizza.lsp ;; ;
;******************************************************************************* (defun oEstraeVtx (bb / listanodi ed i pp nn ) ;******************************************************************************* (setq ed (entget bb) i 1 nn (length (cdr ed))) (while (< i nn) (if (= 10 (car (nth i ed))) (progn (setq pt (cdr (nth i ed)) listanodi (append listanodi (list pt)) ) ):progn );Endif (setq i (1+ i)) )
(setq pp listanodi) ) (defun GtoR(angolo) (/ (* pi angolo) 180.00)) (defun TrovaPunto ( pt0 accuratezza distanza) (setq found T anginit 0 acc (Gtor accuratezza) ptlist nil )
(command "_Circle" pt0 distanza)
(setq ename (entlast))
(while (< anginit (* 2 pi) ) (setq ptNear (polar pt0 anginit distanza) ptint (Osnap ptNear "_int") ) (if (= (type ptint) 'LIST) (progn (if (not (member ptint ptlist)) (setq ptlist (append ptlist (list ptint))) );endif );endprogn );endif
(setq anginit (+ anginit acc))
;(command "_point" ptnear) );endwhile
(command "_erase" ename "")
;(command "_pline") ;(foreach pt ptlist (command pt)) ;(command "") (setq ptlist ptlist)
) (defun c:disc()
(setq LunPar 3 listatemp nil ss1 (ssget) coo (car (oEstraeVtx (ssname ss1 0))) start (car (trovapunto coo 1 lunpar)) ListaTemp (append listatemp (list start)) oldApertur (getvar "APERTURE") )
;(setvar "APERTURE" 16)
(command "_AREA" "_E" (ssname ss1 0) "") (command "_Zoom" "_O" (ssname ss1 0) "") ; (command "_Zoom" "0.75x" "") (setq lpl (getvar "PERIMETER") lpar 0 )
(while (< lpar lpl)
(setq newlist (trovapunto start 1 lunpar) ii 0)
(repeat (length newlist) (if (not (member (nth ii newlist) listatemp)) (setq listatemp (append listatemp (list (nth ii newlist)))) );end if
(setq start (last listatemp))
)
(setq lpar (+ lpar lunpar))
);endwhile
(setvar "APERTURE" oldApertur)
(setq listatemp (Cons coo listatemp))
(command "_pline") (foreach pt listatemp (command pt)) (command "")
)
(princ) (prompt "\nDigitare su linea di comando: disc") -------------
|
Andrea Forza
CadWorx 2014 & Plant3D AutoCAD 2014 su Seven 64bit - Dell Vostro i7 ram 8gb - doppio monitor Hanns-g 22" |
Modificato da - aforza in data 05 novembre 2010 17:58:10 |
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 07 novembre 2010 : 20:03:25
|
Così va meglio...
La routine while è stata completamente ridisegnata, traendo ispirazione da un vecchio trucco usato su un programma che avevo fatto per le distanze di visibilità sulle curve clotoidi delle strade. In pratica, invece di considerare punto per punto di una polilinea con relative perdite di tempo, si divide in due parti la polilinea e si considera se il punto che interessa si trova nella prima parte o nella seconda. LA parte interessata si divide ulteriormente in due e via dicendo. In questo modo si può eliminare la tolleranza dato che si lavora direttamente su 8 decimali e la divisione della polilinea viene fatta quasi istantaneamente. Come ciliegina sulla torta ho aggiunto una piccola finestra di dialogo.
;;; ****************************DIVPOL*************************************** ;;; Programma per discretizzare un polilinea (DIVisione POLilinea) (defun C:DIVPOL (/ punto1 punto2 dist distanza cordapresunta oldosmode sommacorde dist1 dist2 lung P10poli P11poli distx disty adial ndialogo corda ) (setq OLDOSMODE (getvar "OSMODE")) (setvar "CMDECHO" 0) (setvar "OSMODE" 0) (vl-load-com) (setq vlpoly (vlax-ename->vla-object (car (entsel "\nSelezionare la polilinea: ")) ) lung (vlax-curve-getdistatpoint vlpoly (vlax-curve-getendpoint vlpoly) ) P10poli (vlax-curve-getStartPoint vlpoly) P11poli (vlax-curve-getEndPoint vlpoly) punto1 P10poli ) (create_dialog_divpol) (setq dcl_id (load_dialog ndialogo))
(if (not (new_dialog "divpol" dcl_id)) (exit) )
(cond ((= cordas nil) (setq cordas "3.00") (set_tile "corda1" "3.00") ) ((/= cordas nil) (set_tile "corda1" cordas) ) )
;;; (initget 7) ;;; (setq corda (getdist "\nLunghezza della corda desiderata: ")) ;;; (initget 7) ;;; (setq precision (getreal "\nTolleranza (millesimi di unita'): ")) ;;; (setq toll (* 0.00000001 precision))
(setq sommacorde 0.00) (setq dist1 lung) (setq dist lung) (setq distx dist1) (setq dist2 0.00) (setq disty dist2)
(action_tile "corda1" "(setq cordas $value)") (action_tile "accept" "(valutazione)") (action_tile "cancel" "(done_dialog 0)")
(setq flag (start_dialog))
(cond ((= flag 1) (setq corda (atof cordas)) (command "_PLINE" P10poli)
(while (> (distance punto1 P11poli) corda) (setq punto2 (vlax-curve-getPointAtDist vlpoly dist) cordapresunta (distance punto1 punto2) )
(if (equal dist1 dist2 0.00000001) (progn (command punto2) (setq punto1 punto2 sommacorde (+ sommacorde corda) dist1 lung dist2 dist ) ) (progn
(if (> cordapresunta corda) (progn (setq distx dist1 dist1 dist ) ) (progn (setq disty dist2 dist2 dist ) ) )
(setq dist (+ (/ (- dist1 dist2) 2.00) dist2)) ) )
)
(command "") ) ((= flag 0) (alert " Funzione annullata") ) )
(setvar "OSMODE" OLDOSMODE) (princ) ) ;; chiusura defun
(princ "\nDiscretizza una polilinea a distanze di corda prefissate - usare DIVPOL" )
(defun create_dialog_divpol () (setq ndialogo (vl-filename-mktemp "divpol.dcl")) (setq adial (open ndialogo "w")) (write-line
" divpol : dialog { label = \"DIVPOL\"; fixed_width = true; height = 5; width = 15; : edit_box { label = \"Lunghezza corda:\"; key = \"corda1\"; edit_width = 8; edit_limit = 8; alignment = right; } : errtile { width = 10; } ok_cancel; } "
adial )
(close adial) )
(defun valutazione ()
(if (<= (atof cordas) 0.00) (progn (set_tile "error" "Lunghezza corda non valida!") (mode_tile "corda1" 2) ) (progn (set_tile "error" " " ) (done_dialog 1) ) )
) |
Modificato da - Terminator in data 07 novembre 2010 21:13:40 |
|
|
Giuseppe Mauro
Amministratore
Regione: Campania
Prov.: Napoli
2705 Messaggi |
Inserito il - 07 novembre 2010 : 21:12:12
|
Tanto di cappello a Terminator Stavo tentando una strada diversa (costruzione per intersezioni), ma la sua funziona uno spettacolo.
Mi sa che insidierai la leadership di GP nel lisp Davvero i miei complimenti |
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 07 novembre 2010 : 21:18:01
|
Ringrazio per i complimenti!
Penso che tuttavia questo forum non sia una classifica dei più bravi e dei meno bravi, ognuno da il suo contributo e devo dire che in questo forum siete tutti molto, ma molto competenti. Lo dice uno che bazzica con l'AutoCAD e con L'AutoLISP da circa 22 anni. |
|
|
joseph
Utente Master
Regione: Lombardia
Prov.: Cremona
Città: Casalmaggiore
1884 Messaggi |
Inserito il - 07 novembre 2010 : 23:13:45
|
| Messaggio inserito da Terminator ....Infatti ora il programma è lento da far paura, questo perché viene esaminato ogni punto sulla polilinea, anche i punti distanti dalla famigerata lunghezza della corda....
|
Invece di usare la combinazione "setq lung (vlax-curve-getdistatpoint vlpoly(vlax-curve-getendpoint vlpoly))" per trovare la lunghezza totale, si può sfruttare la funzione "(vlax-curve-GetEndParam(car(entsel)))", in cui Param fornisce il numero di vertici di una polilinea; scorrendo successivamente lungo i vertici, se la funzione VLA-GETBULGE mantiene valore 0 (il che è indice di assenza di curvatura) fra 2 vertici in sequenza, in quel tratto si può usare Divide o Misura, velocizzando la procedura. |
|
|
Terminator
Utente Master
725 Messaggi |
Inserito il - 08 novembre 2010 : 04:56:23
|
| Messaggio inserito da joseph
Invece di usare la combinazione "setq lung (vlax-curve-getdistatpoint vlpoly(vlax-curve-getendpoint vlpoly))" per trovare la lunghezza totale, si può sfruttare la funzione "(vlax-curve-GetEndParam(car(entsel)))", in cui Param fornisce il numero di vertici di una polilinea; scorrendo successivamente lungo i vertici, se la funzione VLA-GETBULGE mantiene valore 0 (il che è indice di assenza di curvatura) fra 2 vertici in sequenza, in quel tratto si può usare Divide o Misura, velocizzando la procedura.
|
Precisazione giustissima, ma in caso di polilinee composte da soli archi casca il palco. Poi, con la seconda versione del programma, è stata tagliata la testa al toro. |
|
|
n/a
deleted
Prov.: Estero
Città: Sieradz (PL)
5926 Messaggi |
Inserito il - 08 novembre 2010 : 06:57:17
|
Terminator, lascia che ti dica una cosa.
Se tu ti alzi all'alba e, prima ancora di fare colazione, posti su Cadlandia, beh, meriti una virtuale ma virile pacca sulle spalle.
Resta con noi, grazie! |
|
|
Discussione |
|