Problema geometrico su macchine CNC.
Salve a tutti,
vorrei esporvi un problema di tipo geometrico che ho incontrato nello sviluppo di un software per macchine a controllo numerico e non sapendo dove postare ho pensato di lasciarlo qui!!!
il problema è piuttosto semplice : percorrere un segmento AB comunque orientato nello spazio (x,y,z) partendo dal punto A e potendo effettuare solo spostamenti di lunghezza fissa predefinita lungo ogni asse.
Provo a spiegarmi meglio con un esempio su un piano: mi trovo nel punto A(10,12) e devo raggiungere il punto B(27,-96) (o il punto a B più vicino possibile) eseguendo solo spostamenti pari a 0,85 per ogni singolo asse, quindi a partire da A il primo punto successivo P(x,y) che posso raggiungere sarà uno dei seguenti :
1)P(10 + 0,85 , 12 + 0,85)
2)P(10 - 0,85 , 12 + 0,85)
3)P(10 + 0,85 , 12 - 0,85)
4)P(10 - 0,85 , 12 - 0,85)
5)P(10 , 12 + 0,85)
6)P(10 , 12 - 0,85)
7)P(10 + 0,85 , 12 )
8)P(10 - 0,85 , 12 )
ora non mi resta che calcolare la distanza di ogniuno degli 8 punti P(x,y) possibili dalla retta passante per AB e scegliere il più vicino al segmento da seguire e ricominciare da capo sino a raggiungere il punto B o un suo "intorno"!
Ovviamente posso estendere il ragionamento sullo spazio a 3 dimensioni.
Purtroppo questo sistema già su 2 dimensioni richiede di calcolare almeno 8 distanze ed eseguire i relativi confronti, su 3 assi diventa improponibile.
Se qualcuno ha la possibilità di proporre un algoritmo più veloce sarò ben lieto di testarlo sul mio sistema!!!!
Grazie a tutti in attesa di una vostra idea!!!
vorrei esporvi un problema di tipo geometrico che ho incontrato nello sviluppo di un software per macchine a controllo numerico e non sapendo dove postare ho pensato di lasciarlo qui!!!
il problema è piuttosto semplice : percorrere un segmento AB comunque orientato nello spazio (x,y,z) partendo dal punto A e potendo effettuare solo spostamenti di lunghezza fissa predefinita lungo ogni asse.
Provo a spiegarmi meglio con un esempio su un piano: mi trovo nel punto A(10,12) e devo raggiungere il punto B(27,-96) (o il punto a B più vicino possibile) eseguendo solo spostamenti pari a 0,85 per ogni singolo asse, quindi a partire da A il primo punto successivo P(x,y) che posso raggiungere sarà uno dei seguenti :
1)P(10 + 0,85 , 12 + 0,85)
2)P(10 - 0,85 , 12 + 0,85)
3)P(10 + 0,85 , 12 - 0,85)
4)P(10 - 0,85 , 12 - 0,85)
5)P(10 , 12 + 0,85)
6)P(10 , 12 - 0,85)
7)P(10 + 0,85 , 12 )
8)P(10 - 0,85 , 12 )
ora non mi resta che calcolare la distanza di ogniuno degli 8 punti P(x,y) possibili dalla retta passante per AB e scegliere il più vicino al segmento da seguire e ricominciare da capo sino a raggiungere il punto B o un suo "intorno"!
Ovviamente posso estendere il ragionamento sullo spazio a 3 dimensioni.
Purtroppo questo sistema già su 2 dimensioni richiede di calcolare almeno 8 distanze ed eseguire i relativi confronti, su 3 assi diventa improponibile.
Se qualcuno ha la possibilità di proporre un algoritmo più veloce sarò ben lieto di testarlo sul mio sistema!!!!
Grazie a tutti in attesa di una vostra idea!!!
Risposte
per pulcepelosa :
il tempo NON PUO' ESSERE UNA VARIABILE perchè invio il comando ai motori via porta parallela, quindi (nel caso di 2 assi) ho tre possibilità :
1) Abilito solo il pin del motore asse x
2) Abilito solo il pin del motore asse y
3) Abilito i pin di entrambi i motori
purtroppo la meccanica in gioco mi permette solo di decidere quali motori fanno un passo!
poi ricomincio per un nuovo spostamento aspettando un tempo stabilito tra un clock e il successivo che tra le altre cose avrà una accellerazione all'inizio del movimento e una decellerazione alla fine del segmento per tener conto delle masse in movimento e della loro inerzia!
per ora solo movimenti lineari... poi dovro implementare anche per archi di circonferenza!
per codino75:
proverò a postare sul generale (posso fare un link?) .
il problema è che i parametri variano e quindi non posso fare un lavoro offline , o devo farlo creare di volta in volta al sistema al cambiare dei parametri!
il tempo NON PUO' ESSERE UNA VARIABILE perchè invio il comando ai motori via porta parallela, quindi (nel caso di 2 assi) ho tre possibilità :
1) Abilito solo il pin del motore asse x
2) Abilito solo il pin del motore asse y
3) Abilito i pin di entrambi i motori
purtroppo la meccanica in gioco mi permette solo di decidere quali motori fanno un passo!
poi ricomincio per un nuovo spostamento aspettando un tempo stabilito tra un clock e il successivo che tra le altre cose avrà una accellerazione all'inizio del movimento e una decellerazione alla fine del segmento per tener conto delle masse in movimento e della loro inerzia!
per ora solo movimenti lineari... poi dovro implementare anche per archi di circonferenza!
per codino75:
proverò a postare sul generale (posso fare un link?) .
il problema è che i parametri variano e quindi non posso fare un lavoro offline , o devo farlo creare di volta in volta al sistema al cambiare dei parametri!
non so se puoi postare un link.
sono curioso pure io di sapere se esiste una soluzione generale del problema...
sono curioso pure io di sapere se esiste una soluzione generale del problema...
Dillo a me!!!
proviamo a vedere il problema da un'angolazione diversa:
consideriamo per comodità che il mio punto A sia l'origine degli assi e che io parta con i miei passi lo stesso dall'origine.
solo conoscendo le coordinate del punto B :
posso già stabilire all'inizio in che direzione saranno tutti i miei passi in base alla direzione del segmento.
posso gia stabilire inoltre il numero di passi che devo fare su ogni asse e conoscendo per impostazione la lunghezza del mio passo praticamente conosco la griglia sulla quale passa il mio segmento.....
supposto l'equazione della retta che sottende il segmento come y=ax posso sostituire le sucessive x della mia griglia e calcolare le y piu prossime alla retta che devo seguire.
che ti sembra come ragionamento?
proviamo a vedere il problema da un'angolazione diversa:
consideriamo per comodità che il mio punto A sia l'origine degli assi e che io parta con i miei passi lo stesso dall'origine.
solo conoscendo le coordinate del punto B :
posso già stabilire all'inizio in che direzione saranno tutti i miei passi in base alla direzione del segmento.
posso gia stabilire inoltre il numero di passi che devo fare su ogni asse e conoscendo per impostazione la lunghezza del mio passo praticamente conosco la griglia sulla quale passa il mio segmento.....
supposto l'equazione della retta che sottende il segmento come y=ax posso sostituire le sucessive x della mia griglia e calcolare le y piu prossime alla retta che devo seguire.
che ti sembra come ragionamento?
non e' che ci ho capito molto...
potresti fare, anche se e' complicato lo so , un esempio semplice?
potresti fare, anche se e' complicato lo so , un esempio semplice?
se ho capito bene tu, invece di minimizzare la distanza punto-retta, vorresti , fissata la x, prendere , tra le 2 y possibili (una che sa sopra il segmento e l'altra che sta sotto), quella piu' vicina al segmento insenso verticale?
l'idea m isembra buona.
quindi per ogni intersezione con le linee verticali della griglia, ti calcoli quale dei due punti e' verticalmente piu' vicino...
a questo punto hai tanti puntie puoi unirli....
mi sembra che funzioni la cosa...
l'unico problema e' che devi calcolarti tutti i punti di contatto tra retta e linee verticali della griglia...
quindi per ogni intersezione con le linee verticali della griglia, ti calcoli quale dei due punti e' verticalmente piu' vicino...
a questo punto hai tanti puntie puoi unirli....
mi sembra che funzioni la cosa...
l'unico problema e' che devi calcolarti tutti i punti di contatto tra retta e linee verticali della griglia...
"codino75":
l'idea m isembra buona.
quindi per ogni intersezione con le linee verticali della griglia, ti calcoli quale dei due punti e' verticalmente piu' vicino...
a questo punto hai tanti puntie puoi unirli....
mi sembra che funzioni la cosa...
l'unico problema e' che devi calcolarti tutti i punti di contatto tra retta e linee verticali della griglia...
Si... ma i punti dovrei calcolarli lo stesso perche tanto ci devo passare per arrivare a B!!
devo solo calcolare prina se faccio più passi sull'asse x o su y e se Y>X devo invertire il ragionamento!!
Ok, ti illustro un possibile procedimento, che mi sembra abbastanza buono (te lo illustro nel prmo quadrante, poi è facilmente estendibile).
Allora, se il coefficiente angolare è maggiore di uno, trovi la $x$ da $y=mx+q$ (sempre se puoi farlo) per $y=1,2,3,\ldots$, fino a $y~=B_y$, dove $B_y$ è l'ordinata del punto $B$. Se la $x$ trovata è minore di $1/2$, allora vai in alto, se $x>=1/2$, allora ti sposti sulla diagonale. Parlo di $1/2$, quando lo spostamento che puoi fare è di $1$.
Dovresti seguire il segmento. Con lo stesso ragionamento, lo estendi per $m<1$, e per gli altri quadranti.
Allora, se il coefficiente angolare è maggiore di uno, trovi la $x$ da $y=mx+q$ (sempre se puoi farlo) per $y=1,2,3,\ldots$, fino a $y~=B_y$, dove $B_y$ è l'ordinata del punto $B$. Se la $x$ trovata è minore di $1/2$, allora vai in alto, se $x>=1/2$, allora ti sposti sulla diagonale. Parlo di $1/2$, quando lo spostamento che puoi fare è di $1$.
Dovresti seguire il segmento. Con lo stesso ragionamento, lo estendi per $m<1$, e per gli altri quadranti.
si che mi sembra buono.... faccio due prove e ti faccio sapere!!!
:-):-):-):-):-):-):-):-):-)

Mi sono espresso male. Intendo che se la parte decimale della $x$ trovata è maggiore di $1/2$ (cioè se ${x}>=1/2$), allora vai in diagonale, se $<1/2$, allora in alto. Attento, però, quando il coefficiente angolare è minore di uno, allora devi trovare la $y$ da $y=mx+q$ etc.
sembra non funzionare.
ti posto un po di codice : serve solo un form, un picturebox e un commandbutton
Private Sub Command1_Click()
Dim xa, xb, ya, yb, m, Passo, xt, yt, xx
Passo = 100
xa = 500: ya = 300: xb = 1000: yb = 4000
xt = xa
yt = ya
pic.Line (xa, ya)-(xb, yb)
m = (yb - ya) / (xb - xa)
For f = 1 To yb - Passo Step Passo
xx = (xa - xb) / (ya - yb) * f + ((xb * ya - xa * yb) / (ya - yb))
If ((xx - Int(xx)) >= 0.5) Then
pic.Line (xt, yt)-(xt + Passo, yt + Passo)
xt = xt + Passo
yt = yt + Passo
Else
pic.Line (xt, yt)-(xt, yt + Passo)
yt = yt + Passo
End If
Next
End Sub
provalo e vedrai che non segue la retta.
Mi puoi spiegare il ragionamento che hai fatto per arrivare a questa conclusione giusta o sbagliata che sia? tanto per capire
ti posto un po di codice : serve solo un form, un picturebox e un commandbutton
Private Sub Command1_Click()
Dim xa, xb, ya, yb, m, Passo, xt, yt, xx
Passo = 100
xa = 500: ya = 300: xb = 1000: yb = 4000
xt = xa
yt = ya
pic.Line (xa, ya)-(xb, yb)
m = (yb - ya) / (xb - xa)
For f = 1 To yb - Passo Step Passo
xx = (xa - xb) / (ya - yb) * f + ((xb * ya - xa * yb) / (ya - yb))
If ((xx - Int(xx)) >= 0.5) Then
pic.Line (xt, yt)-(xt + Passo, yt + Passo)
xt = xt + Passo
yt = yt + Passo
Else
pic.Line (xt, yt)-(xt, yt + Passo)
yt = yt + Passo
End If
Next
End Sub
provalo e vedrai che non segue la retta.
Mi puoi spiegare il ragionamento che hai fatto per arrivare a questa conclusione giusta o sbagliata che sia? tanto per capire

non ho seguito gli ultimi sviluppi del post, ma potrebbe essere che la soluzione proposta da crook non considera il fatto che il punto corrente puo' stare sotto ma anche sopra la retta?
"codino75":
non ho seguito gli ultimi sviluppi del post, ma potrebbe essere che la soluzione proposta da crook non considera il fatto che il punto corrente puo' stare sotto ma anche sopra la retta?
Mi sa di si, ma aspetto maggiori info da crook!!
io stò studiando il sistema della griglia, sembra promettente, pochi calcoli per singolo passo!!
la cosa che mi lascia perplesso è se posso considerare "più vicino" il fatto che sia minore la distanza lungo l'ordinata!!
e pensare che poi devo trasportare tutto su tre assi mi viene da piangere!!!



"johnjohn":
io stò studiando il sistema della griglia, sembra promettente, pochi calcoli per singolo passo!!
la cosa che mi lascia perplesso è se posso considerare "più vicino" il fatto che sia minore la distanza lungo l'ordinata!!
penso di si' perche' tratasi di segmenti.
diverso sarebbe se si trattasse di linee curve.
per quanto riguerda la generalizzazione in 3 dimensioni....
fors epuoi scomporre il problema delle 3 dimensioni in 2 problemi da 2 dimensioni, dove ciascun problema a 2 dimensioni e' quello di seguire la proiezione del segmento su un piano 'verticale', dove i 2 piani verticali sono appunto i piani individuati dagli assi del sistema cartesiano di riferimento...
spero di essermi spiegato...

alex
p.s.:mi sa che il tuo metodo iniziale era il piu' semplice...
Ti avevo detto che ti illustro una piccola parte del procedimento generale. Era solo quando il punto B era sopra, sì. Ti ho fato l'idea, ora basta che la generalizzi, e mi sa che dovrai scrivere un po' più di codice.