V I S U A L I Z Z A D I S C U S S I O N E |
Terminator |
Inserito il - 11 novembre 2010 : 11:19:58 Sappiamo tutti (o quasi) che esiste una funzione per verificare se c'è un punto di intersezione fra due linee. Per esigenze di lavoro dovevo verificare in un programma l'intersezione fra un arco e una linea. Ho quindi creato la suddetta funzione e l'ho chiamata ainters
Sintassi: (ainters entità-arco entità-linea)
La funzione restituisce una lista con al suo interno i punti di intersezione, se esistono, e possono essere uno o due. Se non c'è intersezione la funzione restituisce nil. Le coordinate dei punti di intersezione si trovano sull'UCS dell'arco.
NB: l'UCS modificato è quello dove si trova l'arco
Scarica allegato:
ainters.zip 2,33 KB
|
20 U L T I M E R I S P O S T E (in alto le più recenti) |
joseph |
Inserito il - 14 novembre 2010 : 14:56:34 Rimanendo nel campo dell'ottimizzazione del codice, vi allego altre 2 modi (non sono farina del mio sacco) per spezzare (splittare) una lista generica in sottoliste di determinata lunghezza (in particolare una lista di coordinate in gruppi di 3), il primo un po' elaborato, il secondo molto più stringato. +++++++++ (defun SPLIT (elst n) (if elst (cons (sublist elst 0 n) (split (sublist elst n nil) n))))
(defun SUBLIST (lst start lung / n r) (if (or ( not lung) (< (- (length lst) start) lung)) (setq lung (- (length lst) start)) ) (setq n (+ start lung)) (repeat lung (setq r (cons (nth (setq n (1- n)) lst) r )) )) +++++++++++++++++
(defun parse_list (data n / item new) (foreach element (reverse data) (setq item (cons element item)) (if (= (length item) n) (setq new (cons item new) item nil) ) ) new ) +++++++++++++++ In particolare, se è proprio una lista di punti 3D, allora si può optare per:
(defun 3d-coord->pt-lst (lst) (if lst (cons (list (car lst) (cadr lst) (caddr lst)) (3d-coord->pt-lst (cdddr lst)) ) ) )
Buona Domenica Joseph |
Roberto07 |
Inserito il - 13 novembre 2010 : 21:16:19 Bravi!
Felicitazioni per la vostra bravura!! |
Terminator |
Inserito il - 13 novembre 2010 : 20:28:20 Chiedo scusa e ti comunico che l'ultimo listato che vedi è quello aggiornato (quello dell'ottimizzazione per intenderci), gli altri precedenti post che vedi modificati riguardano solo modifiche di carattere ortografico perché mi seccano gli strafalcioni grammaticali che posso commettere, anche se un post risale a qualche tempo fa e non lo rileggerà più nessuno.
Per chiarezza ti rimando l'ultimissima release della funzione:
(defun array2lista (listacoordinate numero / listaparziale index listafinale) (setq listaparziale '() listafinale '() ) (setq index 0) (while (< index (length Listacoordinate)) (repeat numero (if (/= (nth index listacoordinate) nil) (progn (setq listaparziale (cons (nth index listacoordinate) listaparziale)) (setq index (1+ index)) ) ) ) (setq listaparziale (reverse listaparziale) listafinale (cons listaparziale listafinale) listaparziale nil ) ) (princ "\n") (setq listafinale (reverse listafinale)) ) |
Giuseppe Mauro |
Inserito il - 13 novembre 2010 : 18:41:08 | Messaggio inserito da Terminator
1) Un nome come un altro. Dovevo distinguere le tre liste iniziale, parziale e finale, potevo chiamarle anche pippo, pluto e paperino: (setq pippo listacoordinate pluto listaparziale paperino listafinale) 2) Perché le funzioni append e cons hanno il riprovevole vizio di inserire l'elemento non in fondo alla lista ma all'inizio e quindi bisogna capovolgere l'ordine della lista. In alcuni casi non è necessario, ma in altri potrei avere l'esigenza di ottenere la lista finale con gli elementi nello stesso ordine di quelli contenuti nella variabile INT.
Approfitto per un'ottimizzazione della funzione:
(defun array2lista (listacoordinate numero / listaparziale index listafinale) (setq listaparziale '() listafinale '() ) (setq index 0) (while (< index (length Listacoordinate)) (repeat numero (if (/= (nth index listacoordinate) nil) (progn (setq listaparziale (cons (nth index listacoordinate) listaparziale)) (setq index (1+ index)) ) ) ) (setq listaparziale (reverse listaparziale) ;;; listaparziale (list listaparziale) <-- riga eliminata listafinale (cons listaparziale listafinale) listaparziale nil ) ) (princ "\n") (setq listafinale (reverse listafinale)) )
|
Termi, quando aggiorni un post, magari con cose piccolissime, segnalalo sotto, altrimenti non si comprende come mai il post ritorna tra i recenti. Nel caso specifico, a sensazione, credo tu abbia sistemato qualche parentesi nel listato, ma in questo modo non so se adesso quella che ho io non e' piu l'ultima versione, capisci?
Alla prox |
aforza |
Inserito il - 12 novembre 2010 : 14:09:12 ciao,
questa serviva proprio, grazie mille
ciao |
Terminator |
Inserito il - 12 novembre 2010 : 12:00:28 1) Un nome come un altro. Dovevo distinguere le tre liste iniziale, parziale e finale, potevo chiamarle anche pippo, pluto e paperino: (setq pippo listacoordinate pluto listaparziale paperino listafinale) 2) Perché le funzioni append e cons hanno il riprovevole vizio di inserire l'elemento non in fondo alla lista ma all'inizio e quindi bisogna capovolgere l'ordine della lista. In alcuni casi non è necessario, ma in altri potrei avere l'esigenza di ottenere la lista finale con gli elementi nello stesso ordine di quelli contenuti nella variabile INT.
Approfitto per un'ottimizzazione della funzione:
(defun array2lista (listacoordinate numero / listaparziale index listafinale) (setq listaparziale '() listafinale '() ) (setq index 0) (while (< index (length Listacoordinate)) (repeat numero (if (/= (nth index listacoordinate) nil) (progn (setq listaparziale (cons (nth index listacoordinate) listaparziale)) (setq index (1+ index)) ) ) ) (setq listaparziale (reverse listaparziale) ;;; listaparziale (list listaparziale) <-- riga eliminata listafinale (cons listaparziale listafinale) listaparziale nil ) ) (princ "\n") (setq listafinale (reverse listafinale)) )
|
GP |
Inserito il - 12 novembre 2010 : 10:34:34 Non ho capito due cose:
1) la differenza tra Lista_p e listafinale 2) perchè il reverse? |
Terminator |
Inserito il - 12 novembre 2010 : 06:27:57 Il problema degli output di funzioni vlax-invoke e simili è che il loro formato è sempre una lista unica (8.0 4.0 0.0 5.0 4.3 0.0 ......), nel caso specifico la variabile INT. Noi però abbiamo l'esigenza di raggruppare gli elementi della variabile INT nel formato che noi conosciamo: ((8.0 4.0 0.0)(5.0 4.3 0.0)......), che è poi l'output finale.
Per questo motivo GP aveva scritto la routine: (repeat (/ (length INT) 3) (setq Lista_p (cons (list (car INT)(cadr INT)(caddr INT)) Lista_p)) (setq INT (cdddr INT)) )
Dato che nella programmazione la routine sopra accennata ricorre spesso, ho creato la seguente funzione:
(array2lista listacoordinate numero)
argomenti: listacoordinate = lista di numeri, la variabile INT per intenderci numero = intero che rappresenta il numero di elementi per gruppo (quasi sempre 3, nel caso di lwpolyline 2, ma volendo posso inserire qualsiasi numero)
(defun array2lista (listacoordinate numero / listaparziale index listafinale) (setq listaparziale '() listafinale '() ) (setq index 0) (while (< index (length Listacoordinate)) (repeat numero (if (/= (nth index listacoordinate) nil) (progn (setq listaparziale (append (list (nth index listacoordinate)) listaparziale)) (setq index (1+ index)) ) ) ) (setq listaparziale (reverse listaparziale) listaparziale (list listaparziale) listafinale (append (list (nth 0 listaparziale)) listafinale) listaparziale nil ) ) (princ "\n")(setq listafinale (reverse listafinale)) )
In questo modo il programma subisce un'ulteriore riduzione di righe di codice:
(vl-load-com) (setq ENT1 (vlax-ename->vla-object (car (entsel "\Selezionare primo oggetto: "))) ENT2 (vlax-ename->vla-object (car (entsel "\nSelezionare secondo oggetto: "))) INT (vlax-Invoke ENT1 'IntersectWith ENT2 acExtendNone) ) (if INT (array2lista INT 3) )
Per amor di precisione e logica avremmo potuto scrivere anche: (vla-IntersectWith ENT1 ENT2 acExtendNone) Ma questo avrebbe comportato una difficile gestione della variabile INT non restituita nel formato lista
Mi sa che butterò il programma ainters nel water...
PS: Antoniovinci, hai contato anche le righe bianche nel codice? Io le uso spesso per chiarezza e poi volendo un programma lisp si potrebbe scrivere tutto in una riga senza indentazione alcuna. Dato che sei moooolto preciso, avresti dovuto contare solo le righe effettive... |
Giuseppe Mauro |
Inserito il - 11 novembre 2010 : 16:04:16 Non si tratta di lasciar passare. Si tratta di mettere "una patch" quando si parla. Hai fatto una tua osservazione. Bene, basta 1 volta. La seconda volta, diventa polemica sterile e (soprattutto) irritante.
Puoi essere preciso nella sostanza, ma non nelle sottigliezze. Ti propongo un dialogo surreale tra te e me, assumendo le tue "pignolerie" Antonio:"Ciao Peppe" Peppe: "Ciao... ma scusa me sei Antonio Vinci?" Antonio: "Certo che si, non lo vedi il nick?" Peppe: "Si lo vedo, ma che ne so se sei l'Antonio quello polacco?" Antonio "Certo che sono io...." Peppe: "Si ma quanti figli hai?" Antonio "OH! Ma sei impazzito" Peppe: "No Antonio, e che conosco un altro Antonio Vinci che si e' trasferito in Polonia.." Antonio: "Ok, ho un figlio.." Peppe: "Si ma quando sei nato?" Antonio: "Cavolo questo sta dando i numeri..." Peppe: "No Antonio e' che anche il tuo omologo ha un solo figlio..."
Smetto perche potrei continuare per almeno altre 100 righe... Come vedi c'e' differenza tra essere precisi, essere pignoli ed essere polemici. E per come la vedo, tu oscilli tra la seconda e la terza.
|
n/a |
Inserito il - 11 novembre 2010 : 15:26:17 Hai ragione Peppe, ma tu devi capire che io sono ignorante come una capra, ma una capra precisa, quindi per me (3,3) e' e sara' sempre uguale a (3,3,0) come tardivamente ha confermato l'ottimo Terminator.
Sai come la penso al riguardo: non possiamo lasciar passare tutto sotto silenzio, altrimenti il livello tecnico di Cadlandia degrada inesorabilmente.
|
Giuseppe Mauro |
Inserito il - 11 novembre 2010 : 15:19:32 Io sono convinto che Anto' non riesce a litigare con l'uomo sul crocifisso, solo perche' non gli risponde. Se fosse dotato di voce, sono sicuro che lo vedremmo schiodarsi dalla croce e prendere a calci nel didietro il buon antonio |
n/a |
Inserito il - 11 novembre 2010 : 14:33:36 T, per il miracolo che sai, ti sono debitore in eterno, e quindi ti si perdona tutto, tranquillo...
|
Terminator |
Inserito il - 11 novembre 2010 : 14:14:24 Acc...è vero, scusa, la z bisogna specificarla... era giusto (3,3,3) (5,5,5)
Va bè, come non detto. |
n/a |
Inserito il - 11 novembre 2010 : 13:41:33 | Messaggio inserito da Terminator la linea ha coordinate (3,3) e (5,5)
|
Se tu scrivi 3,3 e 5,5 per convenzione mondiale la Z=0 e' sottintesa, quindi la linea sara' perfettamente complanare ad un arco giacente sull'ucs globale.
Se invece cambi le carte in tavole, aggiungendo Z diverse per gli estremi della linea, e' normale che non esista complanarita'...
Direi di chiuderla qua, perche' stiamo passando dalla tecnica alla filosofia.
|
Terminator |
Inserito il - 11 novembre 2010 : 13:26:52 Ti sembrano complanari questi????? (vedi dwg allegato)
Ad ogni modo ti rispondo al quesito: Il risultato è lo stesso, ma il mio programma risale ai tempi pre-ActiveX. La funzione di GP inoltre permette di essere molto più flessibile dato che funziona su ogni tipo di entità.
Scarica allegato:
ucs.zip 7,76 KB |
n/a |
Inserito il - 11 novembre 2010 : 13:12:32 | Messaggio inserito da Terminator se l'arco giace sull'UCS globale e la linea ha coordinate (3,3) e (5,5) NON possono essere complanari
|
Come no, T???
I punti 3,3 e 5,5 giacciono al 100% sul piano X-Y globale, cioe' esattamente nel medesimo UCS dell'arco!!
A parte 'sta questione di lana caprina, la domanda da ignorante che faccio ad entrambi e' la seguente: le 11 righe di codice di GP danno lo stesso identico risultato delle 477 righe di codice di Terminator?
|
Terminator |
Inserito il - 11 novembre 2010 : 12:48:10 Quello che volevo dire è che se l'arco giace sull'UCS globale e la linea ha coordinate (3,3) e (5,5) NON possono essere complanari. Mi sembra chiaro che se c'è un intersezione anche l'UCS sia comune! Ringrazio caldamente GP per l'intervento. Non ho avuto il tempo di studiarmi tutti gli ActiveX e se devo essere onesto non conoscevo la funzione richiamata da vlax-invoke. Una volta di più c'è sempre e ci sarà sempre tanto da imparare. |
n/a |
Inserito il - 11 novembre 2010 : 12:24:22 Ma infatti, e' quindi vero che l'UCS delle coordinate d'intersezione appartiene ad entrambi (linea+arco) e non solo all'arco, come invece sosteneva il grande T alle ore 11:19:58...
|
GP |
Inserito il - 11 novembre 2010 : 12:15:39 Nella variabile Lista_p vengono memorizzati i punti di intersezione degli oggetti ENT1 e ENT2, se giacciono sullo stesso piano.
(vl-load-com)
(setq ENT1 (vlax-ename->vla-object (car (entsel))))
(setq ENT2 (vlax-ename->vla-object (car (entsel))))
(setq INT (vlax-invoke ENT1 'IntersectWith ENT2 acExtendNone))
(cond (INT
(repeat (/ (length INT) 3)
(setq Lista_p (cons (list (car INT)(cadr INT)(caddr INT)) Lista_p))
(setq INT (cdddr INT))
)
)
) |
Terminator |
Inserito il - 11 novembre 2010 : 12:14:48 La funzione inters funziona allo stesso modo, ti restituisce le coordinate solo se le linee sono complanari e non calcola le intersezioni apparenti. |
|
|