Ingegneria Forum
Ingegneria Edile, Strutturale & Geotecnica => .:Geotecnica e Geologia:. => Topic started by: afazio on 12 December , 2009, 20:22:12 PM
-
Proviamo a scrivere la funzione basilare per la verifica di stabilità di un pendio.
Posizione del problema:
- dato un cerchio di cui sono note le coordinate del suo centro ed il raggio
- date le ascisse di inizio e di fine del generico concio
- date le ordinate del profilo, indifferentemente di terreno o di separazione strati o di falda, all'inizio e fine del concio
la funzione deve calcolare l'area del concio e l'angolo formato dalla tangente condotta al piede del concio nel suo punto medio
Il tutto e' rappresentato nella seguente immagine
(http://img130.imageshack.us/img130/4652/pendio.jpg)
chiameremo la funzione col nome concio
essa avrà la forma, che definiremo nei dettagli in seguito, del tipo:
concio(xc, yc, R, xi, xf, yi, yf, flag)
al solito, come ormai uso fare, il parametro flag serve a stabilire se vogliamo in uscita l'area A o l'angolo alfa.
Esso pertanto avrà (per adesso) il valore:
1 - se vogliamo che la funzione ci restituisca l'area
2 - se vogliamo che la funzione ci restituisca l'angolo
Ci riserviamo di estendere i valori di questo parametro, nel caso in cui si presentasse la necessità di avere altri valori in uscita.
Ovviamente i dati in input devono essere tra loro congruenti, nel senso che a monte il programma deve passare valori di xf maggiori di xi, e devono essere passati tutti nella stessa unità di misura.
A questo punto e' lecita la domanda: cosa ce ne facciamo poi dell'area o dell'angolo?
L'area ci servirà a determinare il peso del concio, basta moltiplicarla per il peso per unità di volume del terreno che costituisce il concio, mentre l'angolo ci servirà per determinarci le sue componenti: la componente normale (N) che utilizzeremo per ricavarci la resistenza a taglio e la componente tangenziale che e' quella che tende a far scivolare il concio.
Proprio adesso mentre scrivo mi sovviene che nel caso in cui il terreno fosse anche coesivo, la resistenza a taglio sarebbe data da due contributi:
Tr = c' *B + N*tan(fi)
e quindi ci serve anche determinarci il valore di B e cioe' lo sviluppo dell'arco al piede del concio. Per fare questo, allora decidiamo di estendere il flag a 3 e restituirci B quando passiamo flag=3
Non escludiamo il fatto che, ai fini sismici, ci servirà anche determinarci l'ordinata del baricentro di A ove poter applicare sia la componente orizzontale che quella verticale della forza sismica inerziale. Ma rinviamo questo ad una fase successiva.
Intanto cominciamo, poichè solo chi inizia ha probabilità di completare.
alla prossima
-
Vedo che ti sei gia' dato da fare. Noto anche con interesse che nel VBA usi "L'espediente" di una variabile flag per determinare il parametro in uscita, mentre con c# i metodi possono restituire di default diversi valori a seconda di ciò che desidera il programmatore...per mia curiosità, sei sicuro che questa possibilita' sia negata in VBA?
-
Vedo che ti sei gia' dato da fare. Noto anche con interesse che nel VBA usi "L'espediente" di una variabile flag per determinare il parametro in uscita, mentre con c# i metodi possono restituire di default diversi valori a seconda di ciò che desidera il programmatore...per mia curiosità, sei sicuro che questa possibilita' sia negata in VBA?
Si
questo semplicemente per il fatto che il valore ritornato dalla funzione occuperà la cella che chiama la funzione
La cella puo' contenere un solo valore
-
si ma nel c#(e nel visual basic 2008 se non vado errato) esistono le funzioni multiple in out....domani riprendo il libro di c# e vedo di farti un esempio, perche' mi pare che la stessa cosa possa farsi in VB ma questa e' una parte della programmazione che ho usato raramente, e non mi ricordo bene la sintassi.Ultima domanda: il vba per excel supporta l'overload delle funzioni? perche' se cosi' fosse si potrebbe direttamente sovraccaricare la funzione in modo che a seconda dei parametri in ingresso determini il valore (potremmo addirittura con una sola funzione passare anche spirali logaritmiche per esempio).
:ciau:
p.s. afazio ultima richiesta. Puoi editare il tuo primo post per inserire come allegato quel file di autocad di cui vedo l'immagine? potrà servire più in la per aggiungerci dati, e sarebbe bene avere sempre la stessa figura, tanto per ordine mentale.
-
si ma nel c#(e nel visual basic 2008 se non vado errato) esistono le funzioni multiple in out....domani riprendo il libro di c# e vedo di farti un esempio, perche' mi pare che la stessa cosa possa farsi in VB ma questa e' una parte della programmazione che ho usato raramente, e non mi ricordo bene la sintassi.Ultima domanda: il vba per excel supporta l'overload delle funzioni? perche' se cosi' fosse si potrebbe direttamente sovraccaricare la funzione in modo che a seconda dei parametri in ingresso determini il valore (potremmo addirittura con una sola funzione passare anche spirali logaritmiche per esempio).
:ciau:
p.s. afazio ultima richiesta. Puoi editare il tuo primo post per inserire come allegato quel file di autocad di cui vedo l'immagine? potrà servire più in la per aggiungerci dati, e sarebbe bene avere sempre la stessa figura, tanto per ordine mentale.
non farmi nessun esempio di funzioni multiple in c# o in VB, non sono interessato.
Non ho intenzione alcuna di fare programmi (che fino a tempo fa componevo con delphi) stand-alone. Uso Excel e le sue potenzialità e cio mi basta.
Ovviamente in seguito, volendo, tu potrai trasfeire le funzioni adattandole a c#
ora provo ad allegare il file autocad, ma e' banale.
-
Difatti parlavo di questo genere di "Caratteristiche" delle funzioni, perchè stavo pensando ad una parallela trasposizione in C# per farla divenire una applicazione windows a tutti gli effetti. Possiamo andare avanti.
-
allora, la prima cosa che mi viene in mente, così su due piedi, come primo passo, sarebbe calcolarsi l'area del concio. Per far ciò, dovremo conoscere le coordinate dei due vertici finali p1 e p2 del quadrilatero formatosi (i primi due punti li conosciamo e corrispondono con il profilo del terreno). Secondo me, come prima cosa, conoscendo raggio e centro del cerchio, conosciamo anche l'equazione del cerchio stesso. Se intersechiamo ora la circonferenza con la retta x=xi, otteniamo due y, che rappresentano le due ordinate dei punti di intersezione. Potremmo trovare agevolmente il punto scartando la soluzione che da un y>yi. Procedendo analogamente ci troveremmo le coordinate dei punti di intersezione del quadrilatero con la circonferenza.
(http://s3.postimage.org/7SZP0.jpg) (http://www.postimage.org/image.php?v=Pq7SZP0)
-
Fatte tutte le premesse, iniziamo ad isolare il problema. Vedere pertanto la seguente figura che rappresenta il generico cerchio con dentro il generico concio
(http://img152.imageshack.us/img152/5623/pendio1.jpg)
la prima cosa che notiamo e' che possiamo sostituire le due ordinate degli estremi superiori del concio con la sua ordinata media
ym = 0.5*(yi +yf )
poiche l'area in rosso e' uguale all'area in blu.
Vedremo poi cosa accase per il primo e l'ultimo concio, quello che e' delimitato dal cerchio e da solo una verticale.
Facedno un passo avanti, l'area del concio puo essere determinata a partire dall'area campita riportata nella immagine che segue.
(http://img46.imageshack.us/img46/7493/pendio2.jpg)
questa area, che chiamo con A1, la si puo' ottenere come differenza tra le due aree campite della figura che segue
(http://img692.imageshack.us/img692/6064/pendio3.jpg)
queste due aree dovremmo saperle calcolare agevolmente: vediamo poi come
Adesso immaginiamo di conoscere l'area A1, ed immaginiamo di dimezzarla con una orizzontale passante per il centro ed avente quindi ordinata y=yc
ecco l'immagine risolutiva
(http://img80.imageshack.us/img80/6480/pendio4.jpg)
adesso e' banale scrivere che l'area A che ci interessa vale:
A = 0.5*A1 - (xf-xi)*(yc-ym)
-
A questo punto non resta che procedere al calcolo dell'area dei due segmenti circolari riportati in una delle figure precedenti.
L'area del segmento circolare si trova come differenza fra l'area del settore circolare e larea del suo tirnagolo al centro.
L'area del settore circolare e' pari a:
As= pigreco*R²*beta/360
in cui beta (in gradi) e' l'angolo al cetro sotteso dal settore
Se invece volessimo usare beta espresso in radianti, la formula sarebbe:
As= R²*beta/2
(http://img683.imageshack.us/img683/6699/beta.jpg)
in questa immagine viene considerata l'ascissa generica x che puo' essere sia quella finale che quella iniziale del concio
occorre pertanto trovarsi beta
-
io continuo invece con la mia ipotesi. Una volta trovati i vertici di questo quadrilatero, l'area si puo' trovare facilmente scomponendo il quadrilatero nella somma di un rettangolo + 2 triangoli rettangoli, il tutto con misure note (abbiamo le x e le y dei 4 vertici). Stessa cosa dicasi per il baricentro della figura, che sara' equivalente al baricentro delle figure pesato rispetto alle loro aree.Ovviamente questo algoritmo terrebbe conto in automatico dei conci iniziali e finali, in quanto in questi punti risulterebbe automaticamente verificata l'uguaglianza yf=y2 (primo concio) ed yi=y1 (secondo concio).
-
io continuo invece con la mia ipotesi. Una volta trovati i vertici di questo quadrilatero, l'area si puo' trovare facilmente scomponendo il quadrilatero nella somma di un rettangolo + 2 triangoli rettangoli, il tutto con misure note (abbiamo le x e le y dei 4 vertici). Stessa cosa dicasi per il baricentro della figura, che sara' equivalente al baricentro delle figure pesato rispetto alle loro aree.Ovviamente questo algoritmo terrebbe conto in automatico dei conci iniziali e finali, in quanto in questi punti risulterebbe automaticamente verificata l'uguaglianza yf=y2 (primo concio) ed yi=y1 (secondo concio).
se procedi con la strada delle intersezioni non risolvi il problema, intanto aggiungi l'approssimazione considerando un trapezio cio' che invece non è.
Tempo fà ho provato anche io a ragionare con le intersezioni sia tra le verticali ed il cerchio e sia tra il pendio (o superfici di separazione o linea di falda) ed il cerchio per delimitare il campo dove procedere con la suddivisione in conci. Il problema della posizione di un segmento rispetto ad un cerchio non e' di facile ed immediata soluzione.
E poi, se ritieni sia una valida via, perch' non inizi a scrivere formule?
Ti ricordo che solo chi inizia puo' terminare.
Io intanto continuo
L'angolo beta lo si puo' determinare attraverso la successiva immagine:
(http://img20.imageshack.us/img20/6012/beta1y.jpg)
Qui ho anche riportato la dimensione H/2 che ci servirà per determinare l'area del triangolo sotteso dal settore circolare.
beta=2* arccos[ (x-xc)/R ] e con questo abbiamo beta
mentre la base del triangolo vale:
H=2*R*sin (beta/2)
a questo punto abbiamo anche l'area del triangolo:
At = (x-xc)*R*sin(beta/2)
e quindi l'area del segmento circolare, considerando che l'angolo beta lo abbiamo in radianti, vale:
Aseg = R²*beta/2 - (x-xc)*R*sin(beta/2)
facile no?
A questo punto per evitare di appesantire troppo la funzione concio ci conviene scrivere una funzione dedicata al calcolo dell'area del segmento in cui passando semplicemente l'ascissa del cerchio, il suo raggio e l'ascissa generica x, ci restituisca in un sol botto l'area del segmento
function segmento(xc,R,x)
dim beta as double
beta=2*acos( (x-xc)/R )
segmento= R^2*beta/2 - (x-xc)*R*sin(beta/2)
end
quindi dalla nostra funzione e' sufficiente chiamare la funzione segmento una volta passandogli xi ed una volta xf, e fare la differenza tra i due valori restituiti
A1 = segmento (xc, R , xi) - segmento (xc, R , xf)
-
Adesso non ci rimane altro che capire dove e come questa funzione possa andare in errore ed inserire tutti i controlli necessari.
la prima cosa da verificare e' ovviamente la conguenza dei dati.
- la funzione non deve accettare valori negativi o nulli del raggio, quindi inseriremo la riga:
if R<=0 then concio=0
in questo modo la funzione ci restituisce un valore nullo, ma se vogliamo un avviso che ci faccia comprendere che abbiamo passato un valore privo di senso, e' sufficiente far restituire la stringa "NV" o altro a nostro piacimento.
- i valori di xi e xf devono essere tali che xf>xi
inseriremo quindi la riga:
if xf-xi <=0 then concio=0
anche qui vale la stessa considerazione precedente
adesso andiamo alle aberrazioni
... segue ...
-
se procedi con la strada delle intersezioni non risolvi il problema, intanto aggiungi l'approssimazione considerando un trapezio cio' che invece non è.
Tempo fà ho provato anche io a ragionare con le intersezioni sia tra le verticali ed il cerchio e sia tra il pendio (o superfici di separazione o linea di falda) ed il cerchio per delimitare il campo dove procedere con la suddivisione in conci. Il problema della posizione di un segmento rispetto ad un cerchio non e' di facile ed immediata soluzione.
E poi, se ritieni sia una valida via, perch' non inizi a scrivere formule?
Ti ricordo che solo chi inizia puo' terminare.
Vedo che su questo problema ci avevi sbattutto la testa precedentemente, ed effettivamente con il mio metodo si commette una approssimazione che è tanto più marcata quanto maggiori sono le distanze tra i due punti successivi del pendio. Sto pensando ora ad una soluzione alternativa che permetta di sfruttare semrpe il mio ragionamento (che potrebbe semplificare di molto l'algoritmo), ma prima di dare formule preferisco ragionarci su, perchè, come dici giustamente tu, solo chi inizia può terminare, solo abbiamo tempi e modi diversi di iniziare :)
-
Quindi, riassumendo quanto fin qui analizzato, abbiamo una funzione che pressappoco dovrebbe essere:
Function aRccos(num As Double) As Double
aRccos = Atn(-num / Sqr(-num * num + 1)) + 2 * Atn(1)
End Function
'-----
Function segmento(xc As Double, R As Double, x As Double) As Double
Dim beta As Double
beta = 2 * aaRccos((x - xc) / R)
segmento = R ^ 2 * beta / 2 - (x - xc) * R * Sin(beta / 2)
End
'-----
Public Function concio(xc As Double, yc As Double, R As Double, _
xi As Double, xf As Double, _
yi As Double, yf As Double, flag As Double) As Variant
Dim A As Double
Dim alfa As Double
Dim ym As Double
ym = (yi + yf) / 2
' controllo che il raggio non sia minore o uguale a zero
If R <= 0 Then
concio = 0
Exit Function
End If
' controllo che xf sia maggiore di xi
If xf - xi <= 0 Then
concio = 0
Exit Function
End If
' controllo che xi ed xf siano all'interno deld iametro del cerchio
If xf <= xc - R Or xi >= xc + R Then
concio = 0
Exit Function
End If
A = (segmento(xc, R, xi) - segmento(xc, R, xf)) / 2 - (xf - xi) * (yc - ym)
Select Case flag
Case 1
concio = A
Case 2
concio = alfa
Case Else
concio = 0
End Select
End Function
Ovviamente devo ancora sviluppare la parte di calcolo dell'angolo alfa di inclinazione della tangente.
La funzione arcCos si rende necessaria poiche non e' una funzione inclusa in VBA.
Come vedete bastano davvero pochissime istruzioni cosa praticamente impossibile se si pensa di ricorrere all'intersezione delle verticali col cerchio ed al calcolo dell'are del trapezio.
-
Procediamo adesso con la determinazione dell'angolo alfa di inclinazione della tangente rispetto all'orizzontale e dello sviluppo dell'arco di base del concio.
Consideriamo pertanto la seguente figura:
(http://img135.imageshack.us/img135/4148/alfaoo.jpg)
Qui le cose sembrano complicarsi ma invece analizzando piu attentamente il tutto, la determinazione di alfa e di B diventa banale.
Infatti l'angolo alfa, rappresentato in bianco in basso, e' uguale a quello rappresentato in rosso in alto per questioni di similitudine tra triangoli. Lascio a voi verificare questa asserzione.
Indicando con delta.i e delta.f rispettivamente l'angolo rispetto alla verticale formato dai raggi che congiungono il punto iniziale e finale del concio, si ha:
delta.i =arcsen[ (xi-xc)/R]
delta.f =arcsen[ (xf-xc)/R]
indicando poi con delta l'angolo formato dai due raggi si ha:
delta= delta.f - delta.i
e l'angolo alfa è fornito dalla espressione:
alfa = delta.i + delta/2
mentre lo sviluppo dell'arco di base del concio vale:
B= delta*R
semplice no?
-
Si, ma i terreni difficilmente sono monostrato e noi che ce ne facciamo di questa funzione nel caso in cui vi siano due strati?
(http://img513.imageshack.us/img513/4822/duestrati.jpg)
basta chiamare due volte la funzione e quindi determinare il peso del concio cosi come segue:
P= gamma1*[concio(xc,yc,R,xi,xf, yi1, yf1,1) - concio(xc,yc,R,xi,xf, yi2, yf2,1)] + gamma2* concio(xc,yc,R,xi,xf, yi2, yf2,1)
e se gli strati fossereo tre?
P= gamma1*[concio(xc,yc,R,xi,xf, yi1, yf1,1) - concio(xc,yc,R,xi,xf, yi2, yf2,1)] + gamma2*[concio(xc,yc,R,xi,xf, yi2, yf2,1) - concio(xc,yc,R,xi,xf, yi3, yf3,1)] + gamma3* concio(xc,yc,R,xi,xf, yi3, yf3,1)
e cosi via.
Eppero' pero' puo capitare che a partire da un certo strato in poi questi non siano coinvolti dal cerchio di scivolamento, come rappresentato nella figura che segue
(http://img707.imageshack.us/img707/4725/trestrati.jpg)
qui l'area campita in rosso sarebbe negativa.
Bene allora e' sufficiente tornare nella nostra funzione concio e dire che quando l'area A e' negativa, ci deve restituire valore nullo, ed abbiamo risolto.
Cosi ce ne freghiamo di verificare a monte se lo strato e' coinvolo o meno nell'equilibrio e la chiamiamo ugualmente.
-
Vediamo adesso qualche caso che io chiamo con "aberrazioni"
uno di questi puo' essere quello rappresentato in figura
(http://img193.imageshack.us/img193/1531/aberrazione1.jpg)
qui, come e' possibile vedere, l'area del concio delimitato dalle verticali in rosso e' maggiore dell'area del segmento circolare delimitato dalle due verticali suddette, ed anche i conci successivi
Questo caso non ha senso di esistere poichè se consideriamo di togliere la parte che scivola via , quella che rimane non puo' essere in equilibrio.
(http://img46.imageshack.us/img46/6673/aberrazione2.jpg)
La parte di terreno "a sbalzo" che sta oltre la verticale condotta per x=xc+R e che sta al di sopra dell'orizzontale condotta per yc, non può stare in equilibrio.
Cio' significa che l'arco di cerhio che abbiamo considerato non puo' essere un cerchio di scivolamento.
In questo caso dovremo procedere secondo una delle due alternative:
a- coreggere il cerchio di scivolamento considerando l'arco di cerchio fino al punto P[ (xc+R) ; yc ] e una retta verticale (?? ma sarebbe scelta arbitraria poichè la parete verticale di terreno non starebbe in equilibrio) a partire da questo punto;
b- scartare il cerchio considerando che non puo' essere superficie di scivolamento e passare al successivo. Io, e credo anche la maggior parte di programmi commericlai che fanno la stessa cosa, opto per la seconda opzione.
occorre capire, pertanto, quando si verifica questa condizione.
alla prossima.
-
sto seguendo con molto interesse la tua esposizione afazio, in quanto sto iniziando a dilettarmi con il vba in excel, devo dire che sei stato chiarissimo nell'esposizione, complimenti davvero :piacere:
-
ma ovviamente si sta facendo un qualcosa con il punto C fisso, giusto?
ebbene, non si riesce a fare una funzione in cui si determina il punto C incognito che risulta maggiormente dimensionante?
in che dominio ha senso valutare C?
-
Una volta lanciata questa funzione, puo' andare alla ricerca, dato un insieme di punti, della superficie critica attraverso iterazioni.
-
ma ovviamente si sta facendo un qualcosa con il punto C fisso, giusto?
ebbene, non si riesce a fare una funzione in cui si determina il punto C incognito che risulta maggiormente dimensionante?
in che dominio ha senso valutare C?
cos'e' sto punto C?
-
Una volta lanciata questa funzione, puo' andare alla ricerca, dato un insieme di punti, della superficie critica attraverso iterazioni.
Si, ma ancora non e' finita. Occorre risolvere ancora parecchi problemi.
Ma piano piano se affrontati al nocciolo si puo' riuscire a fare qualcosa "in casa" davvero buono.
Tu sei certo di riuscire a creare una interfaccia grafica senza tanti fronzoli in grado di rappresentare il tutto?
Io posso riuscirci in excel utilizzando i grafici oppure far aprire autocad da excel col disegno del pendio e dei cerhi.
-
ma ovviamente si sta facendo un qualcosa con il punto C fisso, giusto?
ebbene, non si riesce a fare una funzione in cui si determina il punto C incognito che risulta maggiormente dimensionante?
in che dominio ha senso valutare C?
ecco, adesso capisco
Con punto C intendi il centro del cerchio.
No, come vedi xc e yc sono dati come variabili. La funzione sarà chiamata passandogli ogni volta le coordinate del centro che sarà variabile.
-
ma ovviamente si sta facendo un qualcosa con il punto C fisso, giusto?
ebbene, non si riesce a fare una funzione in cui si determina il punto C incognito che risulta maggiormente dimensionante?
in che dominio ha senso valutare C?
ecco, adesso capisco
Con punto C intendi il centro del cerchio.
No, come vedi xc e yc sono dati come variabili. La funzione sarà chiamata passandogli ogni volta le coordinate del centro che sarà variabile.
sì intendo il centro di coordinate xc e yc.
capisco come ottimizzare il C sia difficile, ma molti programmi geotecnici superano il problema discretizzando il dominio d'esistenza del C.
una sorta di griglia in cui il punto C si trova al primo iter nel nodo 1, al secondo iter nel nodo 2...
compito del progettista è scegliere la maglia della griglia.
altro problema è scegliere il raggio..
-
Una volta lanciata questa funzione, puo' andare alla ricerca, dato un insieme di punti, della superficie critica attraverso iterazioni.
Si, ma ancora non e' finita. Occorre risolvere ancora parecchi problemi.
Ma piano piano se affrontati al nocciolo si puo' riuscire a fare qualcosa "in casa" davvero buono.
Tu sei certo di riuscire a creare una interfaccia grafica senza tanti fronzoli in grado di rappresentare il tutto?
Io posso riuscirci in excel utilizzando i grafici oppure far aprire autocad da excel col disegno del pendio e dei cerhi.
Di sicuro al mondo c'e' solo la morte...da poco sto prendendo confidenza con le GDI+, ma come dici tu, solo chi comincia può terminare quindi...con molta buona volontà si può fare tutto. Appena stendi per intero il codice VB, lo converto in c#e vedo cosa si può fare.
-
Seguo anche io con interesse il post. interessantissimo.
Complimenti :ook:
-
ma ovviamente si sta facendo un qualcosa con il punto C fisso, giusto?
ebbene, non si riesce a fare una funzione in cui si determina il punto C incognito che risulta maggiormente dimensionante?
in che dominio ha senso valutare C?
ecco, adesso capisco
Con punto C intendi il centro del cerchio.
No, come vedi xc e yc sono dati come variabili. La funzione sarà chiamata passandogli ogni volta le coordinate del centro che sarà variabile.
sì intendo il centro di coordinate xc e yc.
capisco come ottimizzare il C sia difficile, ma molti programmi geotecnici superano il problema discretizzando il dominio d'esistenza del C.
una sorta di griglia in cui il punto C si trova al primo iter nel nodo 1, al secondo iter nel nodo 2...
compito del progettista è scegliere la maglia della griglia.
altro problema è scegliere il raggio..
Scusa Massimo, ma sei molto avanti.
Qui si stanno costruendo le funzioni basilari che serviranno POi per i processi di ottimizzazione e di ricerca della superficie critica.
Cio che dici tu NON SI PUo' FARE con una semplice funzione bensi con un programma intero. Ed il programma alla fine altro non e' che tutta una serie di funzioni e procedure.
-
intorrompo le quotate perchè stava diventando illeggibile.
non vedo il problema. che sia legato al fatto che non del vba non ne ho una mezza idea? :firuli:
penso che se si riuscirà ad ottenere una funzione, non vedo perchè essa non possa essere integrata in un ciclo for in cui ogni iter coinciderà con un Ci e ad ogni ciclo si valuterà un fattore di sicurezza e alla fine la stabilità globale avrà un fattore di sicurezza pari al minimo fattore di sicurezza calcolato.
-
intorrompo le quotate perchè stava diventando illeggibile.
non vedo il problema. che sia legato al fatto che non del vba non ne ho una mezza idea? :firuli:
penso che se si riuscirà ad ottenere una funzione, non vedo perchè essa non possa essere integrata in un ciclo for in cui ogni iter coinciderà con un Ci e ad ogni ciclo si valuterà un fattore di sicurezza e alla fine la stabilità globale avrà un fattore di sicurezza pari al minimo fattore di sicurezza calcolato.
Il cilco for sarà esterno alle funzioni e farà parte del programma principale.
Ripeto, non puo' essere condotto all'interno della funzione indipendentemente che essa sia scritta in VBA o in C++, poiche per poter fare cio' occorrerebbe passare una infinita di variabili alla funzione.
-
Pensiamo adesso su come operare la suddivisione in conci del pendio.
La suddivisione dovrebbe partire dal primo punto di intersezione del profilo col cerchio fino all'ultimo punto di intersezione.
Occorrerebbe pertanto determinarsi tali punti di intersezione. La cosa risulta alquanto ardua, poiche occorrerebbe determinarsi i punti di intersezioni di "una spezzata" con un cerchio determinando per ogni segmento costituente la polilinea, la sua posizione reciproca rispetto al cerchio e capire quele di essi interseca il cerchio se lo interseca.
Non ho trovato la soluzione di questa via.
Allora conviene pensare ad una suddivisione del tratto di pendio compreso tra xc-R ed Xc+R (cioe' il tratto di pendio coinvolto dal diametro del cerchio) magari stabilendo un numero n di suddivisioni (o in alternativa stabilire una dimensione massima del concio ed in base a questa determinarsi il numero di suddivisioni.
(http://img683.imageshack.us/img683/9329/conci.jpg)
Cosi facendo superiamo il problema delle intersezioni ed abbiamo comunque delimitato il campo di scansione dei conci.
-
Pensiamo adesso su come operare la suddivisione in conci del pendio.
La suddivisione dovrebbe partire dal primo punto di intersezione del profilo col cerchio fino all'ultimo punto di intersezione.
Occorrerebbe pertanto determinarsi tali punti di intersezione. La cosa risulta alquanto ardua, poiche occorrerebbe determinarsi i punti di intersezioni di "una spezzata" con un cerchio determinando per ogni segmento costituente la polilinea, la sua posizione reciproca rispetto al cerchio e capire quele di essi interseca il cerchio se lo interseca.
Non ho trovato la soluzione di questa via.
Allora conviene pensare ad una suddivisione del tratto di pendio compreso tra xc-R ed Xc+R (cioe' il tratto di pendio coinvolto dal diametro del cerchio) magari stabilendo un numero n di suddivisioni (o in alternativa stabilire una dimensione massima del concio ed in base a questa determinarsi il numero di suddivisioni.
(http://img683.imageshack.us/img683/9329/conci.jpg)
Cosi facendo superiamo il problema delle intersezioni ed abbiamo comunque delimitato il campo di scansione dei conci.
Partendo dallo schema sopra riportato vediamo adesso come modificare la nostra funzione concio per adattarla a tutti i casi che possiamo riscontrare.
Il primo caso, che in una certa misura abbiamo gia visto, e' quello per cui il concio, pur interno al diametro si trova esterno al cerchio
(http://img252.imageshack.us/img252/9744/conci1.jpg)
In questo caso come gia detto, l'area risulta essere negativa e quindi basta scrivere nella nostra funzione:
if A<0 the A=0
-
Pensiamo adesso su come operare la suddivisione in conci del pendio.
La suddivisione dovrebbe partire dal primo punto di intersezione del profilo col cerchio fino all'ultimo punto di intersezione.
Occorrerebbe pertanto determinarsi tali punti di intersezione. La cosa risulta alquanto ardua, poiche occorrerebbe determinarsi i punti di intersezioni di "una spezzata" con un cerchio determinando per ogni segmento costituente la polilinea, la sua posizione reciproca rispetto al cerchio e capire quele di essi interseca il cerchio se lo interseca.
Non ho trovato la soluzione di questa via.
Allora conviene pensare ad una suddivisione del tratto di pendio compreso tra xc-R ed Xc+R (cioe' il tratto di pendio coinvolto dal diametro del cerchio) magari stabilendo un numero n di suddivisioni (o in alternativa stabilire una dimensione massima del concio ed in base a questa determinarsi il numero di suddivisioni.
(http://img683.imageshack.us/img683/9329/conci.jpg)
Cosi facendo superiamo il problema delle intersezioni ed abbiamo comunque delimitato il campo di scansione dei conci.
Partendo dallo schema sopra riportato vediamo adesso come modificare la nostra funzione concio per adattarla a tutti i casi che possiamo riscontrare.
Il primo caso, che in una certa misura abbiamo gia visto, e' quello per cui il concio, pur interno al diametro si trova esterno al cerchio
(http://img252.imageshack.us/img252/9744/conci1.jpg)
In questo caso come gia detto, l'area risulta essere negativa e quindi basta scrivere nella nostra funzione:
if A<0 then A=0
Altro caso particolare è quello per cui avendo adottato quel sistema di suddivisione in conci, tra gli estremi superiori del concio cada un vertice del profilo, come in figura che segue
(http://img188.imageshack.us/img188/2804/conci2.jpg)
Attualmente la funzione calcola l'area che ho indicto con A. Se non apportassimo alcuna modifica avremmmo un errore pari all'area che ho indicato con A' sia in negativo che in positivo.
Occorre quindi procedere ad una variazione che ci costa solo l'inserimento di altri due parametri in ingresso alla nostra funzione concio.
I due parametri sono la ascissa del vertice interno e la sua ordinata, Li indico con
xv, yv
-
ihihihih
quanto mi date per proseguire queste lezioncine?
-
ihihihih
quanto mi date per proseguire queste lezioncine?
Dipende... rilasci l'attestato di frequenza alla fine?
-
Altro caso particolare è quello per cui avendo adottato quel sistema di suddivisione in conci, tra gli estremi superiori del concio cada un vertice del profilo, come in figura che segue
(http://img188.imageshack.us/img188/2804/conci2.jpg)
Attualmente la funzione calcola l'area che ho indicto con A. Se non apportassimo alcuna modifica avremmmo un errore pari all'area che ho indicato con A' sia in negativo che in positivo.
Occorre quindi procedere ad una variazione che ci costa solo l'inserimento di altri due parametri in ingresso alla nostra funzione concio.
I due parametri sono la ascissa del vertice interno e la sua ordinata, Li indico con
xv, yv
Come prima soluzione veine subito da paensare di cambiare la suddivisione in conci del pendio ed inserire anche le verticali per i vertici del profilo.
Questa soluzione, seppur praticabile, comporta che dovremmo apportare ulteriori suddivisioni dovute ai vertici di ciascuno strato sottostante, i cui vertici non per forza coincidono con quelli della superficie topografica, ed eventualmente anche i vertici della linea di falda se presente.
No. Abbandoniamo pertanto questa idea e sobbarchiamoci l'aggiunta dei due parametri xv e yv
Potremmo pensare di far calcolare l'area A e poi sommare o sottrarre quella del triangolo campito.
In effetti la formula dell'area effettiva del concio che indico con Ac sarebbe pari ala somma dei seguenti termini:
+ A area determinata come se non ci fosse il verticie del profilo nel mezzo
+ (xf-xi)*(yf-yi)/2 area del triangolo compreso tra la linea che congiunge i due estrei superiori del concio e la orizzontale passante per l'ordinata yf
- (xv - xi )*(yv - yi)/2 area del triangolo compreso tra xi. xv, yi, yv
- (xf-xv)*(yf-yv)/2 area del triangolo compreso tra xv, xf, yv, yf
- (xv-xi)*(yf-yv) area del rettangolino compreso tra xi, xv, yv, yf
Se non e' chiaro ditemelo che vedro' di predisporre una figura appositamente
Altra soluzione sarebbe quella di considerare due segmenti circolari delimitati: il primo delimitato dalle verticali passanti per xi e xv, ed il secondo per le verticali passanti per xv ed xf. Cosa che gia sappiamo fare
... segue ...
-
Altro caso particolare è quello per cui avendo adottato quel sistema di suddivisione in conci, tra gli estremi superiori del concio cada un vertice del profilo, come in figura che segue
(http://img188.imageshack.us/img188/2804/conci2.jpg)
Attualmente la funzione calcola l'area che ho indicto con A. Se non apportassimo alcuna modifica avremmmo un errore pari all'area che ho indicato con A' sia in negativo che in positivo.
Occorre quindi procedere ad una variazione che ci costa solo l'inserimento di altri due parametri in ingresso alla nostra funzione concio.
I due parametri sono la ascissa del vertice interno e la sua ordinata, Li indico con
xv, yv
Come prima soluzione veine subito da paensare di cambiare la suddivisione in conci del pendio ed inserire anche le verticali per i vertici del profilo.
Questa soluzione, seppur praticabile, comporta che dovremmo apportare ulteriori suddivisioni dovute ai vertici di ciascuno strato sottostante, i cui vertici non per forza coincidono con quelli della superficie topografica, ed eventualmente anche i vertici della linea di falda se presente.
No. Abbandoniamo pertanto questa idea e sobbarchiamoci l'aggiunta dei due parametri xv e yv
Potremmo pensare di far calcolare l'area A e poi sommare o sottrarre quella del triangolo campito.
In effetti la formula dell'area effettiva del concio che indico con Ac sarebbe pari ala somma dei seguenti termini:
+ A area determinata come se non ci fosse il verticie del profilo nel mezzo
+ (xf-xi)*(yf-yi)/2 area del triangolo compreso tra la linea che congiunge i due estrei superiori del concio e la orizzontale passante per l'ordinata yf
- (xv - xi )*(yv - yi)/2 area del triangolo compreso tra xi. xv, yi, yv
- (xf-xv)*(yf-yv)/2 area del triangolo compreso tra xv, xf, yv, yf
- (xv-xi)*(yf-yv) area del rettangolino compreso tra xi, xv, yv, yf
Se non e' chiaro ditemelo che vedro' di predisporre una figura appositamente
Altra soluzione sarebbe quella di considerare due segmenti circolari delimitati: il primo delimitato dalle verticali passanti per xi e xv, ed il secondo per le verticali passanti per xv ed xf. Cosa che gia sappiamo fare
... segue ...
Ma siccome dove ci sta una pentola spesso ci sta anche un coperchio ecco la sorpresa:
E se tra le due verticali che delimitano il concio ci stessero due vertici del profilo?
(http://img521.imageshack.us/img521/8452/compl.jpg)
Ehh no! Minkia, questo non dovevate farmelo
Posso anche pensare di aggiungere altri due parametri nella mia funzione, ma chi mi dice che qualche altro diavolo non ci aggiunga un terzo o un quarto vertice?
Ovviamente questa possibilita e' tanto piu probabile che si verifichi tanto piu grande e' il passo di suddivisione. Certamente non posso pensare di inserire un numero indefinito di parametri per risolvere il problema.
Quindi dobbiamo risolvere a monte questo problema e fissare il passo di suddivisione dei conci in modo tale che non vi siano piu di un vertice all'interno dello stesso concio.
Basta pertanto fissare come pmax il valore del piu piccolo dei segmenti in cui e' schematizzato il profilo. Ovviamente nella sua componente orizzontale includendo anche le superfici di separazione tra gli strati e la linea di falda.
-
Riassumendo quanto analizzato fino ad adesso, abbiamo la seguente funzione:
Function aRccos(num As Double) As Double
aRccos = Atn(-num / Sqr(-num * num + 1)) + 2 * Atn(1)
End Function
'-----
Function arCsin(num As Double) As Double
arCsin = Atn(num / Sqr(-num * num + 1))
End Function
'------
Function segmento(xc As Double, R As Double, x As Double) As Double
Dim beta As Double
beta = 2 * aRccos((x - xc) / R)
segmento = R ^ 2 * beta / 2 - (x - xc) * R * Sin(beta / 2)
End
'-----
Public Function concio(xc As Double, yc As Double, R As Double, _
xi As Double, xf As Double, _
yi As Double, yf As Double, _
xv As duble, yv As Double, flag As Double) As Variant
Dim A As Double ' variabile per il calcolo dell'area
Dim B As Double 'variabile per il calcolo dello sviluppo dell'arco di base
Dim alfa As Double 'variabile per il calcolo dell'angolo di inclinazione della tangente
Dim ym As Double
ym = (yi + yf) / 2
' controllo che il raggio non sia minore o uguale a zero
If R <= 0 Then
concio = 0
Exit Function
End If
' controllo che xf sia maggiore di xi
If xf - xi <= 0 Then
concio = 0
Exit Function
End If
' controllo che xi ed xf siano all'interno del diametro del cerchio
If xf < xc - R Or xi > xc + R Then
concio = 0
Exit Function
End If
' controllo che xv sia all'interno di xi xf, nel caso cada all'esterno
' lo assumo pari ad xi
If xv < xi Or xv > xf Then
xv = xi
yv = yi
End If
' calcolo l'area sottesa dalla congiungente yi-yf
A = (segmento(xc, R, xi) - segmento(xc, R, xi)) / 2 - (xf - xi) * (yc - ym)
' adesso considero la presenza del vertice intermedio
A = A + (xf - xi) * (yf - yi) / 2 - (xv - xi) * (yv - yi) / 2 - (xf - xi) * (yf - yv) / 2 - (xv - xi) * (yf - yv)
' controllo area negativa
If A < 0 Then
concio = 0
End If
' calcolo dell'angolo alfa
alfa = arCsin((xi - xc) / R) + (arCsin((xi - xc) / R) - arCsinn((xf - xc) / R)) / 2
' calcolo dello sviluppo dell'arco di base
B = R * arCsin((xi - xc) / R) - arCsin((xf - xc) / R)
Select Case flag
Case 1
concio = A
Case 2
concio = alfa
Case 3
concio = B
Case Else
concio = 0
End Select
End Function
-
Riassumendo quanto analizzato fino ad adesso, abbiamo la seguente funzione:
Function aRccos(num As Double) As Double
aRccos= Atn(-num / Sqr(-num * num + 1)) + 2 * Atn(1)
End Function
'-----
Function arCsin(num As Double) As Double
arCsin = Atn(num / Sqr(-num * num + 1))
End Function
'------
Function segmento(xc As Double, R As Double, x As Double) As Double
Dim beta As Double
beta = 2 * aRccos((x - xc) / R)
segmento = R ^ 2 * beta / 2 - (x - xc) * R * Sin(beta / 2)
End
'-----
Public Function concio(xc As Double, yc As Double, R As Double, _
xi As Double, xf As Double, _
yi As Double, yf As Double, _
xv As duble, yv As Double, flag As Double) As Variant
Dim A As Double ' variabile per il calcolo dell'area
Dim B As Double 'variabile per il calcolo dello sviluppo dell'arco di base
Dim alfa As Double 'variabile per il calcolo dell'angolo di inclinazione della tangente
Dim ym As Double
ym = (yi + yf) / 2
' controllo che il raggio non sia minore o uguale a zero
If R <= 0 Then
concio = 0
Exit Function
End If
' controllo che xf sia maggiore di xi
If xf - xi <= 0 Then
concio = 0
Exit Function
End If
' controllo che xi ed xf siano all'interno del diametro del cerchio
If xf < xc - R Or xi > xc + R Then
concio = 0
Exit Function
End If
' controllo che xv sia all'interno di xi xf, nel caso cada all'esterno
' lo assumo pari ad xi
If xv < xi Or xv > xf Then
xv = xi
yv = yi
End If
' calcolo l'area sottesa dalla congiungente yi-yf
A = (segmento(xc, R, xi) - segmento(xc, R, xi)) / 2 - (xf - xi) * (yc - ym)
' adesso considero la presenza del vertice intermedio
A = A + (xf - xi) * (yf - yi) / 2 - (xv - xi) * (yv - yi) / 2 - (xf - xi) * (yf - yv) / 2 - (xv - xi) * (yf - yv)
' controllo area negativa
If A < 0 Then
concio = 0
End If
' calcolo dell'angolo alfa
alfa = arCsin((xi - xc) / R) + (arCsin((xi - xc) / R) - arCsinn((xf - xc) / R)) / 2
' calcolo dello sviluppo dell'arco di base
B = R * arCsin((xi - xc) / R) - arCsin((xf - xc) / R)
Select Case flag
Case 1
concio = A
Case 2
concio = alfa
Case 3
concio = B
Case Else
concio = 0
End Select
End Function
Dove va in errore questa funzione?
All'inizio il valore di xi passato alla funzione e' pari, per il tipo di suddivisione adottato, proprio a:
xi=xc-R
mentre alla fine il valore di xf è pari a:
yf=xc+R
Vediamo allora cosa accade alle funzioni trigonometriche inverse
primo caso
arCsin((xi - xc) / R), ma essendo xi=xc-r si ha
arCsin((xc- R - xc) / R) =arCsin(-1)
e sappiamo che il risultato e' pari a -pi.greco/2
Ora, siccome noi abbiamo fatto ricorso ad una funzione apposita (non presente in VBA), per il calcolo dell'arcocoseno:
Function aRccos(num As Double) As Double
aRccos= Atn(-num / Sqr(-num * num + 1)) + 2 * Atn(1)
End Function
vediamo immeditamante che avendo passato il valore num=-1 si verifica un errore di divisione per zero, infatti
aRccos(-1) = Atn(1 / Sqr(-1+ 1)) + 2 * Atn(1) = Atn(1 / 0) + 2 * Atn(1)
la stessa cosa vale per la funzione arcoseno
Occorre pertanto procedere ad una correzione delle due funzioni, tale che restituiscano:
l'arcCos il valore di 0 o -pigreco quando si passa un valore di 1 o -1
l'arcSen il valore di pigreco/2 o -pigreco/2 quando si passa un valore di 1 o -1
-
A questo punto siamo quasi alla fine
ma cirestano da esaminare ancora alcuni casi particolari per i quali richiedo il vostro contributo in idee
(http://s4.postimage.org/45uo9.jpg) (http://www.postimage.org/image.php?v=aV45uo9)
(http://s4.postimage.org/45BSA.jpg) (http://www.postimage.org/image.php?v=aV45BSA)
(http://s1.postimage.org/D9Xg0.jpg) (http://www.postimage.org/image.php?v=gxD9Xg0)
-
Ho notato che premendo sul tasto stampa che si trova in coda alla serie di post si puo' ottenere un originale ed interessante manualetto.
Quel che rompe e' lo sfondo nero di autocad
Vedro per i prossimi post di inserire immagini con sfondo bianco.
saluti
-
stai notando una piccola parte delle cose che si possono fare in questo forum...se vuoi ed hai tempo, smanetta con tutte le funzioni permesse, troverai alcune cose molto interessanti (vedi wysiwyg editor che puoi abilitare dal tuo profilo) ;)
-
stai notando una piccola parte delle cose che si possono fare in questo forum...se vuoi ed hai tempo, smanetta con tutte le funzioni permesse, troverai alcune cose molto interessanti (vedi wysiwyg editor che puoi abilitare dal tuo profilo) ;)
ho provato a premere il tasto stampa ma le immagini non le vedo, mi esce il link (http://img130.imageshack.us/img130/4652/pendio.jpg (http://img130.imageshack.us/img130/4652/pendio.jpg))
c'è modo di visualizzare l'immagine?
grazie
-
quello e' un problema di imageshack, in quanto afazio (giustamente direi) usa le thumbmail per evitare che l'immagine sformi la pagina del forum.
-
Pensiamo adesso su come operare la suddivisione in conci del pendio.
La suddivisione dovrebbe partire dal primo punto di intersezione del profilo col cerchio fino all'ultimo punto di intersezione.
Occorrerebbe pertanto determinarsi tali punti di intersezione. La cosa risulta alquanto ardua, poiche occorrerebbe determinarsi i punti di intersezioni di "una spezzata" con un cerchio determinando per ogni segmento costituente la polilinea, la sua posizione reciproca rispetto al cerchio e capire quele di essi interseca il cerchio se lo interseca.
Non ho trovato la soluzione di questa via.
Allora conviene pensare ad una suddivisione del tratto di pendio compreso tra xc-R ed Xc+R (cioe' il tratto di pendio coinvolto dal diametro del cerchio) magari stabilendo un numero n di suddivisioni (o in alternativa stabilire una dimensione massima del concio ed in base a questa determinarsi il numero di suddivisioni.
(http://img683.imageshack.us/img683/9329/conci.jpg)
Cosi facendo superiamo il problema delle intersezioni ed abbiamo comunque delimitato il campo di scansione dei conci.
Ciao Afazio
non mi sembra difficile da risolvere il problema evidenziato in rosso, se ragioni intermini di distanze dal centro. Se la distanza del nodo i della polilinea è < del raggio e se la distanza del nodo i+1 è > (ovvero se accade il contrario) significa che il segmento della polilinea interseca il cerchio, o sbaglio? Dovrebbe essere abbastanza semplice il codice da scrivere. Ciao.
-
Occorrerebbe pertanto determinarsi tali punti di intersezione. La cosa risulta alquanto ardua, poiche occorrerebbe determinarsi i punti di intersezioni di "una spezzata" con un cerchio determinando per ogni segmento costituente la polilinea, la sua posizione reciproca rispetto al cerchio e capire quele di essi interseca il cerchio se lo interseca.
Non ho trovato la soluzione di questa via.
Ciao Afazio
non mi sembra difficile da risolvere il problema evidenziato in rosso, se ragioni intermini di distanze dal centro. Se la distanza del nodo i della polilinea è < del raggio e se la distanza del nodo i+1 è > (ovvero se accade il contrario) significa che il segmento della polilinea interseca il cerchio, o sbaglio? Dovrebbe essere abbastanza semplice il codice da scrivere. Ciao.
considera la seguente figura:
(http://s2.postimage.org/11B0v0.jpg) (http://www.postimage.org/image.php?v=Ts11B0v0)
col metodo del raggio/distanza i due segmenti (i-1) i ed i (i+1) verrebbero visti entrambi come esterni.
occorrerebbe pertanto considerare altra condizioneche potrebbe essere la distanza tra segmento e centro.
anche ricorrendo alla distanza tra cerchio e retta su cui giace il segmento non potremmo distinguere i due casi poiche in entrambi i casi abbiamo:
di>R; df>R dc<R
-
Occorrerebbe pertanto determinarsi tali punti di intersezione. La cosa risulta alquanto ardua, poiche occorrerebbe determinarsi i punti di intersezioni di "una spezzata" con un cerchio determinando per ogni segmento costituente la polilinea, la sua posizione reciproca rispetto al cerchio e capire quele di essi interseca il cerchio se lo interseca.
Non ho trovato la soluzione di questa via.
Ciao Afazio
non mi sembra difficile da risolvere il problema evidenziato in rosso, se ragioni intermini di distanze dal centro. Se la distanza del nodo i della polilinea è < del raggio e se la distanza del nodo i+1 è > (ovvero se accade il contrario) significa che il segmento della polilinea interseca il cerchio, o sbaglio? Dovrebbe essere abbastanza semplice il codice da scrivere. Ciao.
considera la seguente figura:
(http://s2.postimage.org/11B0v0.jpg) (http://www.postimage.org/image.php?v=Ts11B0v0)
col metodo del raggio/distanza i due segmenti (i-1) i ed i (i+1) verrebbero visti entrambi come esterni.
occorrerebbe pertanto considerare altra condizioneche potrebbe essere la distanza tra segmento e centro.
anche ricorrendo alla distanza tra cerchio e retta su cui giace il segmento non potremmo distinguere i due casi poiche in entrambi i casi abbiamo:
di>R; df>R dc<R
tempo fa avevo individuato una via che ritenevo essere risolutiva che si basava su questo ragionamento:
- i segmenti che possono intersecare il cerchio sono solo e soltanto quelli per cui la distanza della retta su cui giace il segmento e' inferiore al raggio. I rimanenti segmenti sono certamente esterni.
- quindi pensavo di fare una prima cernita tra tuti i segmenti della polilinea applicando questo criterio
- poi avevo pensato di determinare per ciascuno dei segmenti la cui retta godeva di quella caratteristica (distanza minore del raggio) i due punti di intersezione e poi applicare un criterio che poteva farmi capire se gli estremi del segmento erano entrambi esterni entrambi interni o uno interno ed uno esterno,
- la condizione di intersezione poteva essere solo se si verificava il primo ed il terzo caso.
- in ogni caso la soluzione si presentava alquanto laboriosa.
Anche perche avrei dovuto applicare tutti questi ragionamenti anche ale sottostanti superfici di separazione tra gli strati ed alla linea di falda, e poi anche avebdo individuato tuti i punti di intersezione tra varie polilinea e cerchio, la suddivisione che sarebbe partita dal primo punto di intersezione del pendio col cerhio fino al secondo punto di intersezione, non poteva tenere conto della posizione dei punti di intersezione di tutte le superfici di separazione e di tutti i vertici di tutte le polilinee.
Per questo dopo diverse settimane e diversi chili di fogli formato A4 da riciclo, abbandonai l'idea per cercare altra soluzione.
-
Ciao Afazio
non mi sembra difficile da risolvere il problema evidenziato in rosso, se ragioni intermini di distanze dal centro. Se la distanza del nodo i della polilinea è < del raggio e se la distanza del nodo i+1 è > (ovvero se accade il contrario) significa che il segmento della polilinea interseca il cerchio, o sbaglio? Dovrebbe essere abbastanza semplice il codice da scrivere. Ciao.
In ogni caso mi hai dato una idea. vediamo se puo portare alla soluzione.
Ipotizziamo per adesso che non ricorra il caso che pur essendo gli estremi entrambi esterni il segmento che li unisce non intersechi il cerchio. Cioè mettiamoci nel caso in cui i due vertici siano uno interno ed uno esterno
In questa situazione vi sarà certamente un punto di intersezione tra il segmento superiore del concio e il cerchio
Trattasi di determinare proprio questo punto e poi sostutire, prima del calcolo dell'area, al valore di (xi;yi) (o di xf a seconda del caso) proprio le coordinate (x;y) del punto di intesezione.
(http://img39.imageshack.us/img39/7327/intersez.jpg)
inizio pertanto col determinare le due distanze di e df
di=radq[ (xc-xi)² + (yc-yi)² ]
df=radq[ (xc-xf)² + (yc-yf)² ]
nel caso in cui si abbia:
di>R e df<R , che e' il caso della figura, fisso un punto generico (x;y) interno al segmento superiore del concio e mi determino la distanza d
d=radq[ (xc-x)² + (yc-y)² ]
e confronto questa distanza col raggio. Variero il punto (x;y) finche non ottengo l'uguaglianza
radq[ (xc-x)² + (yc-y)² ] =R
la coppia (x;y) che soddisfa la precedente equazione e' quella del punto di intersezione.
Posso procedere secondo il metodo della bisezione:
- scelgo il punto medio del segmento superiroe del concio:
x= (xf-xi)/2
Y= (yf-yi)/2
determino d e la cofronto con R. Se d e' maggiore di R, allora fisso come punto iniziale del tratto superiore il punto medio precedente e procedo nuovamente seguendo la procedura, se invece e' minore del raggio, allora fisso come estremo finale il punto medio e procedo con la successiva bisezione.
Ovviamente occorrerà fissare una tolleranza quindi il confronte sarà in base alla:
if radq[ (xc-x)² + (yc-y)² ] - R < epsilon
oppure nel caso inverso
if radq[ (xc-x)² + (yc-y)² ] - R > epsilon
alla fine avrò ottenuto le coordinate del punto di intersezione e gli estremi della parte superiore del concio che ricadono uno sul cerchio e l'altro all'interno.
-
In ogni caso mi hai dato una idea. vediamo se puo portare alla soluzione.
Ipotizziamo per adesso che non ricorra il caso che pur essendo gli estremi entrambi esterni il segmento che li unisce non intersechi il cerchio. Cioè mettiamoci nel caso in cui i due vertici siano uno interno ed uno esterno
In questa situazione vi sarà certamente un punto di intersezione tra il segmento superiore del concio e il cerchio
Trattasi di determinare proprio questo punto e poi sostutire, prima del calcolo dell'area, al valore di (xi;yi) (o di xf a seconda del caso) proprio le coordinate (x;y) del punto di intesezione.
(http://img39.imageshack.us/img39/7327/intersez.jpg)
inizio pertanto col determinare le due distanze di e df
di=radq[ (xc-xi)² + (yc-yi)² ]
df=radq[ (xc-xf)² + (yc-yf)² ]
nel caso in cui si abbia:
di>R e df<R , che e' il caso della figura, fisso un punto generico (x;y) interno al segmento superiore del concio e mi determino la distanza d
d=radq[ (xc-x)² + (yc-y)² ]
e confronto questa distanza col raggio. Variero il punto (x;y) finche non ottengo l'uguaglianza
radq[ (xc-x)² + (yc-y)² ] =R
la coppia (x;y) che soddisfa la precedente equazione e' quella del punto di intersezione.
Posso procedere secondo il metodo della bisezione:
- scelgo il punto medio del segmento superiroe del concio:
x= (xf-xi)/2
Y= (yf-yi)/2
determino d e la cofronto con R. Se d e' maggiore di R, allora fisso come punto iniziale del tratto superiore il punto medio precedente e procedo nuovamente seguendo la procedura, se invece e' minore del raggio, allora fisso come estremo finale il punto medio e procedo con la successiva bisezione.
Ovviamente occorrerà fissare una tolleranza quindi il confronte sarà in base alla:
if radq[ (xc-x)² + (yc-y)² ] - R < epsilon
oppure nel caso inverso
if radq[ (xc-x)² + (yc-y)² ] - R > epsilon
alla fine avrò ottenuto le coordinate del punto di intersezione e gli estremi della parte superiore del concio che ricadono uno sul cerchio e l'altro all'interno.
alla fine dovremmo pervenire ad una situazione simile a quella raffigurata sotto
(http://img43.imageshack.us/img43/3000/intersez1.jpg)
in cui si tratta di determinare l'area campita, lo sviluppo dell'arco segnato in rosso e l'angolo di inclinazione della tangente al punto medio dell'arco.
cosa che sappiamo fare senza dover modificare nulla di quanto gia scritto.
Prima di trasferire in codice il tutto, occorre pero' esaminare tutti i casi diversi possibili, catalogarli e vedere se possono compattarsi le procedure
Se vi ho annoiato, ditemelo, continuerò le mie divagazioni geometriche per conto mio.
saluti
-
qual noia, io mi sto facendo una cultura, grande afazio :clap: :ook:
-
Qualcuno potrebbe obiettare, a ragione, che con l'ultimo procedimento ho praticamente contraddetto quanto gia espresso precedentemente in merito al metodo delle intersezioni.
Pero' le situazioni sono diverse, poichè nel primo caso si trattava di determinare le intersezioni tra i segmenti costituenti il pendio o le superfici di separazione, mentre in quest'ultimo ragionamento si tratta di determinare l'intersezione tra il segmento superiore di un concio e il cerchio.
Nel primo caso i singoli tratti della polilinea possono avere uno sviluppo maggiore del diametro, poichè nessuno vieta di analizzare un pendio con superficie topografica costituita da parti ad una o due pendenze e nessuno vieta che la superficie di separazione tra due strati non possa essere un unica retta. Quindi potremmo avere a che fare con segmenti la cui ordine di grandezza e' quella del diametro del cerchio.
Nel secondo caso, invece, stiamo parlando di segmenti il cui sviluppo e' in ogni caso una piccola parte del diametro, dipendente dalla suddivisione in conci. Quindi abbiamo a che fare con segmenti che, mal ci vada, sono di un ordine di grandezza inferiori a quella del diametro del cerchio.
-
considera la seguente figura:
(http://s2.postimage.org/11B0v0.jpg) (http://www.postimage.org/image.php?v=Ts11B0v0)
col metodo del raggio/distanza i due segmenti (i-1) i ed i (i+1) verrebbero visti entrambi come esterni.
occorrerebbe pertanto considerare altra condizioneche potrebbe essere la distanza tra segmento e centro.
anche ricorrendo alla distanza tra cerchio e retta su cui giace il segmento non potremmo distinguere i due casi poiche in entrambi i casi abbiamo:
di>R; df>R dc<R
Ciao Afazio,
hai ragione, mi era sfuggito, ma col controllo sulla distanza centro cerchio/punto medio puoi spezzare la polilinea inserendo un punto in corrispondenza del punto medio del segmento, e poi procedere.
Ciao.
-
Siamo sempre li, Alberto.
Anche considerando il punto medio, quindi operando gia una sorta di suddivisione dei singoli tratti della polilinea in macroconci (quindi si potrebbe pensare di inserire due punti in corrispondenza dei terzi, oppure 4 o 5), in relazione alla lunghezza del segmento, il punto medio puo' risultare essere sia interno che esterno.
Edit By Gilean: Se i post sono consecutivi evitare di quotare l'intero messaggio, il post diverrà così più leggibile.
-
continuo con l'analisi dei vari casi possibili
ho gia visto il caso in cui il segmento superiore del concio interseca il cerchio "in salita"
(http://img43.imageshack.us/img43/3000/intersez1.jpg)
qui ricorrendo al metodo della bisezione determinavo il punto di intersezione e quindi potevo applicare il metodo gia descritto per il calcolo dell'area senza avere dubbi di commettere errori per il semplice fatto che la retta orizzontale condotta dal punto medio del segmento in rosso sta tutta dentro il cerchio
Nel caso in cui invece il tratto spueriore del concio intersecasse il cerchio "in discesa" come nella figura che segue
(http://img37.imageshack.us/img37/3203/nuovop.jpg)
ci puo venire il dubbio che il metodo descritto per il calcolo dell'area sottesa dal concio residuo [dopo esser passati dal punto (xfo;yfo) al punto (xf;yf) ] non ci fornisca il valore corretto dell'area per il fatto che l'orizzontale passante per il punto medio interseca anch'essa il cerchio.
E' dimostrabile pero' che l'area della parte ABC e' uguale all'area della parte DBE con semplici considerazioni geometriche che per illutrarledovrei postare almeno tre figure. Conducete da voi la verifica se lo ritenete necessario.
se ne conclude che in qualsiasi caso in cui il segmento superiroe interseca il cerchio, "in salita a sx" in salita a dx" in "discesa a sx" ed in "discesa a dx" il metodo descritto nella parte iniziale di questo 3d ci fornisce valori corretti e mai approssimati. Cio' significa che non abbiamo necessita di modificare quella parte di codice che ci calcola l'area ma solo aggiungere una parte di codice che ci controlla se il segmento interseca il cerchio e nel caso positivo ci determini i nuovi estremi del concio.
... segue...
-
Tuttavia dobbiamo porre particolare attenzione sul valore dello sviluppo dell'arco da prendere in considerazione, per intenderci quello che hochiamato con B all'inizio e che ci serve per determinarci la parte di resistenza a taglio dovuta alla coesione.
Infatti, nel caso in cui la polilinea a cui stiamo facendo riferimento e' quella delal superficie topografica siamo certo che non vi sono altre superfici che intersecano il cerchio, mentre nelcaso in cui il segmento in esame fosse quello di una supercicie di separazione tra due strati, allora lo sviluppo complessivo dell'arco e' quello riferito agli estremi originari e non a quelli ottenuti attraverso il processo di bisezione.
In questo caso dovremmo applicare la coesione del primo strato alla parte B-B' e la coesione dello strato inferiore alla parte B', in cui con B' ho indicato lo sviluppo dell'arco riferito al concio ridotto.
Con una immagine successiva illustrerò l'evenienza.
-
Siamo sempre li, Alberto.
Anche considerando il punto medio, quindi operando gia una sorta di suddivisione dei singoli tratti della polilinea in macroconci (quindi si potrebbe pensare di inserire due punti in corrispondenza dei terzi, oppure 4 o 5), in relazione alla lunghezza del segmento, il punto medio puo' risultare essere sia interno che esterno.
Edit By Gilean: Se i post sono consecutivi evitare di quotare l'intero messaggio, il post diverrà così più leggibile.
Pardon, nella fretta ho scritto una sciocchezza. Dunque: devo ottenere i punti di insersezione tra una polinea definita da n punti ed un cerchio con centro C(xc, yc) e raggio r.
1) l'equazione della circonferenza è (x-xc)^2+(y-yc)^2=r^2;
2) l'equazione della retta appartenente al generico segmento della polilinea è (y-yi)/(yf-yi)=(x-xi)/(xf-xi), salvo le singolarità (xi=xf o yi=yf): i ed f sono i punti iniziale e finale del segento considerato della polilinea;
E' un sistema di secondo grado con 2 incognite. Le soluzioni sono direttamente i punti di intersezione (se le radici sono reali e distinte). Se le radici coincidono ho un punto di tangenza.
Per sostituzione diventa un po' lunga ma ce la si fa abbastanza bene.
3) se le radici esistono devo vedere se sono interne o esterne al segmento considerato. Se sono interne ho beccato i punti d'intersezione (magari 1 sola è interna), se sono esterne le scarto e passo all'analisi del segmento successivo. La condizione affinché la radice sia interna è del tipo " xi<x and x<xf " (se sono interne le ascisse lo sono anche le ordinate essendo una retta, quindi mi limito a questo solo controllo).
Così dovrebbe funzionare anche se è un po' laborioso da implementare.
Ciao.
-
Eddai. Mi sono dimenticato un'altra roba.
Se xi=xf o se yi=yf (più prababile) beh l'equazione della retta si semplifica (tipo y=yi=yf) e le intersezioni (reali o complesse) col cerchio sono immediate (tipo x=xc+radq(r^2-(yi-yc)^2)).
Ciao.
-
Tuttavia dobbiamo porre particolare attenzione sul valore dello sviluppo dell'arco da prendere in considerazione, per intenderci quello che hochiamato con B all'inizio e che ci serve per determinarci la parte di resistenza a taglio dovuta alla coesione.
Infatti, nel caso in cui la polilinea a cui stiamo facendo riferimento e' quella delal superficie topografica siamo certo che non vi sono altre superfici che intersecano il cerchio, mentre nelcaso in cui il segmento in esame fosse quello di una supercicie di separazione tra due strati, allora lo sviluppo complessivo dell'arco e' quello riferito agli estremi originari e non a quelli ottenuti attraverso il processo di bisezione.
In questo caso dovremmo applicare la coesione del primo strato alla parte B-B' e la coesione dello strato inferiore alla parte B', in cui con B' ho indicato lo sviluppo dell'arco riferito al concio ridotto.
Con una immagine successiva illustrerò l'evenienza.
(http://img213.imageshack.us/img213/8452/compl.jpg)
come e' possibile vedere, alla funzione noi passiamo sempre gli estremi di suddivisione in conci, ed in quei casi in cui c'e' l'intersezione del segmento superiore, la funzione per le finalita del calcolo dell'area riduce l'ampiezza del concio determinandosi il punto di intersezione e stabilendo nuovi limiti del concio ridotto.
Correttamente dovremmo determinarci sia lo sviluppo dell'arco di base del concio intero che lo sviluppo dell'arco di base del concio ridotto, in modo da applicare la coesione dei due strati ai tratti di loro competenza.
Ma i casi possono complicarsi considerando il fatto che abbiamo anche previsto la possibilita di un vertice posto all'interno del concio e puo anche capitare il caso che se il vertice e' di uno strato di separazione, questo possa uscire fuori dal cerchio
(http://img94.imageshack.us/img94/8949/compl1.jpg)
le cose si complicano abbastanza e se fino ad adesso non abbiamo fatto alcuna approssimazione, per evitare di arrovellarci il cervello e per evitare di appesantire eccessivamente la nostra funzione, decidiamo di attribuire all'intero sviluppo B dell'arco di base, la coesione dell'ultimo strato interessato.
L'errore che si commette e' tanto piu piccolo tanto piu fitta e' la suddivisione in conci.
E poi non e' detto che si debba per forza incorrere nell'errore, seppur piccolo e trascurabile, poiche in genere il modello di suddivisione stratigrafica non preveda un eccessivo frastagliamento delle superfici di separazione, dato che esso viene fissato sulla base dei risultati ottenuto in un numero discreto di sondaggi.
-
Siamo sempre li, Alberto.
Anche considerando il punto medio, quindi operando gia una sorta di suddivisione dei singoli tratti della polilinea in macroconci (quindi si potrebbe pensare di inserire due punti in corrispondenza dei terzi, oppure 4 o 5), in relazione alla lunghezza del segmento, il punto medio puo' risultare essere sia interno che esterno.
Edit By Gilean: Se i post sono consecutivi evitare di quotare l'intero messaggio, il post diverrà così più leggibile.
Pardon, nella fretta ho scritto una sciocchezza. Dunque: devo ottenere i punti di insersezione tra una polinea definita da n punti ed un cerchio con centro C(xc, yc) e raggio r.
1) l'equazione della circonferenza è (x-xc)^2+(y-yc)^2=r^2;
2) l'equazione della retta appartenente al generico segmento della polilinea è (y-yi)/(yf-yi)=(x-xi)/(xf-xi), salvo le singolarità (xi=xf o yi=yf): i ed f sono i punti iniziale e finale del segento considerato della polilinea;
E' un sistema di secondo grado con 2 incognite. Le soluzioni sono direttamente i punti di intersezione (se le radici sono reali e distinte). Se le radici coincidono ho un punto di tangenza.
Per sostituzione diventa un po' lunga ma ce la si fa abbastanza bene.
3) se le radici esistono devo vedere se sono interne o esterne al segmento considerato. Se sono interne ho beccato i punti d'intersezione (magari 1 sola è interna), se sono esterne le scarto e passo all'analisi del segmento successivo. La condizione affinché la radice sia interna è del tipo " xi<x and x<xf " (se sono interne le ascisse lo sono anche le ordinate essendo una retta, quindi mi limito a questo solo controllo).
Così dovrebbe funzionare anche se è un po' laborioso da implementare.
Ciao.
Prendo atto di questo tuo intervento.
Intanto penso di continuare sulla via che ho gia intrapreso, che non e' detto mi porti alla conclusione. Nel caso dovessi registrare il fallimento posso pensare di reiniziare tutto basandomi su qunto mi hai detto.
In ogni caso mi sto divertendo.
Grazie, ciao
-
Prendo atto di questo tuo intervento.
Intanto penso di continuare sulla via che ho gia intrapreso, che non e' detto mi porti alla conclusione. Nel caso dovessi registrare il fallimento posso pensare di reiniziare tutto basandomi su qunto mi hai detto.
In ogni caso mi sto divertendo.
Grazie, ciao
Bene, è un tema interessante quello che stai affrontando.
Io non ho ancora avuto il tempo di analizzarlo anche se è parecchio tempo che ci sto pensando: seguirò con attenzione gli sviluppi.
Ciao.
x Gilean: non è possibile togliere di default tutti 'sti "Re: Re: Re: ..." che si generano automaticamente nel testo del topic quando ci si risponde in continuo? Ciao.
-
Bene, è un tema interessante quello che stai affrontando.Io non ho ancora avuto il tempo di analizzarlo anche se è parecchio tempo che ci sto pensando: seguirò con attenzione gli sviluppi.Ciao.x Gilean: non è possibile togliere di default tutti 'sti "Re: Re: Re: ..." che si generano automaticamente nel testo del topic quando ci si risponde in continuo? Ciao.
Alberto, Bug dei re: re: corretto.
-
Dopo un paio di giorni di meditazioni e prove, sono pervenuto a:
- la funzione che calcola l'area del concio generico funziona e dà risultati corretti nel caso in cui passiamo estremi del concio per cui abbaimo certezza che esso ricade all'interno del cerchio;
- i problemi si hanno quando passiamo estremi del concio che implicano la determinazione di una eventuale intersezione col cerchio;
- i problemi suddetti nascono dal fatto che ho pensato di limitare il campo di scansione dei conci all'interno del diametro e dal fatto che non vengono determinati a priori i punti di intersezione delle varie superfici.
Penso pertanto di chiudere la funzione concio e procedere con altre funzioni o macro che mi determinano tutti i punti di intersezione
(http://img685.imageshack.us/img685/4797/suddivisione.jpg)
si tratta quindi di determinare le coordinate dei punti A, B, C, D, E, F e di eventuali altri dovuti alla presenza di altre superfici di separazione tra gli strati.
-
A questo punto e' utile pertanto riassumere il codice fin qui scritto.
iniziano le due funzioni trigonometriche inverse, necessarie perche in VBA mancano le funzioni apposite.
_________________________________________________
Function arCsin(num As Double) As Variant
Dim pi As Double
pi = 4 * Atn(1)
If num < -1 Or num > 1 Then
arCsin = "NV"
Else
If num = 1 Or num = -1 Then
arCsin = num * pi / 2
Else
arCsin = Atn(num / Sqr(-num * num + 1))
End If
End If
End Function
_______________________________________________
Function aRccos(num As Double) As Variant
Dim pi As Double
pi = 4 * Atn(1)
If num < -1 Or num > 1 Then
aRccos = "NV"
Else
If num = 1 Or num = -1 Then
aRccos = (num - 1) * pi / 2
Else
aRccos = Atn(-num / Sqr(-num * num + 1)) + 2 * Atn(1)
End If
End If
End Function
_________________________________________________
In queste ho inserito i controlli sul valore passato e nel caso faccio restituire la stringa NV
segue la funzione che calcola l'area del segmento di cerchio
________________________________________________
Function segmento(xc As Double, R As Double, x As Double) As Variant
Dim beta As Double
beta = 2 * aRccos((x - xc) / R)
segmento = R ^ 2 * beta / 2 - (x - xc) * R * Sin(beta / 2)
End Function
____________________________________________
ed infine la funzione concio che riscrivo
__________________________________________________
Public Function concio(xc As Double, yc As Double, R As Double, _
xi As Double, xf As Double, _
yi As Double, yf As Double, _
xv As duble, yv As Double, flag As Double) As Variant
Dim A As Double ' variabile per il calcolo dell'area
Dim B As Double 'variabile per il calcolo dello sviluppo dell'arco di base
Dim alfa As Double 'variabile per il calcolo dell'angolo di inclinazione della tangente
Dim ym As Double
ym = (yi + yf) / 2
' controllo che il raggio non sia minore o uguale a zero
If R <= 0 Then
concio = 0
Exit Function
End If
' controllo che xf sia maggiore di xi
If xf - xi <= 0 Then
concio = 0
Exit Function
End If
' controllo che xi ed xf siano all'interno del diametro del cerchio
' questo controllo serve a non fare andare in errore le funzioni trigonometriche inverse
If xf < xc - R Or xi > xc + R Then
concio = 0
Exit Function
End If
' controllo che xv sia all'interno di xi xf, nel caso cada all'esterno
' lo assumo pari ad xi
If xv < xi Or xv > xf Then
xv = xi
yv = yi
End If
' calcolo l'area sottesa dalla congiungente yi-yf
A = (segmento(xc, R, xi) - segmento(xc, R, xi)) / 2 - (xf - xi) * (yc - ym)
' adesso considero la presenza del vertice intermedio
A = A + (xf - xi) * (yf - yi) / 2 - (xv - xi) * (yv - yi) / 2 - (xf - xi) * (yf - yv) / 2 - (xv - xi) * (yf - yv)
' controllo area negativa
If A < 0 Then
concio = 0
End If
' calcolo dell'angolo alfa
alfa = arCsin((xi - xc) / R) + (arCsin((xi - xc) / R) - arCsinn((xf - xc) / R)) / 2
' calcolo dello sviluppo dell'arco di base
B = R * arCsin((xi - xc) / R) - arCsin((xf - xc) / R)
Select Case flag
Case 1
concio = A
Case 2
concio = alfa
Case 3
concio = B
Case Else
concio = 0
End Select
End Function
______________________________________________
Per adesso considero conclusa questa funzione salvo a modificarla in seguito includendo anche la determinazione dell'ordinata del baricentro del concio
saluti
Edit by Gilean: afazio puoi usare il pulsante codice (http://www.postimage.org/image.php?v=gxKY0rS) per racchiudere le tue funzioni tra codice, per non perdere la formattazione delle funzioni e selezionarle con un click ;)
-
Sono ansioso di vedere come finisce la discussione, nel frattempo rinnovo i miei complimenti ad afazio...questo forum vedo ha al suo attivo gente estremamente competente in molti campi, non può farmi che piacere :ciau:
-
Sono ansioso di vedere come finisce la discussione, nel frattempo rinnovo i miei complimenti ad afazio...questo forum vedo ha al suo attivo gente estremamente competente in molti campi, non può farmi che piacere :ciau:
Ho gai scritto la funzione che determina u due punti di intersezione tra polilinea del profilo di campagna e cerchio. Occorre solo inserire i controlli
Stasera posto il codice ed una breve descrizione.
-
ecco la prima videata del foglio per verifica di stabilità del pendio.
(http://s1.postimage.org/MinSi.jpg) (http://www.postimage.org/image.php?v=gxMinSi)
Edit By Gilean: afazio è bene usare le thumbnail per evitare di sformare il post. Puoi usare il pulsante add image to post per inserire immagini.
-
se mi si indica come fare l'upload del file condivido il file di inizio.
Fino ad adesso sono solo rimaste formule e righe di codice. Adesso sto iniziando a compilare il foglio che nel corso di questo processo subirà certamente una serie di modifiche sostanziali.
Intanto descrivo cosa ho fatto.
Ho prima di tutto scritto la funzione che, dato come input il range di celle contenenti i vertici della polilinea e i dati del cerchio mi restituisce i due punti di intersezione tra polilinea a cerchio (se esistono).
La forma della funcione e':
Public Function interseca_poly1(tabella As Range, xc As Double, yc As Double, R As Double, flag As Integer) As Variant
in cui i nomi delle variabili sono autoesplicativi
Il parametro flag serve per stabilire cosa deve restituire la funzione secondo la seguente convenzione:
flag=0, la funzione restituisce un valore logico Vero se esistono le intersezioni, Falso se non esistono
flag=1, la funzione restituisce l'ascissa del primo punto di intersezione
flag=2, la funzione restituisce l'ordinata del primo punto di intersezione
flag=3, la funzione restituisce l'ascissa del secondo punto di intersezione
flag=4, la funzione restituisce l'ordinata del secondo punto di intersezione
di seguito il codice che deve ancora essere sottoposto a tutti i controlli necessari per non incorrere in errori
Public Function interseca_poly1(tabella As Range, xc As Double, yc As Double, R As Double, flag As Integer) As Variant
Dim nPunti As Integer
Dim xx(1 To 2) As Double
Dim yy(1 To 2) As Double
Dim count As Integer
Dim esiste_intersez As Boolean
Dim x1 As Double
Dim y1 As Double
Dim x2 As Double
Dim y2 As Double
nPunti = tabella.Rows.count ' leggo il numero di punti della polilinea
ReDim coord(1 To nPunti, 1 To 2) As Double
' trasferisco la tabella delle coordinate nella matrice coord
For count = 1 To nPunti
coord(count, 1) = tabella.Cells(count, 1)
coord(count, 2) = tabella.Cells(count, 2)
Next
' eseguo adesso la ricerca delle intersezioni per ciascun segmento della polilinea
esiste_intersez = False
For count = 2 To nPunti
xi = coord(count - 1, 1)
yi = coord(count - 1, 2)
xf = coord(count, 1)
yf = coord(count, 2)
A = -2 * xc
B = -2 * yc
c = xc ^ 2 + yc ^ 2 - R ^ 2
m = (yf - yi) / (xf - xi)
n = yi - m * xi
a1 = m ^ 2 + 1
b1 = 2 * m * n + A + B * m
c1 = n ^ 2 + B * n + c
d = b1 ^ 2 - 4 * a1 * c1
If d > 0 Then
x1 = (-b1 - d ^ 0.5) / (2 * a1)
x2 = (-b1 + d ^ 0.5) / (2 * a1)
y1 = m * x1 + n
y2 = m * x2 + n
If Not (xf < x1 Or xi > x2) Then
' vi sono intersezioni
If xi <= x1 And xf < x2 Then
'una intersezione data dal primo punto
xx(1) = x1
yy(1) = y1
esiste_intersez = True
End If
If xi <= x1 And xf >= x2 Then
' due intersezioni
xx(1) = x1
yy(1) = y1
xx(2) = x2
yy(2) = y2
esiste_intersez = True
End If
If xi > x1 And xf < x2 Then
' nessuna intersezione
End If
If xi > x1 And xf >= x2 Then
' una intersezione
xx(2) = x2
yy(2) = y2
esiste_intersez = True
End If
End If
End If
Next
Select Case flag
Case 0
interseca_poly1 = esiste_intersez
Case 1
interseca_poly1 = xx(1)
Case 2
interseca_poly1 = yy(1)
Case 3
interseca_poly1 = xx(2)
Case 4
interseca_poly1 = yy(2)
Case Else
interseca_poly1 = "ERRORE NEL FLAG"
End Select
End Function
-
menù in alto, clicca---> Downloads poi il alto alto a destra ---> MYFILES
-
se mi si indica come fare l'upload del file condivido il file di inizio.
Fino ad adesso sono solo rimaste formule e righe di codice. Adesso sto iniziando a compilare il foglio che nel corso di questo processo subirà certamente una serie di modifiche sostanziali.
Intanto descrivo cosa ho fatto.
Ho prima di tutto scritto la funzione che, dato come input il range di celle contenenti i vertici della polilinea e i dati del cerchio mi restituisce i due punti di intersezione tra polilinea a cerchio (se esistono).
La forma della funcione e':
Public Function interseca_poly1(tabella As Range, xc As Double, yc As Double, R As Double, flag As Integer) As Variant
in cui i nomi delle variabili sono autoesplicativi
Il parametro flag serve per stabilire cosa deve restituire la funzione secondo la seguente convenzione:
flag=0, la funzione restituisce un valore logico Vero se esistono le intersezioni, Falso se non esistono
flag=1, la funzione restituisce l'ascissa del primo punto di intersezione
flag=2, la funzione restituisce l'ordinata del primo punto di intersezione
flag=3, la funzione restituisce l'ascissa del secondo punto di intersezione
flag=4, la funzione restituisce l'ordinata del secondo punto di intersezione
di seguito il codice che deve ancora essere sottoposto a tutti i controlli necessari per non incorrere in errori
Public Function interseca_poly1(tabella As Range, xc As Double, yc As Double, R As Double, flag As Integer) As Variant
Dim nPunti As Integer
Dim xx(1 To 2) As Double
Dim yy(1 To 2) As Double
Dim count As Integer
Dim esiste_intersez As Boolean
Dim x1 As Double
Dim y1 As Double
Dim x2 As Double
Dim y2 As Double
nPunti = tabella.Rows.count ' leggo il numero di punti della polilinea
ReDim coord(1 To nPunti, 1 To 2) As Double
' trasferisco la tabella delle coordinate nella matrice coord
For count = 1 To nPunti
coord(count, 1) = tabella.Cells(count, 1)
coord(count, 2) = tabella.Cells(count, 2)
Next
' eseguo adesso la ricerca delle intersezioni per ciascun segmento della polilinea
esiste_intersez = False
For count = 2 To nPunti
xi = coord(count - 1, 1)
yi = coord(count - 1, 2)
xf = coord(count, 1)
yf = coord(count, 2)
A = -2 * xc
B = -2 * yc
c = xc ^ 2 + yc ^ 2 - R ^ 2
m = (yf - yi) / (xf - xi)
n = yi - m * xi
a1 = m ^ 2 + 1
b1 = 2 * m * n + A + B * m
c1 = n ^ 2 + B * n + c
d = b1 ^ 2 - 4 * a1 * c1
If d > 0 Then
x1 = (-b1 - d ^ 0.5) / (2 * a1)
x2 = (-b1 + d ^ 0.5) / (2 * a1)
y1 = m * x1 + n
y2 = m * x2 + n
If Not (xf < x1 Or xi > x2) Then
' vi sono intersezioni
If xi <= x1 And xf < x2 Then
'una intersezione data dal primo punto
xx(1) = x1
yy(1) = y1
esiste_intersez = True
End If
If xi <= x1 And xf >= x2 Then
' due intersezioni
xx(1) = x1
yy(1) = y1
xx(2) = x2
yy(2) = y2
esiste_intersez = True
End If
If xi > x1 And xf < x2 Then
' nessuna intersezione
End If
If xi > x1 And xf >= x2 Then
' una intersezione
xx(2) = x2
yy(2) = y2
esiste_intersez = True
End If
End If
End If
Next
Select Case flag
Case 0
interseca_poly1 = esiste_intersez
Case 1
interseca_poly1 = xx(1)
Case 2
interseca_poly1 = yy(1)
Case 3
interseca_poly1 = xx(2)
Case 4
interseca_poly1 = yy(2)
Case Else
interseca_poly1 = "ERRORE NEL FLAG"
End Select
End Function
per determinare i punti di intersezione ho seguito il metodo che mi ha suggerito Alberto
-
menù in alto, clicca---> Downloads poi il alto alto a destra ---> MYFILES
Download Not Approved
Lo approvo subito afazio, ho messo la moderazione in download per evitare di essere sommerso da files (o virus) di possibili bot di spam.
-
Download Not Approved
Credo li debba approvare l'Amministratore, così mi è parso di capire in questi giorni di letture.
-
per determinare i punti di intersezione ho seguito il metodo che mi ha suggerito Alberto
Ciao Afazio, ho letto rapidamente il codice. Occhio che se xi=xf si genera un errore di runtime.
Ciao.
-
per determinare i punti di intersezione ho seguito il metodo che mi ha suggerito Alberto
L'equazione del cerchio si puo scrivere come
x² + y² + A*x + B*y + C = 0
con:
A=-2*xc
B=-2*yc
C=xc²+yc² - R²
L'equazione passante per (xi;yi) e per (xf,yf) si scrive;
y = m*x + n
con
m=(yf-yi)/(xf-xi)
n= yi - m*xi
e qui c'e' la prima fonte di errore, nel caso di segmento verticale abbiamo divisione per zero. Occorrerà apportare questo controllo e procedere con l'intersezione di un cerchio con la retta x=xi
Sostituendo nell'equazione del cerchio il valore (mx+n) otteniamo l'equazione dis econdo grado dei memorabili tempi del liceo:
a1*x² + b1*x +c1 = 0
con
a1 = m²+1
b1= 2*m*n + A +m*B
c1= n ² + B * n + C
Si determina il discriminante e se e' maggiore di zero vi sono le due intersezioni con la retta su cui giace il generico segmento della polilinea.
Il caso di discriminante nullo non mi interessa, poichè un segmento tangente al cerchio non partecipa nell'equilibrio del pendio dato che sarebbe nullo l'apporto di area di concio
Ma il fatto che vi siano due intersezione della retta su cui giace il segmento col cerchio, non significa affatto che necessariamente il segmento interseca il cerchio.
Occorre capire la posizione reciproca tra gli estremi del segemento e i due punti di intersezione
pertanto, indicand o con x1 ed x2 rispettivamente le ascisse del primo e del secondo punto di intersezione, abbiamo i seguenti casi:
- se (xf < x1 Or xi > x2) - non vi sono intersezioni poiche il segmento e' o tutto a sinistra del cerchio o tutto a destra
- se xi <= x1 And xf < x2 - vi e' una sola intersezione. Il segmento ha il primo estremo a sinistra del cerchio (o sul cerchio stesso) mentre il secondo si trova dentro il cerchio. il punto i intersezione è proprio x1
- se xi <= x1 And xf >= x2 vi sono due intersezioni in quanto il primo estremo del segemento si trova a sinistra del cerchio (oppure sul cerchio stesso) ed il secondo estremo si trova a destra del cerchio (oppure sul cerchio). Entrambi i punti, x1 ed x2 sono punti di intersezione
- se xi > x1 And xf < x2, non vi sono intersezioni poiche il segmento e' tutto interno al cerchio
- se xi > x1 And xf >= x2, vi e' una sola intersezione in quanto ilprimo estremo del segmento e' dentro il cerchio mentre il secondo è o sul cerchio oppure fuori dal cerchio a destra. Il punto i intersezione è proprio x2
-
Ciao Afazio, ho letto rapidamente il codice. Occhio che se xi=xf si genera un errore di runtime.
Ciao.
Si. Devo ancora inserire i controlli.
Nel caso di xi=xf (quindi tratto verticale delle polilinea), devo intersecare il cerchio con la retta x=xi e la cosa e' facile, ma oltre a questo devo anche modificare le condizioni che discriminano la posizione del segmento rispetto ai punti di intersezione. E' ovvio che gli IF non possono avere come condizione i valori delle ascisse (essendo tutte uguali ad xi) ma si devono basare invece sulle ordinate.
-
Occhio anche all'orientamento con il quale viene definita la polilinea: da sx verso dx o viceversa: in quest'ultimo caso mi pare che le condizioni finali sul controllo delle intersezioni interne al segmento non siano correttamente funzionanti.
Ciao.
-
Occhio anche all'orientamento con il quale viene definita la polilinea: da sx verso dx o viceversa: in quest'ultimo caso mi pare che le condizioni finali sul controllo delle intersezioni interne al segmento non siano correttamente funzionanti.
Ciao.
Non ho specificato, ma in ogni figura ho sempre disegnato il profilo da sx verso destra a salire.
Questa e' una regola che occorre rispettare per evitare di complicare le funzioni ed i controlli
Altra regola e' quella che non si pososno inserire tratti di pendio o di separazione strati in contropendenza, cioe con xf<xi.
Potrei anche aggiungere la limitazione che non si pososno mettere tratti verticali, ma per adesso la cosa non mi ha dato alcun problema. Forse me li darà quando dovro procedere alla suddivisione in conci.
Vedremo.
Per le condizioni finali a cui ti riferisci, non saprei, posso solo dirti che col foglio che ho predisposto ho provato numerosi casi e le intersezioni sono sempre calcolate correttamente, tuttavia sappiamo benissimo che il bug si puo celare financo sotto il tuo naso.
Mi spieghi meglio dove sta il tuo dubbio?
-
Mi spieghi meglio dove sta il tuo dubbio?
L'input da parte dell'utente da dx verso sx. Metti un controllo nelle celle, in tutti i casi x(i+1)>=x(i).
Ho l'ossessione dei bug ecco perchè presto attenzione a queste sciocchezze.
Ciao.
-
L'input da parte dell'utente da dx verso sx. Metti un controllo nelle celle, in tutti i casi x(i+1)>=x(i).
Ho l'ossessione dei bug ecco perchè presto attenzione a queste sciocchezze.
Ciao.
ok
non sono riuscito a fare l'upload del file
te lo mando adesso via mail.
-
ok
non sono riuscito a fare l'upload del file
te lo mando adesso via mail.
afazio, ho inserito la moderazione nei downloads, per evitare che eventuali bot inseriscano files dannosi (virus ecc..) sul forum. Ho approvatoil tuo download, ad ogni modo se vuoi che la gente possa trovarlo, sarebbe bene se tu potessi inserire una breve descrizione di ciò che fa e nelle parole chiave inserire qualche parola che caratterizzi questo file, in modo che sia subito ritrovabile dal cerca. Ho fatto gia' tutto questo io per te, trovate il file di afazio qui
http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208 (http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208)
ora tu afazio potrai editare il download in qualsiasi momento semplicemente cliccando su edit ed inserendo il nuovo file. Il vecchio si cancellerà in automatico .
-
Download Not Approved
Lo approvo subito afazio, ho messo la moderazione in download per evitare di essere sommerso da files (o virus) di possibili bot di spam.
aspetta un attimo
ho apportato delle variazioni nel frattempo
dimmi come devo fare per l'upload
-
torna nel tuo file, clicca su edit, dopo clicca su sfoglia e scegli il tuo file dal pc e reinseriscilo, poi premi edit download.
(http://s2.postimage.org/19cSNr.jpg) (http://www.postimage.org/image.php?v=Ts19cSNr)
L'input da parte dell'utente da dx verso sx. Metti un controllo nelle celle, in tutti i casi x(i+1)>=x(i).Ho l'ossessione dei bug ecco perchè presto attenzione a queste sciocchezze.Ciao.
Siamo in due alberto, se scarichi qualche mio programma dalla sezione downloads, troverai moltissimi controlli e gestione delle eccezioni.
-
afazio, ho inserito la moderazione nei downloads, per evitare che eventuali bot inseriscano files dannosi (virus ecc..) sul forum. Ho approvatoil tuo download, ad ogni modo se vuoi che la gente possa trovarlo, sarebbe bene se tu potessi inserire una breve descrizione di ciò che fa e nelle parole chiave inserire qualche parola che caratterizzi questo file, in modo che sia subito ritrovabile dal cerca. Ho fatto gia' tutto questo io per te, trovate il file di afazio qui
http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208 (http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208)
ora tu afazio potrai editare il download in qualsiasi momento semplicemente cliccando su edit ed inserendo il nuovo file. Il vecchio si cancellerà in automatico .
si va bene tutto ma in questo caso tieni conto di:
- e' un file in progresso, non completo
- serve solo per seguire gli sviluppi avendo davanti il foglio ed anche per fare delle prove
- deve essere sotituito ogni volta con la nuova versione che eliminerà la precedente
ed infine
- a tutto cio' ci devi pensare tu, cioe' a metetre gli indici le key le toppe e le tappe, metterlo dove meglio ti aggrada facendo solo attenzione al naso. Il fiel potrebbe diventare piu grosso delle narici.
ciao
-
si va bene tutto ma in questo caso tieni conto di:
- e' un file in progresso, non completo
- serve solo per seguire gli sviluppi avendo davanti il foglio ed anche per fare delle prove
- deve essere sotituito ogni volta con la nuova versione che eliminerà la precedente
ed infine
- a tutto cio' ci devi pensare tu, cioe' a metetre gli indici le key le toppe e le tappe, metterlo dove meglio ti aggrada facendo solo attenzione al naso. Il fiel potrebbe diventare piu grosso delle narici.
ciao
Se io devo inserire le chiavi per ogni file ed i files sono di cento utenti, ci sto cento minuti, se ogni file viene gestito dall'utente che lo inserisce con le chiavi, ogni utente ci sta un minuto :)
ad ogni modo non sono obbligatorie, lo dicevo solo per far si che i colleghi che lo cercano lo trovino subito. hai capito come si edita il file?
-
Se io devo inserire le chiavi per ogni file ed i files sono di cento utenti, ci sto cento minuti, se ogni file viene gestito dall'utente che lo inserisce con le chiavi, ogni utente ci sta un minuto :)
ad ogni modo non sono obbligatorie, lo dicevo solo per far si che i colleghi che lo cercano lo trovino subito. hai capito come si edita il file?
bho
forse
ma il nome del nuovo file e' diverso dal precedente
prova ad approvare l'upload
-
a...ma non devi inserire un file nuovo, ti basta editare sempre il vecchio downloads...cmq approvo l'ultimo ed elimino l'altro.
ecco il link
http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208 (http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208)
-
ma io ho editato il download
e poi ho scelto il file modifcato
al quale pero' io cambiosempre nome
Mantengo sempre le due precedenti versioni
e ad ogni nuova versione elimino la terza piu vecchia
dici che non devo cambuare il nome al file?
-
a...ma non devi inserire un file nuovo, ti basta editare sempre il vecchio downloads...cmq approvo l'ultimo ed elimino l'altro.
ecco il link
http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208 (http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=208)
ok
iddu è
prova ad aprirlo adesso e modificare i dati. Ricordati di attivare l'esecuzione delle macro.
-
a no tutto ok, pare che ogni edit debba essere approvato...prova a lasciare stesso nome, al limite vedo se si puo' evitare sta cosa.
-
Ecco, nemmeno il tempo di rallegrami per essere arrivato a qualcosa dove, previo opportuni aggiustamenti, si poteva mettere un punto ed andare avanti, che subito nasce la prima questione.
Intanto ammettiamo che la superficie topografica non può avere più di due punti di intersezioni, nel senso che non possiamo accettare come cerchi di scivolamento quelli che mi dividono il suolo in tre o quattro parti come nella figura che segue:
(http://img684.imageshack.us/img684/7302/eccezione01.jpg)
In questo caso si può procedere secondo una delle due vie:
- scartare il cerchio
- considerare solo la parte di pendio intercettato a monte scartando quello di valle.
Mentre i casi di intersezione plurime con qualsiasi superficie di separazione tra gli strati non sono da scartare
occorre quindi saper riconoscere i casi in cui vi sono intersezioni plurime tra cerchio e superficie topografica per scartare il relativo cerchio o parte di pendio ed anche le intersezioni plurime con le superfici di separazione tra gli strati per farvi passare le verticali di suddivisione dei conci
vedremo come risolvere questo problema.
-
Mentre i casi di intersezione plurime con qualsiasi superficie di separazione tra gli strati non sono da scartare
occorre quindi saper riconoscere i casi in cui vi sono intersezioni plurime tra cerchio e superficie topografica per scartare il relativo cerchio o parte di pendio ed anche le intersezioni plurime con le superfici di separazione tra gli strati per farvi passare le verticali di suddivisione dei conci
vedremo come risolvere questo problema.
Ciao Afazio
per le intersezioni plurime si potrebbe pensare ad un avviso nel caso in cui siano maggiori di due, oppure scartare direttamente la soluzione. Non ho capito perchè usi 3 muduli per scrivere 3 funzioni: perchè non le raggruppi in uno solo? O magari, perchè non le raggruppi per tipologia in determinati moduli? Quando il codice diventa molto complesso è importante riuscire a metter le mani al posto giusto in tempo zero. Sarà che alcuni dei miei programmi sono arrivati ad alcune centinaia di pagine di codice...
In uno dei post precedenti avevo erroneamente indicato come questo fosse un problema da minimizzare su 3 variabili: in realtà dovrebbero essere 2 perchè se non ricordo male il cerchio deve sempre passare per un punto (lo spigolo della fondazione del muro di sostegno). Quindi mancherebbe un input che è la coordinata del punto del muro, poi si dovrebbe procedere spostando il solo centro del cerchio (il raggio sarebbe determinato) e minimizzare la funzione che esprime il coefficiente di sicurezza in funzione delle coordinate del centro del cerchio.
Ci aggiorniamo, ciao.
x Gilean: non si capisce se l'ora di pubblicazione dei messaggi sia AM o PM: non è meglio usare h24? Ciao.
Edit By Gilean: Orario del forum modificato, grazie per la segnalazione alberto.
-
Ciao Afazio
per le intersezioni plurime si potrebbe pensare ad un avviso nel caso in cui siano maggiori di due, oppure scartare direttamente la soluzione. Non ho capito perchè usi 3 muduli per scrivere 3 funzioni: perchè non le raggruppi in uno solo? O magari, perchè non le raggruppi per tipologia in determinati moduli? Quando il codice diventa molto complesso è importante riuscire a metter le mani al posto giusto in tempo zero. Sarà che alcuni dei miei programmi sono arrivati ad alcune centinaia di pagine di codice...
In uno dei post precedenti avevo erroneamente indicato come questo fosse un problema da minimizzare su 3 variabili: in realtà dovrebbero essere 2 perchè se non ricordo male il cerchio deve sempre passare per un punto (lo spigolo della fondazione del muro di sostegno). Quindi mancherebbe un input che è la coordinata del punto del muro, poi si dovrebbe procedere spostando il solo centro del cerchio (il raggio sarebbe determinato) e minimizzare la funzione che esprime il coefficiente di sicurezza in funzione delle coordinate del centro del cerchio.
Ci aggiorniamo, ciao.
x Gilean: non si capisce se l'ora di pubblicazione dei messaggi sia AM o PM: non è meglio usare h24? Ciao.
Edit By Gilean: Orario del forum modificato, grazie per la segnalazione alberto.
a- per l'avviso nel caso di intersezioni plurime con la sup. topografica, credo non sia praticabile, poichè devi vedere la cosa all'interno di un megaciclo che fa variare sia il centro del cerchio su una griglia prefissata e sia il raggio dello stesso entro un range prefissato. Per adesso stiamo analizzando il singolo cerchio generico e la cosa potrebbe apparire utile e non noiosa. Quindi te lo immagini un programma che si ferma ogni secondo per decine e decine di volte per avvisarti che quel cerchio con quel raggio ha intersezioni plurime? Dobbiamo stabilire fin da adesso quale deve essere la linea da seguire, se scartare il cerchio o scartare parte del pendio.
Io sono per la prima, poichè nel caso si volesse analizzare la stabilità di una parte di pendio, mi riferisco al caso che ho postato nella mia ultima immagine, l'input del profilo topografico si dovrebbe fermare prima di coinvolgere anche la protuberanza di valle, come d'altra parte procedo io utilizzando i programmi commerciali.
b- per i moduli diversi per funzione diverse, alla fine saranno raggruppati in unico modulo, o se utile in moduli ognuno dedicato a uno specifico aspetto.
c- per quanto riguarda la variabilità del cerchio:
- nel caso di verifica di stabilità globale di un muro, l'unica variabile e' il centro del cerchio, poichè esso deve passare sempre per lo spigolo interno della fondazione del muro (altrimenti si tratta di verifica di stabilità del pendio);
- nel caso di verifica di stabilità di un fronte di scavo, la superficie deve invece passare per il piede dello scavo ed anche qui devi solo far variare il centro del cerchio
- nel caso piu generico di verifica di un pendio, il raggio torna ad essere variabile insieme alla maglia dei centri. Ma qui e' possibile pensare di imporre delle considioni nella variabilita del ragio, come per esempio fissare un range, oppure fissare un afondamento massimo o ancora stabilire una retta di tangenza o altro ancora. Ma questi sono problemi che riguardano la fase successiva: per adesso occorre risolvere il singolo cerchio, poichè risoltone uno possiamo risolverne in ciclo quanti ne vogliamo.
- infine, sarebbe utile far tracciare al programma una mappa dei coefficienti di sicurezza associati a ciascun centro. Questa mappa a curve di livello e' utile nelle fasi iniziali della verifica per stabilire piu' opportunamente la maglia dei centri.
-
Ciao Afazio
per le intersezioni plurime si potrebbe pensare ad un avviso nel caso in cui siano maggiori di due, oppure scartare direttamente la soluzione. Non ho capito perchè usi 3 muduli per scrivere 3 funzioni: perchè non le raggruppi in uno solo? O magari, perchè non le raggruppi per tipologia in determinati moduli?
Noto con piacere che segui con interesse e che sono riuscito a coinvolgerti.
Grazie.
ciao
-
Anche se non scrivo, hai coinvolto anche me.
aspetto con ansia i nuovi messaggi.
complimenti :clap:
-
Eccomi Afazio,
in merito al punto a) anche io la penso come te. In un megaciclo non si può chiedere cosa fare all'utente => si scarta il cerchio. In merito al punto c) condivido il target dell'ultimo punto che indichi: un contur con i coefficienti di sicurezza in funzione del centro del cerchio (tipo quello colorato che hai postato per le isobare sotto la fondazione). Pagherebbe l'occhio istantaneamente.
Ciao.
-
Anche se non scrivo, hai coinvolto anche me.
aspetto con ansia i nuovi messaggi.
complimenti :clap:
si, la cosa sta divenendo MOLTO interessante. Da bravo pivellino della programmazione quale sono, non avrei mai compreso l'esistenza di tutti questi problemi per una funzione che usiamo tutti i giorni in geotecnica, all'apparenza banale, bravo a fazio :clap:
-
Per riuscire a determinare tutte le intersezioni con tutte le polilinee ho dovuto apportare delle modifiche alla funzione interseca_poly1, che adesso vi descrivo.
La prima modifica apportata e' stata quella della determinazione delle intersezioni anche nel caso di segmento verticale della polilinea.
Questa e' consistita nell'inserimento di una serei di if aventi come argomento l'uguaglianza delle ascisse xi ed xf
IF xi=xf
In questo caso abbiamo:
equazione del cerchio, al solito.
equazione della retta: x=xi
sostituendo questìultima nella equazione del cerchio otteniamo una equazione di secondo grado, stavolta in y
y² + B*y + (C + A*xi + xi²)
in cui A B e C sono quelli gia definiti nel caso precedente
Anche qui si ricava il discriminante e se positivo si procede con la verifica se il segmento yi, yf e' interno o no al segmento y1 y2, in cui y1 e y2 sono le soluzioni della equazone di secondo grado.
La seconda modifica e' quella di avere inserito un contatore delle intersezioni ( Dim n_intersezioni As Integer ) che si incrementerà ad ogni intersezione trovata.
Per salvare le coordinate dei punti di intersezioni, che a questo punto pososno essere piu' di due, servivano dei vettori che si ridimensionassero al variare del numero di intersezioni:
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
la parola chiave Preserve e' necessaria per non perdere nel ridimensionamento, i punti gia registrati.
Infine, affinche la funzione potesse restituirmi uno qualsiasi degli n punti trovati, ho dovuto aggiungere un ulteriore flag, che ho chiamato con flag_punto che rappresenta l'indice delpunto che voglio restituito
I valori che puo' assumere il falg principale sono:
-1: se voglio sapere se vi sono o meno delle intersezioni
0: se voglio sapere il numero delle intersezioni trovate
1: se voglio l'ascissa del punto il cui indice e' flag_punto
2: se voglio l'ordinata del punto il cui indice e' flag_punto
mentre il flag_punto e' un numero intero che mi indica l'indice del punto di cui voglio le coordinate
Ovviamente nel caso in cui viene passato un flag principale pari a -1 o 0, il valore di flag_punto e' ininfluente.
Public Function interseca_poly1(tabella As Range, xc As Double, yc As Double, R As Double, flag As Integer, flag_punto As Integer) As Variant
' la funzione calcola le intersezioni tra una polilinea ed un cerchio
' in input:
' tabella: il range di celle contenente le coordinate dei punti. Nella prima colonna le ascisse
' nella seconda colonna le ordinate
' xc, yc, R: rispettivamente le coordinate del centro del cerchio ed il suo raggio
' flag: parametro che determina il valore che la funzione deve ritornare secondo la tabella che segue
' -1 : ritorna il valore logico vero se vi sono intersezioni, falso se non ve ne sono
' 0 : ritorna il numero delle intersezioni trovate
' 1 : ritorna l'ascissa del punto di intersezione indicato con flag_punto
' 2 : ritorna l'ordinata
' flag_punto: parametro che indica il punto di intersezione per il quale si vogliono le coordinate
Dim nPunti As Integer
Dim xx() As Double
Dim yy() As Double
Dim count As Integer
Dim esiste_intersez As Boolean
Dim n_intersezioni As Integer
Dim x1 As Double
Dim y1 As Double
Dim x2 As Double
Dim y2 As Double
nPunti = tabella.Rows.count ' leggo il numero di punti della polilinea
ReDim coord(1 To nPunti, 1 To 2) As Double
' trasferisco la tabella delle coordinate nella matrice coord
For count = 1 To nPunti
coord(count, 1) = tabella.Cells(count, 1)
coord(count, 2) = tabella.Cells(count, 2)
Next
' eseguo adesso la ricerca delle intersezioni per ciascun segmento della polilinea
n_intersezioni = 0
esiste_intersez = False
For count = 2 To nPunti
xi = coord(count - 1, 1)
yi = coord(count - 1, 2)
xf = coord(count, 1)
yf = coord(count, 2)
A = -2 * xc
B = -2 * yc
c = xc ^ 2 + yc ^ 2 - R ^ 2
If xi = xf Then
a1 = 1
b1 = B
c1 = c + A * xi + xi ^ 2
Else
m = (yf - yi) / (xf - xi)
n = yi - m * xi
a1 = m ^ 2 + 1
b1 = 2 * m * n + A + B * m
c1 = n ^ 2 + B * n + c
End If
d = b1 ^ 2 - 4 * a1 * c1
If d > 0 Then
If xi = xf Then
x1 = xi
x2 = xi
y1 = (-b1 - d ^ 0.5) / (2 * a1)
y2 = (-b1 + d ^ 0.5) / (2 * a1)
Else
x1 = (-b1 - d ^ 0.5) / (2 * a1)
x2 = (-b1 + d ^ 0.5) / (2 * a1)
y1 = m * x1 + n
y2 = m * x2 + n
End If
If xi = xf Then
If Not (yf < y1 Or yi > y2) Then
' vi sono intersezioni
If yi <= y1 And yf < y2 Then
'una intersezione data dal primo punto
esiste_intersez = True
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x1
yy(n_intersezioni) = y1
End If
If yi <= y1 And yf >= y2 Then
' due intersezioni
esiste_intersez = True
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x1
yy(n_intersezioni) = y1
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x2
yy(n_intersezioni) = y2
End If
If yi > y1 And yf < y2 Then
' nessuna intersezione
End If
If yi > y1 And yf >= x2 Then
' una intersezione
esiste_intersez = True
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x2
yy(n_intersezioni) = y2
End If
End If
Else
'-----
If Not (xf < x1 Or xi > x2) Then
' vi sono intersezioni
If xi <= x1 And xf < x2 Then
'una intersezione data dal primo punto
esiste_intersez = True
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x1
yy(n_intersezioni) = y1
End If
If xi <= x1 And xf >= x2 Then
' due intersezioni
esiste_intersez = True
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x1
yy(n_intersezioni) = y1
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x2
yy(n_intersezioni) = y2
End If
If xi > x1 And xf < x2 Then
' nessuna intersezione
End If
If xi > x1 And xf >= x2 Then
' una intersezione
esiste_intersez = True
n_intersezioni = n_intersezioni + 1
ReDim Preserve xx(1 To n_intersezioni)
ReDim Preserve yy(1 To n_intersezioni)
xx(n_intersezioni) = x2
yy(n_intersezioni) = y2
End If
End If
End If
'-----
End If
Next
Select Case flag
Case -1
interseca_poly1 = esiste_intersez
Case 0
interseca_poly1 = n_intersezioni
Case 1
If flag_punto <= n_intersezioni And esiste_intersez Then
interseca_poly1 = xx(flag_punto)
Else
interseca_poly1 = "ND"
End If
Case 2
If flag_punto <= n_intersezioni And esiste_intersez Then
interseca_poly1 = yy(flag_punto)
Else
interseca_poly1 = "ND"
End If
Case Else
interseca_poly1 = "ERRORE NEL FLAG"
End Select
End Function
Adesso, notando che buona parte del codice e' duplicato, conviene scrivere una funzione che sostituisca una volta per tutte il codice duplicato. ma questa e' cosa che puo farsi in seguito.
-
A questo punto arrivato, fatte salve le modifiche ed aggiustamenti di quanto già scritto per esigenze che possono sopraggiungere nel seguito, il prossimo passo da sviluppare e' quello della suddivisione in conci del pendio.
Si tratta di stilare una tabella delle ascisse di tutte le verticali che suddivideranno la parte di pendio che ricade entro il cerchio.
Il punto da cui partire e' quello di definire le caratteristiche di questa tabella. Io ho pensato alle seguenti:
- l'ascissa iniziale deve essere il primo punto di intersezione del cerchio col profilo topografico
- l'ascissa finale deve essere il secondo ed ultimo punto di intersezione del cerchio col profilo topografico e nel caso in cui vi fossero piu di due punti di intersezione la tabella deve essere composta da sole due righe entrambi con ascissa nulla
-deve essere considerato ogni vertice del profilo che si trova internamente al cerchio
- devono essere considerati tutti i punti di intersezione delle superfici di separazione degli strati
-deve essere considerato ogni vertice delle superfici di separazione che si trovano internamente ai corrispondenti punti di intersezione
- infine devono aggiungersi ulteriori ascisse in quei tratti in cui la suddivisione risulta maggiore di un passo massimo che avremo fissato.
Penso di fare tutto questo ricorrendo ad una sub anzichè ad una function.
Chi invece cercherà di tradurre questo codice per fare una applicazione autonoma, penso dovrà inserire questa parte nel corpo del programma.
-
Bene, inizia la fase 2. Da parte mia nessuna osservazione particolare.
Ciao.
-
Bene, inizia la fase 2. Da parte mia nessuna osservazione particolare.
Ciao.
e no!
saremmo alla fase 3.
Non scordarti la prima funzione che calcola area sviluppo di base e tangente.
-
Ho iniziato la terza fase. Troverete il file in avanzamento da qualche parte in questo sito appena gil lo avrà approvato.
Non chiedetemi dove lo troverete perche non ci ho capito proprio un tubo.
il codice:
Sub suddivisione()
Dim count As Integer
Dim i As Integer
Dim conta_ascisse As Integer
Dim conta_aggiunte As Integer
Dim x_iniz As Double
Dim x_finale As Double
Dim x As Double ' variabile di appoggio
Dim doppione As Boolean
Dim dxmax As Double
Dim dx As Double ' variabile di appoggio
Dim ndx As Integer ' variabile di appoggio
Dim n_vert_terreno As Double
Dim n_vert_str1 As Double
Dim n_intersez_Str1 As Double
Dim XX() As Double
Dim xx1() As Double
n_vert_terreno = Range("n_vert_t").Value
n_vert_str1 = Range("n_vert_STR1").Value
n_intersez_Str1 = Range("n_int_STR1").Value
conta_ascisse = 2 + n_intersez_Str1
ReDim Preserve XX(1 To conta_ascisse) As Double
x_iniz = Range(" Tab_intersez_T").Cells(1, 1)
x_finale = Range(" Tab_intersez_T").Cells(2, 1)
dxmax = Range("dx_max").Value
' cancello il contenuto della tabella ascisse conci
For count = 1 To Range("ascisse_conci").Rows.count
Range("ascisse_conci").Cells(count) = 0
Next
' inserisco nel vettore xx le coordinate diintersezione del terreno
' e quelle con la superficie di separazione dello strato
XX(1) = x_iniz
XX(2) = x_finale
For count = 1 To n_intersez_Str1
XX(2 + count) = Range("Tab_intersez_sTr1").Cells(count, 1)
Next
' adesso scansiono tra le ascisse del profilo quelle che sono maggiori di x_iniz e minori di xfinale
For count = 1 To n_vert_terreno
x = Range("Coordinate_profilo").Cells(count, 1).Value
If x > x_iniz And x < x_finale Then
'controllo che l'ascissa non sia gia presente, se assente incremento
' il contatore e la aggiumgo al vettore
doppione = False
For i = 1 To conta_ascisse
If x = XX(i) Then doppione = True
Next
If Not (doppione) Then
conta_ascisse = conta_ascisse + 1
ReDim Preserve XX(1 To conta_ascisse)
XX(conta_ascisse) = x
doppione = False
End If
End If
Next
' adesso scansiono tra le ascisse dello strato quelle che sono maggiori di x_iniz e minori di xfinale
For count = 1 To n_vert_str1
x = Range("coord_1").Cells(count, 1).Value
If x > x_iniz And x < x_finale Then
'controllo che l'ascissa non sia gia presente, se assente incremento
' il contatore e la aggiumgo al vettore
doppione = False
For i = 1 To conta_ascisse
If x = XX(i) Then doppione = True
Next
If Not (doppione) Then
conta_ascisse = conta_ascisse + 1
ReDim Preserve XX(1 To conta_ascisse)
XX(conta_ascisse) = x
doppione = False
End If
End If
Next
' ordino il vettore xx
Call Ordina(XX)
' inserisco ascisse in quei tratti maggiori di dx_max
conta_aggiunte = 0
For count = 2 To conta_ascisse
dx = XX(count) - XX(count - 1)
If dx > dxmax Then
ndx = Int(dx / dxmax)
For i = 1 To ndx
conta_aggiunte = conta_aggiunte + 1
ReDim Preserve xx1(1 To conta_aggiunte)
xx1(conta_aggiunte) = XX(count) + i * dx / ndx
Next
End If
Next
'accodo il vettore xx1 ad xx e riordino nuovamente
ReDim Preserve XX(1 To conta_ascisse + conta_aggiunte)
For i = 1 To conta_aggiunte
XX(conta_ascisse + i) = xx1(i)
Next
Call Ordina(XX)
' scrivo il vettore sul foglio di calcolo
For count = 1 To conta_ascisse
Range("ascisse_conci").Cells(count) = XX(count)
Next
End Sub
la descrizione di cio' che fa il codice
Intanto occorre sapere che ho attribuito dei nomi ai range del foglio che interessano la sub-routine
inizio col leggere il numero di vertici del profilo terreno, il numero dei vertici del primo (ed unico strato per ora) ed il numero delle intersezioni dello strato
n_vert_terreno = Range("n_vert_t").Value
n_vert_str1 = Range("n_vert_STR1").Value
n_intersez_Str1 = Range("n_int_STR1").Value
quindi inzializzo il contatore delle ascisse dei conci ad un numero pari alel due intersezioni del profilo topografico piu quella dello strato
conta_ascisse = 2 + n_intersez_Str1
e con questa mi fisso la dimensione iniziale del vettore che conterra le ascisse dei conci
ReDim Preserve XX(1 To conta_ascisse) As Double
quindi mi leggo l'ascissa di inizio della suddivisione e l'ascissa di fine ed insieme a queste mi leggo il valore del passo max tra due conci
x_iniz = Range(" Tab_intersez_T").Cells(1, 1)
x_finale = Range(" Tab_intersez_T").Cells(2, 1)
dxmax = Range("dx_max").Value
Pulisco la tabella sul foglio ove depositero' le ascisse
For count = 1 To Range("ascisse_conci").Rows.count
Range("ascisse_conci").Cells(count) = 0
Next
e quindi inizio a popolare il vettore delle ascisse dei conci con quelle che abbiamo note e cioè le due ascisse di inzio e fine e tutte le ascisse di intersezione dello strato
XX(1) = x_iniz
XX(2) = x_finale
For count = 1 To n_intersez_Str1
XX(2 + count) = Range("Tab_intersez_sTr1").Cells(count, 1)
Next
A questo punto non resta che leggere le ascisse del profilo, verificare che si trovino internamente ad x iniziale e finale, verificare che non sia gia presente, quindi ridimensionare il vettore ed aggiungere l'ascissa
Stessa cosa per le ascisse delo strato
la forma e' essenzialmente questa:
For count = 1 To n_vert_terreno
x = Range("Coordinate_profilo").Cells(count, 1).Value
If x > x_iniz And x < x_finale Then
'controllo che l'ascissa non sia gia presente, se assente incremento
' il contatore e la aggiungo al vettore
doppione = False
For i = 1 To conta_ascisse
If x = XX(i) Then doppione = True
Next
If Not (doppione) Then
conta_ascisse = conta_ascisse + 1
ReDim Preserve XX(1 To conta_ascisse)
XX(conta_ascisse) = x
doppione = False
End If
End If
Next
fatta la stessa cosa col profilo dello strato, adesos mi ritrovo un vettore con ascisse non ordinate. Per potere inserire ulteriori ascisse in funzione del dmax prefissato, mi serve prima ordinare il vettore in modo che per differenza tra due valori successivi possa controllare se il tratto e' maggiore di dmax.
la sub di ordinamento e' banale:
Sub Ordina(XX)
n = UBound(XX)
For i = 1 To n
For j = i To n
x = XX(j)
If XX(i) > x Then
XX(j) = XX(i)
XX(i) = x
End If
Next j
Next i
End Sub
adesso basta procedere al controllo di ogni tratto e nel caso in cui fosse maggiore di dmax, inserire un numero di ascisse pari all'intero di dx/dxmax. Deposito queste nuove ascisse in un vettore di appoggio che poi accoderò al vettore delle ascisse.
ReDim Preserve XX(1 To conta_ascisse + conta_aggiunte)
For i = 1 To conta_aggiunte
XX(conta_ascisse + i) = xx1(i)
Next
adesso mi ritrovo il vettore delle ascisse di nuovo non ordinato.
Lo ordino e scrivo i risultati sul foglio
-
Al codice precedente occorre apportare la seguente correzione
conta_aggiunte = 0
For count = 2 To conta_ascisse
dx = XX(count) - XX(count - 1)
If dx > dxmax Then
ndx = Int(dx / dxmax) + 1
For i = 1 To ndx
conta_aggiunte = conta_aggiunte + 1
ReDim Preserve xx1(1 To conta_aggiunte)
xx1(conta_aggiunte) = XX(count - 1) + i * dx / ndx
Next
End If
Next
Se non sapete come fare la troverete nel prossimo file in avanzamento insieme alla rappresentazione grafica dei conci che per adesso non c'e'.
saluti
-
Afazio mi scuserà se intervengo "a capocchia".
Forse era già stato detto, nel qual caso me lo sono perso.
La funzione concio gestisce una situazione del genere?
(http://s3.postimage.org/wgxj9.jpg) (http://www.postimage.org/image.php?v=Pqwgxj9)
Perchè immagino che le forze che "trattengono" il concio nella sua posizione siano differenti in funzione dello strato attraversato dalla superficie di rottura.
Forse era già stato detto che per evitare questa situazione la suddivisione in conci doveva tenere conto di questo aspetto. Nel qual caso mi scuso.
-
Afazio mi scuserà se intervengo "a capocchia".
Forse era già stato detto, nel qual caso me lo sono perso.
La funzione concio gestisce una situazione del genere?
(http://s3.postimage.org/wgxj9.jpg) (http://www.postimage.org/image.php?v=Pqwgxj9)
Perchè immagino che le forze che "trattengono" il concio nella sua posizione siano differenti in funzione dello strato attraversato dalla superficie di rottura.
Forse era già stato detto che per evitare questa situazione la suddivisione in conci doveva tenere conto di questo aspetto. Nel qual caso mi scuso.
Inizialmente era mia intenzione fargliela gestire, poi viste le enormi difficoltà connesse con questo problema, ho abbandonato l'idea pensando di passare alla funzione anche i punti di intersezione del cerchio con tutte le superfici di separazione e tutti i vertici sia della superficie topografica che di tutte le superfici di separazione.
Nel caso d'esempio che hai riportato, alla funzione arriverebbero tre conci come nella seguente immagine:
(http://img696.imageshack.us/img696/1517/aaao.jpg)
con questa suddivisione la funzione concio gestisce qualsiasi situazione restituendo valori esatti di A, B ed alfa.
Il problema che hai evidenziato l'ho comunque esplicitato e trattato in uno dei cento post che compongono questo 3d
ciao
-
File di afazio reperibile qui
http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=211 (http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=211)
-
Gilean, adesso mi devi dire come ha fatto Afazio a prendere l'immagine che nel mio post è una thumbnail e farla diventare una immagine a grandezza reale.
Come si fa?
Anch'io, anch'io.... ???
-
eccomi con altro aggiornamento del foglio
Prego Gilean di approvare la versione 4 ed eliminare la prima versione mantenendo la penultima.
Qui ho apportato varie modifiche alla funzione di suddivisione in conci, poichè ho riscontrato che malgrado tutti i miei accorgimenti per evitare ascise duplicate la tabella delle ascisse dei conci continuava a riportare ascisse doppioni.
Ho aggiunto due funzioni: una che per fissata ascissa x mi determina l'ordinata del punto di intersezione con il cerchio e l'altra che per fissata ascissa mi determina l'ordinata del punto di intersezione con la superficie topografica.
Queste due coordinate insieme alla ascissa mi servono per disegnare il concio.
Ho inserito le verticali dei conci nel grafico fermandomi per adesso a 40 (mi ero stancato di inserirne altre).
Ho imposto dei limiti al numero dei vertici in input sia per il profilo topografico che per la superficie di separazione tra gli strati.
La parte grafica geometrica e' quasi terminata, resta ancora la definizione della maglia dei centri, la definizione dei parametri geotecnici e poi si dovrebbe passare alla parte geotecnica.
Le convenzioni sul foglio, per chi volesse fare delle prove alla ricerca di un qualche bug, sono sempre le stesse: celle di input su sfondo verdino, mentre tutte le altre contengono formule o i richiami delle varie funzione finora scritte.
Il procedimento e':
- input delle cordinate dei vertici (il numero di ordine si aggiorna automaticamente)
- input dei vertici della superficiedi separazione ( anche qui il numero di ordine si aggiorna automaticamente)
- input dei dati del cerchio
- lettura dei limiti del grafico ed inserimento manuale della quota di partenza delle ordinate
- input del passo massimo di suddivisione in conci
- premere quindi il bottone "suddividi"
- controllare che il numero delle ascisse dei conci non superi 100 e quindi visualizzare il grafico mediante pressione del tasto "vedi grafico"
- se e' il caso aggiustare manualmente i limiti del grafico
Divertitevi anche a vedere le formule contenute nelle celle
saluti
-
trovate il file a cui faccio riferimento nel precedente messaggio qui:
http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=212 (http://ingegneriaforum.it/index.php?action=downloads;sa=view;down=212)
-
che ne dici di prevedere una macro che legga un file dxf con la stratigrfia del pendio ed importarla direttamente nelle celle apposite? fattibile con vba?
-
che ne dici di prevedere una macro che legga un file dxf con la stratigrfia del pendio ed importarla direttamente nelle celle apposite? fattibile con vba?
la cosa e' fattibile ma da file dxf abbastanza laborioso poichè occorrerebbe conoscere perfettamente il formato del file .dxf per andare a reperire la sezione dove iniziare ad estrarre i dati. Sarebbe invece cosa quasi immediata se il file fosse un formato testo. Quindi se riesci ad estrarre le coordinate dei vertici della polilinea e salvarli in un file txt dimmelo e passami il formato del file o in alternativa un file di esempio
-
e' possibile farlo con una macro scritta in vba per autocad, vedi TinPoly della sezione download. Vedrò se riesco ad effettuare questa operazione anche da excel.
-
e' possibile farlo con una macro scritta in vba per autocad, vedi TinPoly della sezione download. Vedrò se riesco ad effettuare questa operazione anche da excel.
IL VBA per autocad agendo dall'interno dell'ambiente opera direttamente sul database degli oggetti presenti nel disegno. Altra cosa e' gestire un file dxf. Per estrarre i dati che ti servono devi conoscere il formato dati del file e attraverso programma scartare tutte le linee del file che riguardano altre sezioni per pervenire alla sezione che ti interessa.
-
difatti l'idea base sarebbe avere un dxf con la sola sezione interessata suddivisa in polilinee, e poi aprire il file dxf da excel ed importare tali punti. Il problema e' se esistono o meno librerie che abbiano le funzioni per gestire l'import dei punti direttamente da excel.
-
difatti l'idea base sarebbe avere un dxf con la sola sezione interessata suddivisa in polilinee, e poi aprire il file dxf da excel ed importare tali punti. Il problema e' se esistono o meno librerie che abbiano le funzioni per gestire l'import dei punti direttamente da excel.
quando apri un file da excel puoi anche scegliere di aprire un file di formato .txt
prima di aprire il file ti appare una finestrella che ti inviat a specificare come vuoi importarli, stabilendo il carattere di separazione dei dati, se il tab o una virgola o altro ecc ecc.
prova ad aprire da excel un file dxf (tanto alla fine anche esso e' un file formato testo) e capisci meglio quello che voglio dire.
-
il problema secondo me non sta tanto nell'apertura nel file, quanto nella lettura dei dati delle coordinate degli oggetti presenti dentro il dxf. Per quello, sempre secondo me, serviranno librerie apposite (come ad esempio mi e' successo in c# per poter esportare/Importare dati da e in file dxf). Da qua però non ho excel e non posso fare prove al riguardo.
Edit: non sapevo che il dxf si potesse anche leggere come file di testo, e proprio ora lo sto osservando meglio...questo secondo me semplifica le cose di parecchio.
-
IL VBA per autocad agendo dall'interno dell'ambiente opera direttamente sul database degli oggetti presenti nel disegno. Altra cosa e' gestire un file dxf. Per estrarre i dati che ti servono devi conoscere il formato dati del file e attraverso programma scartare tutte le linee del file che riguardano altre sezioni per pervenire alla sezione che ti interessa.
Io in VB questo problema l'ho risolto così: 1) apro il file .dxf; 2) cerco la riga ENTITIES (vado a memoria), che contrassegna l'inizio degli oggetto contenuti nel dxf (linee, punti, blocchi, testi, polilinee eccetera); 3) cerchi a seguire le scritte LWPOLYLINE (che contraddistinguono l'inizio di sezione per ciascuna polilinea 2D); in una riga seguente c'è il numero dei punti appartenenti alla polilinea (non ricordo a memoria il codice dietro il quale c'è l'info), le ascisse/ordinate di ciascun punto sono dopo le scritte "10" e "20" rispetivamente. Se ti interessa ti giro qualche info più precisa.
Ciao.
-
Infatti, dopo aver notato che il dxf è un file di testo stavo scrivendo qualche riga di codice che scorresse tutto il file, e fermandosi ad una certa stringa, cominciasse il ciclo di scrittura delle coordinate sulle celle.
questo e' il contenuto relativo alla polilinea di una polilinea a 5 linee
LWPOLYLINE
5
1B0
330
1F
100
Le coordinate dove sono?
Edit: leggendo meglio il file dovrebbero essere specificate in seguito
LWPOLYLINE
5
1B0
330
1F
100
AcDbEntity
8
0
100
AcDbPolyline
90
6
70
0
43
0.0
10
845.5959318439273
20
764.4852931896885
10
1240.860143063539
20
1232.138822771062
10
1958.475742410254
20
1163.140760348933
10
2150.351575965487
20
1370.134947615319
10
2511.07813299037
20
1293.470433812954
10
2791.2168484503
20
1473.632041248512
0
ENDSEC
0
SECTION
2
OBJECTS
Quindi bisogna considerare la AcDbPolyline, ma cosa sono quei numeri dopo la AcDbPolyline? la prima coordinata e' la 845.5959318439273
-
Infatti, dopo aver notato che il dxf è un file di testo stavo scrivendo qualche riga di codice che scorresse tutto il file, e fermandosi ad una certa stringa, cominciasse il ciclo di scrittura delle coordinate sulle celle.
questo e' il contenuto relativo alla polilinea di una polilinea a 5 linee
LWPOLYLINE
5
1B0
330
1F
100
Le coordinate dove sono?
Edit: leggendo meglio il file dovrebbero essere specificate in seguito
LWPOLYLINE
5
1B0
330
1F
100
AcDbEntity
8
0
100
AcDbPolyline
90
6
70
0
43
0.0
10
845.5959318439273
20
764.4852931896885
10
1240.860143063539
20
1232.138822771062
10
1958.475742410254
20
1163.140760348933
10
2150.351575965487
20
1370.134947615319
10
2511.07813299037
20
1293.470433812954
10
2791.2168484503
20
1473.632041248512
0
ENDSEC
0
SECTION
2
OBJECTS
Quindi bisogna considerare la AcDbPolyline, ma cosa sono quei numeri dopo la AcDbPolyline? la prima coordinata e' la 845.5959318439273
non e' cosi semplice.
Cercare di scrivere un codice che ti legga i vertici di una polilinea senza conoscere il formato dati e' come andare al buio.
Intanto il file dxf di una stessa polilinea e' diverso da ambiente ad ambiente poichè in esso sono registrati anche altre variabili che dipendono dalle personalizzazioni di autocad.
Potresti trovarti per esempio anche il codice 30 che anticipa la coordinata z anche se hai disegnato una polilinea su un piano.
In ogni caso il codice che scriveresti non terrebbe conto del fatto che nello stesso file potrebbero essere presenti piu di una polilinea e tu leggeresti solo la prima oppure dovresti imporre a chi fa il disegno in cad di tracciare una polilinea per volta, mentre naturalmente chi fa il disegno metterebbe pure le polilinee di separazione tra gli strati.
Quindi dovresti farle differenziare per layer o per colore e stabilire la convenzione comunicandola al disegnatore.
Meglio, invece, procedere al contrario: da ambiente cad scrivi un programma che, selezionando la polilinea che ti interessa, registri le coordinate dei vertici in un file txt.
Poi si importerebbero le polilineee dai file txt attraverso una macro dedicata.
-
Sarà ma che io sappia il dxf è nato come file di interscambio tra i vari software, pertanto dovrebbe essere standardizzato:
http://it.wikipedia.org/wiki/AutoCAD_DXF (http://it.wikipedia.org/wiki/AutoCAD_DXF)
Ripeto, mi approccio ora a questo formato, ma non mi sembra che debba essere così differente tra i vari programmi, altrimenti l'interoperabilità andrebbe a farsi friggere.
-
Sarà ma che io sappia il dxf è nato come file di interscambio tra i vari software, pertanto dovrebbe essere standardizzato:
http://it.wikipedia.org/wiki/AutoCAD_DXF (http://it.wikipedia.org/wiki/AutoCAD_DXF)
Ripeto, mi approccio ora a questo formato, ma non mi sembra che debba essere così differente tra i vari programmi, altrimenti l'interoperabilità andrebbe a farsi friggere.
esatto, e' standardizzato, ma per poter interagire e quindi scambuare dati tra diverse applicaioni occorre conoscere lo standard.
IL fatto che possa anche presentarsi il codice 30 e' regolamente stabilito nella standard di modo che chiuque, conoscendo cio' possa scrivere nel suo codice:
if rigo=30
saltalo che non mi interessa
end if
ecco perche ti dico che devi conoscere il formato dati del file dxf, cioè lo standard.
edit:
Siccome io non lo conosco, non posso scrivere una funzione che legga un dxf per estrarre i vertici della polilinea, mentre verrebbe banale per un file txt.
ciao
-
Pare che lo standard dell'autocad 2010 sia questo
http://images.autodesk.com/adsk/files/acad_dxf1.pdf (http://images.autodesk.com/adsk/files/acad_dxf1.pdf)
Ora esistono diversi PDF in base alla versione di autocad, il che mi confonde non poco.
-
Non è poi così difficile come sembra: nel codice prima di tutto a mio avviso bisognerebbe leggere tutte le LWPOLYLINE e non fermarsi dopo la prima. Ricapitolo guardando un mio codice:
1) cerco LWPOLYLINE dopo l'inizio della sezione ENTITIES;
2) procedi con la lettura del file, una riga alla volta, cercando "AcDbpolyline";
3) cerchi il campo " 90" e la lettura successiva rappresenta il numero di punti della polilinea (nell'esempio di Gilean era 6);
4) cerchi il campo " 43", seguito da "0.0";
5) a seguire le coordinate x ed y dei punti dopo i campi " 10" e " 20".
Io l'ho usata parecchie volte questa tecnica e non mi ha mai dato problemi. Versioni più evolute di Autocad aggiungono campi nuovi ma non modificano i codici di quelli esistenti a quanto ne so.
Ciao.
-
ottimo, grazie mille alberto.
-
ho provato ad esercitarmi con il mio VBA maccheronico per leggere i vertici di una polilinea.
funziona così:
1) salvare la polilinea in dxf versione R12
2) aprire il dxf con blocco note e copiare il testo
3) incollare il testo in cella 1,1
4) avviare macro
la scelta di legare il codice alla versione r12 di dxf mi pare il male minore.
ha la struttura più semplice ed in acad è sempre rimasta la possibilità di salvare in questo formato.
il codice non è elegante ma mi pare funzioni.
Sub leggipolydxf()
Cells(1, 1).Activate
Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select
numrighe = Selection.Rows.Count
Cells(1, 9) = "numero righe dxf"
Cells(1, 10) = numrighe
Cells(2, 9) = "numero punti"
Cells(1, 3) = "punto n."
Cells(1, 4) = "X"
Cells(1, 5) = "Y"
Count = 0
i = 1
Do While Cells(i, 1) <> "EOF"
If Cells(i, 1).Value = "VERTEX" Then
Count = Count + 1
Cells(Count + 1, 3) = Count
Cells(Count + 1, 4) = Cells(i + 6, 1)
Cells(Count + 1, 5) = Cells(i + 8, 1)
i = i + 9
Else
i = i + 1
End If
Loop
Cells(2, 10) = Count
End Sub
in alternativa a nella versione 2008 di acad è stata introdotta la funzione "data extraction", che permette di estrarre tabelle di dati relative agli oggetti, quindi p.e. le coordinate dei vertici di una o più polilinee.
-
Vedo che l'argomento non é più "attivo", complimenti ad afazio e a tutti gli intervenuti per la dotta qualità degli interventi.
se non mi sono perso qualcosa... ho trovato poco o nulla sul solutore, mi sembra di capire che si vogliano esaminare solo superfici circolari.
mi ero occupato di questo argomento qualche anno fa, prima con HP41CV, poi col gwbasic (che gira ancora sotto XP) e al max con il programma compilato.
Ho avuto la fortuna di fare "lo scudieronumerico" di un prof. di geotecnica e, in allora ho fatto montagne di numeri, qualcosa anche per la val pola.
Se può essere di interesse posso mettere in linea bishop, janbu semplificato e forse anche janbu generalizzato -superfici qualunque,sarma - interazioni fra pareti vert. conci, certo bisogna ripassarsi 2 comandi di basic se non altro per stampare i listati.
saluti
-
Vedo che l'argomento non é più "attivo", complimenti ad afazio e a tutti gli intervenuti per la dotta qualità degli interventi.
se non mi sono perso qualcosa... ho trovato poco o nulla sul solutore, mi sembra di capire che si vogliano esaminare solo superfici circolari.
mi ero occupato di questo argomento qualche anno fa, prima con HP41CV, poi col gwbasic (che gira ancora sotto XP) e al max con il programma compilato.
Ho avuto la fortuna di fare "lo scudieronumerico" di un prof. di geotecnica e, in allora ho fatto montagne di numeri, qualcosa anche per la val pola.
Se può essere di interesse posso mettere in linea bishop, janbu semplificato e forse anche janbu generalizzato -superfici qualunque,sarma - interazioni fra pareti vert. conci, certo bisogna ripassarsi 2 comandi di basic se non altro per stampare i listati.
saluti
certo che è di interesse!!! :ook:
PS. Benvenuto nel forum :ciau:
-
Vedo che l'argomento non é più "attivo", complimenti ad afazio e a tutti gli intervenuti per la dotta qualità degli interventi.
se non mi sono perso qualcosa... ho trovato poco o nulla sul solutore, mi sembra di capire che si vogliano esaminare solo superfici circolari.
mi ero occupato di questo argomento qualche anno fa, prima con HP41CV, poi col gwbasic (che gira ancora sotto XP) e al max con il programma compilato.
Ho avuto la fortuna di fare "lo scudieronumerico" di un prof. di geotecnica e, in allora ho fatto montagne di numeri, qualcosa anche per la val pola.
Se può essere di interesse posso mettere in linea bishop, janbu semplificato e forse anche janbu generalizzato -superfici qualunque,sarma - interazioni fra pareti vert. conci, certo bisogna ripassarsi 2 comandi di basic se non altro per stampare i listati.
saluti
Nelle mie intenzioni nonc'era solo lo studio della parte geometrica delle superfici, ma anche la parte dell'equilibrio.
Purtroppo pero' mi sono fermato e non riesco a trovare piu quella spinta, in termini di tempo , che mi faccia continuare.
Ma lo spirito del topic non era quello "ora vi spiego come si fa", e lo potrai anche evincere leggendo qualche intervento, bensi' "io inizio, ma voi poi datemi na mano".
saluti
-
Vedo che l'argomento non é più "attivo", complimenti ad afazio e a tutti gli intervenuti per la dotta qualità degli interventi.
se non mi sono perso qualcosa... ho trovato poco o nulla sul solutore, mi sembra di capire che si vogliano esaminare solo superfici circolari.
mi ero occupato di questo argomento qualche anno fa, prima con HP41CV, poi col gwbasic (che gira ancora sotto XP) e al max con il programma compilato.
Ho avuto la fortuna di fare "lo scudieronumerico" di un prof. di geotecnica e, in allora ho fatto montagne di numeri, qualcosa anche per la val pola.
Se può essere di interesse posso mettere in linea bishop, janbu semplificato e forse anche janbu generalizzato -superfici qualunque,sarma - interazioni fra pareti vert. conci, certo bisogna ripassarsi 2 comandi di basic se non altro per stampare i listati.
saluti
ogni contributo e' sempre gradito
grazie
-
qui trovate i files
http://www.box.net/shared/r9sh9gmwwc (http://www.box.net/shared/r9sh9gmwwc)
non mi ricordo quasi più nulla di gwbasic, la funzione llist non opera correttamente
passo il tutto a qualcuno di buona volontà.
so di avere in giro i riferimenti, la bibliografia, gli articoli, se servono...
a memoria direi che il pendio era bassO A SX E ALTO A dX
saluti
... comunque non ci sono più i PC di una volta....
M24 é partito al primo colpo senza fare cilecca... a 5-6 anni dall'ultima accensione!
-
sempre in tema di solutore
...oppure potreste indirizzare le attività "in fieri" verso la creazione di un pre-post processore per il software, una volta libero e disponibile in rete della Purdue University
Pcstabl
http://www.google.com/search?q=purdue+university+pcstabl+slope+stability&rls=com.microsoft:it:IE-SearchBox&ie=UTF-8&oe=UTF-8&sourceid=ie7&rlz=1I7ADBF_it (http://www.google.com/search?q=purdue+university+pcstabl+slope+stability&rls=com.microsoft:it:IE-SearchBox&ie=UTF-8&oe=UTF-8&sourceid=ie7&rlz=1I7ADBF_it)
che dovrebbe ancora essere disponibile .
Ho visto al made expo che anche la software house di pro-sap ha realizzato un prodotto basato su questo stesso motore....
saluti