interpolazioni nel CAM

Sezione riservata ai sofware sviluppati in proprio
Rispondi
Avatar utente
franc
Senior
Senior
Messaggi: 1152
Iscritto il: lunedì 13 novembre 2006, 20:10
Località: Ponte S.Giovanni-PG

interpolazioni nel CAM

Messaggio da franc » lunedì 22 settembre 2008, 14:24

Ho estratto quanto segue dal thead Cncontrol by melino65, per una più facile ricerca e raggiungimento.

Ecco la mia tiritera che feci per il vecchio forum, dove non fù mai postato.

Come un Cam può implementare i codici ISO G02 e G03

Chi si dedica alla programmazione di un Cam, deve, tra l'altro, affrontare il problema della implementazione dei codici Iso G02 e G03 onde comandare gli azionamenti necessari per tracciare la curva circolare programmata.

La curva circolare da costruire sarà  caratterizzata da:
1- punto di inizio dell'arco
2- codice che stabilisce il senso di rotazione
2- coordinate del centro di curvatura o in alternativa il raggio
3- punto finale

un codice Iso per una traiettoria circolare potrebbe essere il seguente:
...........
N200 G01 X100 Y50
N210 G02 X169.60 Y47.83 R70
N220 G03 X300 Y70 I221.12 J139.37
......
il cui tracciato è quello in figura 1 allegata in calce.

Al termine dell'esecuzione del blocco 200 l'utensile si trovera in X100 Y50, il blocco 210 indica al Cam che l'utensile deve andare in X169.60 Y47.83 con un arco di raggio 70 percorrendolo in senso (G02) destrorso. Nel grafico il percorso relativo è quello tra A e B di colore nero e il centro è in O1. Con un raggio di queste dimensioni (70) si puo costruire un altro arco, che è quello di colore blu tratteggiato il cui centro è in O2. Per stabilire qual'è l'arco giusto dovremo porre positivo il raggio per il primo arco e negativo per il secondo. In termini geometrici i due archi si distinguono per avere il primo un angolo al centro inferiore a 180 e superiore il secondo. Altra caratteristica, che sarà  utile per le soluzioni geometriche è che i due centri si trovano sull'asse della corda AB, equidistanti dalla stessa.
Per concludere sul blocco 210 se in esso avessimo letto G02 X169.60 Y47.83 R-70 il Cam avrebbe tracciato l'arco blu del grafico.
Faccio notare che il segno - (meno) posto davanti al valore del raggio è solo un flag, infatti un raggio di valore negativo non ha geometricamente senso.

Il blocco 220 indica che l'utensile deve andare in X300 Y70 percorrendo un arco circolare, il cui centro di curvatura si trova a (coord. X ) I221.12 e (coord.Y) J139.37, percorrendo l'arco in senso (G03) sinistrorso. In questo caso la soluzione è una sola e l'arco è quello che va da B a C.
Le coordinate del centro di curvatura possono essere assolote o invrementali, in questo caso riferite alle coordinate del punto raggiunto, che sarà  l'inizio dell'arco.

Cosa deve fare il CAM

Nel corso della stesura del mio programma, non avendo la possibilità  di scrutare i metodi usati dai programmatori professionisti nei vari Cam in commercio, ho trovato un mio sistema che potrebbe non essere il migliore o il più semplice, ma visto che funziona già  da qualche anno, ne riporto i concetti, sperando che qualcuno proponga soluzioni anche diverse.

Prima di tutto occorre stabilire con chiarezza alcuni parametri e creare della variabili affinché non si faccia confusione nella lettura della descrizione:

X-Y-Z coordinate di un punto
Pi = 3.141592 corrispondente all'angolo piatto in radianti
om = angolo al centro che sottende l'arco
xC e yC = coordinate di calcolo del centro di curvatura che saranno rispettivamente = a I e J
te = abbreviazione dell'angolo theta cioè l'angolo che una retta forma con l'asse x del piano
cartesiano girando in senso sinistrorso. Le lettere che seguono ‘te’ indicano la direzione della retta in esame; es teAB sarà  l'angolo tra l'asse X ed il segmento da A a B, teBA sarà  l'angolo tra l'asse X e il segmento da B a A. Riconoscere questi angoli è essenziale per non avere risultati sballati, per questo riporto alcuni esempi, vedi fig 2 in calce.

Per tracciare l'arco programmato, partendo dal punto d'inizio, dobbiamo cercare le caratteristiche geometriche di punti successivi, disposti sull'arco e distanti l'un l'altro di una entità  che sarà  funzione del passo minimo possibile per gli assi interessati e del raggio della curva.

Supponiamo di lavorare sul piano XY, ci servirà  il minimo spostamento possibile in X e Y; supponiamo ancora che dette entità  siano uguali per entrambi gli assi e siano di 1/100 di mm.
Sappiamo che la nostra curva sarà  costituita da tratti rettilinei, i cui percorsi saranno tanto più vicini alla curva quanto più brevi saranno questi segmenti. E' risaputo che l'utensile nel percorrere la curva si discosta da questa provocando un errore il cui massimo valore si verifica nei tratti di curva inclinati di 45° rispetto agli assi e sarà  pari al passo minimo per il seno di 45°; nel nostro caso 0.01 x 0.708 = 0.007 cioè 7/1000 di mm. Per tratti ad inclinazione diversa dai 45° potrebbe essere anche vicino al passo minimo, ma in sede di azionamento dei motori vedremo come si può intervenire dimezzando l'errore.


Per determinare le coordinate dei punti successivi al primo, dobbiamo definire meglio le caratteristiche geometriche della curva che, come si è già  detto, sono: i punti di inizio e fine, il raggio, le coordinate del centro e l'angolo al centro. Riprendendo il nostro codice e leggendo i blocchi 200 e 210, sappiamo che il nostro arco comincia a x100, y50, finisce a x169.50 y47.83 ed ha un raggio di curvatura di 70 mm. La curva relativa è illustrata in figura 3 in calce.

Cominciamo con determinare la lunghezza della corda AB, con Pitagora essa sarà 
AB = sqr( (yB-yA)^2 +( xB-yA)^2)
Con la trigonometria occorre prima trovare la pendenza di AB e poi la distanza
La pendenza cioè te(AB) ci servirà  successivamente, quindi io ho usato questo metodo.
Te(AB) = arctan ( (yB–yA) / (xB–xA) )
AB = (yB–yA) / sen (te(AB))
Il triangolo ABO è un triangolo isoscele di cui conosciamo tutti i lati, AB e due lati uguali pari al raggio R. Il triangolo AMO è un triangolo rettangolo in M. possiamo determinare gli angoli a (alfa) e om (omega):
a =arccos ( AB/(2*R) )
om = 2 * arcsen ( AB / (2*R) )
nelle due formule precedenti il valore di R dovrà  essere espresso in valore assoluto poiché sappiamo che detto valore può essere preceduto dal (flag) segno negativo.
Ora possiamo calcolare te(AO) e le coordinate di O.
te(AO) = te(AB) – a . nel caso specifico te(AO) è negativo per cui si prende il suo esplementare cioè 2 * pi + (–a)
Il segno (–) posto davanti alla R indica che l’arco ha uno sviluppo il cui angolo al centro è superiore a 180° quindi il centro di curvatura si trova nel punto O2 (foto 1) simmetrico a O1 rispetto alla direzione AB. In questo caso te(AO) = te(AB) + a.
xO = xA + R (cos(te(AO)
yO = yA + R (sen(te(AO)

Abbiamo ora tutti gli elementi necessari per calcolare le coordinate di un punto generico (P), che si trova ad una distanza angolare (e), frazione di OM.
Te(OP) = te(OA) – e
xP = xO + R * cos(te(OP))
yP=yO + Rr* sen(te(OP))

Nel caso specifico essendo te(OP) un valore del secondo quadrante avremo la funzione seno positiva e la funzione coseno negativa per cui yP sarà  maggiore di yO mentre Xp sarà  minore di xO.

Stabilendo un loop da te(OA) a te(OB) con un adeguato step si potranno calcolare le coordinate dei punti che in successione da A a B permettono di costruire la curva.
Lo step è ovviamente angolare espresso in radianti, potrebbe essere pari all'arctan( passo minimo della macchina, diviso il raggio della curva) ed avrà  segno positivo se la curva gira a sinistra (G3) e segno negativo se la curva gira a destra (G2).

Nel caso in cui il codice indichi le coordinate I e J invece del raggio della curva, per arrivare allo stesso risultato dovremo calcolare i vari angoli con lo stesso metodo esposto e il raggio, che è pari alla distanza AO.

Te (OA) = arctan ( (yA – J) / (xA – I) )
Te (OB) = arctan ( (yB – j ) / (xB – i) )
om = te(AB) – te(OB)
R = (yA – J) / te(OA)

Da qui è come nel caso precedente.

E ovvio che il calcolo dei theta (te) dovrà  essere seguito da una routine nella quale, sulla base di opportune relazioni condizionali, verrà  stabilito il quadrante di appartenenza in base al valore delle coordinate relative ai punti considerati. La routine dovrà  anche comprendere relazioni condizionali per prefissare il theta nei casi di rette parallele agli assi, che provocherebbero errore per valori di arctan pari a zero (parallela all’asse X) o infinito (parallela all’asse Y). http://www.cncitalia.net/forum/viewtopic.php?t=1787

La curva così determinata in realtà  sarà  una polilinea i cui lati saranno tanto più piccoli quanto più piccolo sarà  lo step che comunque non avrà  effetto se scelto più piccolo del valore arctan(passo minimo/R).

nota: calcolata la corda AB sarà  necessario che il programma controlli se il raggio calcolato o rilevato dal codice sia uguale o maggiore di AB/2; in caso contrario sarà  necessario un messaggio d'errore.

Mi auguro di essere stato chiaro comunque sono disponibile per ulteriori chiarimenti e soprattutto per conoscere metodi anche diversi .

salutoni
Non hai i permessi necessari per visualizzare i file e le foto allegati in questo messaggio. Per visualizzare tali file devi registrarti ed effettuare il Login
Ultima modifica di franc il sabato 18 ottobre 2008, 12:20, modificato 1 volta in totale.
franc
cerco sempre di fare tutto con entusiasmo, ma a volte non è sufficiente.

velleca55

Messaggio da velleca55 » lunedì 22 settembre 2008, 14:49

Mi fai sentire più stupido di quanto già  non sono ... :( ...

Ti seguo e anche capisco, ma non saprei partecipare ad una discussione cosi per mancanza di tempo per studiare il tema ...

Magari mi manca un po di scuola ...

Comunque ti leggo con piacere ... grazie per l'approfondimento ...

.

Avatar utente
franc
Senior
Senior
Messaggi: 1152
Iscritto il: lunedì 13 novembre 2006, 20:10
Località: Ponte S.Giovanni-PG

Messaggio da franc » lunedì 22 settembre 2008, 15:24

Ciao Donato,

se mi venissa in mente di creare o scopiazzare una delle tue opere,

oppure di fare una macchina come quelle che fa Tiziano o il tornio di Engine,

e cosi potrei continuare per altre cose viste sul forum,

mi troverei in serie difficoltà .

Ognuno predilige o riesce meglio solo in certi settori, che per studio o per hobby gli sono congeniali. Il tutto accompagnato da volontà  e perseveranza.

E' per questo che l'unione fa la forza.

a presto

ciao
Ultima modifica di franc il lunedì 22 settembre 2008, 16:22, modificato 1 volta in totale.
franc
cerco sempre di fare tutto con entusiasmo, ma a volte non è sufficiente.

velleca55

Messaggio da velleca55 » lunedì 22 settembre 2008, 15:53

... :wink: ...



.

anonimo/3

Messaggio da anonimo/3 » lunedì 22 settembre 2008, 17:46

:shock: :shock: bravissimo

ENGINE
Senior
Senior
Messaggi: 2734
Iscritto il: venerdì 12 gennaio 2007, 1:20
Località: Milano Milano

Messaggio da ENGINE » lunedì 22 settembre 2008, 21:45

Franc e' bravissimo senza alcun dubbio.....

MA IO NON C'HO CAPITO UNA CIPPA DI MINCHIA !!!! :lol: :lol:
Lavorare il metallo e' il piu' bel lavoro del mondo.
Giuseppe non era un falegname... era un fabbro.

Avatar utente
franc
Senior
Senior
Messaggi: 1152
Iscritto il: lunedì 13 novembre 2006, 20:10
Località: Ponte S.Giovanni-PG

Messaggio da franc » domenica 28 settembre 2008, 9:10

Io penso che tu abbia letto in fretta come succede a chi è indaffarato.
Se la cosa ti interessa posso ripetere esponendo in modo diverso, tutto o parte, come da tue eventuali indicazioni.

ciao
franc
cerco sempre di fare tutto con entusiasmo, ma a volte non è sufficiente.

gawain
Newbie
Newbie
Messaggi: 23
Iscritto il: martedì 8 dicembre 2009, 22:56
Località: milano

Re: interpolazioni nel CAM

Messaggio da gawain » domenica 3 gennaio 2010, 18:10

qui una soluzione veloce perche implementabile in numeri interi e senza la nacessita di funzioni trigonometrice e estrazione di radice (vedi helix.zip)
Non hai i permessi necessari per visualizzare i file e le foto allegati in questo messaggio. Per visualizzare tali file devi registrarti ed effettuare il Login
Ultima modifica di Anonymous il domenica 3 gennaio 2010, 18:25, modificato 1 volta in totale.
Motivazione: ... tolto riporto "chilometrico" ed inutile, poiché presente nella stessa pagina del riporto ...

velleca55

Re: interpolazioni nel CAM

Messaggio da velleca55 » domenica 3 gennaio 2010, 18:27

Gawain ... ti ho tolto il riporto che avevi fatto di TUTTO il primo messaggio di Franc ... era completamente esagerato, ripetitivo, ed inutile ... :wink: ...

Grazie per il tuo intervento comunque, anche se non ho tempo adesso per provare, e nemmeno le capacità  ... però ricordati che nel forum solo alcuni sanno l'inglese, e con temi cosi complessi allora ...

gawain
Newbie
Newbie
Messaggi: 23
Iscritto il: martedì 8 dicembre 2009, 22:56
Località: milano

Re: interpolazioni nel CAM

Messaggio da gawain » lunedì 4 gennaio 2010, 0:48

hai ragione bisognerebbe tradurlo...perchè è davvero interessante per la sua semplicità  (usa solo le 4 operazioni)e perche parte dalla considerazione fondamentale e soprattutto reale che le interpolazioni di cui si parla sono discrete (nel senso di non continue), abbiamo a che fare con encoder e/o stepper, quindi con una realta fatta di numeri interi...(piu velocita per i processori :) )
Ultima modifica di Anonymous il lunedì 4 gennaio 2010, 1:02, modificato 1 volta in totale.
Motivazione: ... tolto riporto consecutivo ...

velleca55

Re: interpolazioni nel CAM

Messaggio da velleca55 » lunedì 4 gennaio 2010, 1:03

Aspettiamo altri commenti ... :wink: ...

gawain
Newbie
Newbie
Messaggi: 23
Iscritto il: martedì 8 dicembre 2009, 22:56
Località: milano

Re: interpolazioni nel CAM

Messaggio da gawain » sabato 9 gennaio 2010, 11:30

esiste questo interessante algoritmo di estrazione di radice quadrata utile per le interpolazioni che è molte volte piu veloce del sistema classico. l'autore è john carmak un mostro sacro del soft grafico.

/*
================
SquareRootFloat
================
*/
float SquareRootFloat(float number) {
long i;
float x, y;
const float f = 1.5F;

x = number * 0.5F;
y = number;
i = * ( long * ) &y;
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
y = y * ( f - ( x * y * y ) ); /* prima iterazione
y = y * ( f - ( x * y * y ) ); /*seconda iterazione necessaria o no a seconda della precisione richiesta
return number * y;
}

il codice di controllo stepper allegato di chris meighan ne fa uso olòtre alla interpolazione di bresenham per le interpolazioni di cui si parla nel documento helix...insomma un concentrato di qualita


p.s. il link... http://www.codemaestro.com/reviews/9
Non hai i permessi necessari per visualizzare i file e le foto allegati in questo messaggio. Per visualizzare tali file devi registrarti ed effettuare il Login

Avatar utente
v.devis
Newbie
Newbie
Messaggi: 32
Iscritto il: sabato 22 agosto 2009, 9:21
Località: Motta di Livenza

Re: interpolazioni nel CAM

Messaggio da v.devis » venerdì 12 marzo 2010, 1:26

... tolto riporto consecutivo ... (Velleca) ...

Ciao, ho proprio trovato ieri altro questo prammento di codice, poi oggi son quì(telepatia????)

l'hotrovato googlando in cerca di un modo di fare il cross product per trovare la normale dei triangoli, devo dire che è impreciso però sia rispetto il cross dell'XNA che a quello che mi sono fatto a mano è circa il triplo più veloce

quì il codice c# del test:

Codice: Seleziona tutto

            Stopwatch sw = new Stopwatch();            
            sw.Start();
            for (int s = 0; s < int.MaxValue / 10; s++)
            {
                Cx = Ay * Bz - Az * By;
                Cy = Az * Bx - Ax * Bz;
                Cz = Ax * By - Ay * Bx;
                //nf = 1 / (float)Math.Sqrt(Cx * Cx + Cy * Cy + Cz * Cz); //leeeeeeenta

                float x = Cx * Cx + Cy * Cy + Cz * Cz;
                unsafe
                {                     
                    float xhalf = 0.5f * x;
                    int i = *(int*)&x;
                    i = 0x5f375a86 - (i >> 1); //trucchetti dei vecchi maghi dei transistor anni 90
                    x = *(float*)&i;
                    x *= 1.5f - xhalf * x * x;
                }

                Cx *= x; //normalizzazione vettore carmack
                Cy *= x;
                Cz *= x;

                //Cx *= nf;
                //Cy *= nf;
                //Cz *= nf;
            }
            sw.Stop();
            textBox3.Text = sw.Elapsed.ToString() + " " + (int.MaxValue / 10).ToString();
            textBox2.Text = Cx.ToString() + " " + Cy.ToString() + " " + Cz.ToString();
            sw.Reset();
devo dire comunque che la maggiore velocità  stà  nel fatto che nel caso del c# le funzioni math le fa in double e poi bisogna castarle in float.

il tempi:
00:00:04.8313335 per 214748364 calcoli vettori normalizzati clockwise -- metodo carmak silicongraphics

00:00:13.9613306 per 214748364 calcoli vettori normalizzati clockwise -- usando nf con sqrt castata in float

l'XNA ci mette lo stesso identico dell' nf, praticamente più preciso di carmak ma 1/3 più lento

ho anche notato che l'XNA non è proprio precisissimo, l'nf è il top di precisione(confrontato con excell e calcolatrice sharp)
Il carisma è la dote di convincersi che ciò che si dirà è il top e insuperabile.

Avatar utente
v.devis
Newbie
Newbie
Messaggi: 32
Iscritto il: sabato 22 agosto 2009, 9:21
Località: Motta di Livenza

Re: interpolazioni nel CAM

Messaggio da v.devis » venerdì 12 marzo 2010, 1:53

Ho notato sul primo post che viene calcolata la pendenza con il trucco dell' y1-y0 / x1-x0

quì bisogna stare attenti di bypassare i casi limite che tendono all'infinito

es di un semicerchio verticale con centro in 0,0:
y1=50
y0=-50

x1=0
x0=0

se faccio 50 - -50 più me lo meno, più vengo meno... mi fa 100

poi sempre tramite l'algoritmo di pierino faccio 0-0 che fa 0

adesso 100 / 0 mi fa + infinito

arcotangente di + infinito mi fa 90° ma i linguaggi c++ e c# standard non sanno risolvere i limiti e sbagliano i conti(boh ci saran le librerie a pagamento o sono ancora acerbo e non le ho viste quelle standard)

quindi in questo caso si dovrebbe o fare tutto senza le pendenze e usare la trigonometria nei 4 quadranti di cerchio, oppure fare 1 if() che controlla la x2-x1 che se uguale a 0 salterà  i calcoli e scriverà  direttamente +90 o -90(dipende dalla y1-y0)

io nell'interpolatore che stò facendo ho usato solo trigonometria per trovarmi il centro dell'arco raggio R, per adesso va poi dovrò fare dei test col cam per vedere il backplot in tutte le condizioni innimaginabili.

che devo dire ottima spegazione ho solo intravisto un possibile inceppo che a mia volta mi ha fatto abbandonare questa ottima tecnica.

pasienza mi son fatto un pieno di trigonometria violenta per non usare la pendenza. Spero di riuscire a finire presto, almeno il backplot, così rilascio i sorgenti, dell'alternativa :-)

un primo stralcio:

Codice: Seleziona tutto


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace interprete
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public Regex re = new Regex("(?<lettera>[A-Z])(?<numero>-?[0-9]*\\.?[0-9]*)", RegexOptions.Compiled);
        int g, f = 1000;
        double x, y, z, r, xp, yp, zp;
        List<double> lx, ly, lz, lf;

        void lineare(int cf)
        {
            lx.Add(x);
            ly.Add(y);
            lz.Add(z);
            lf.Add(cf);
        }

        void orario(int cf)
        {
        }

        void antiorario(int cf)
        {
            double corda;
            if ((corda = Math.Sqrt(Math.Pow(x - xp, 2d) + Math.Pow(y - yp, 2d))) > (r * 2d)) corda = r * 2d;//MessageBox.Show("distanza > di 2 volte raggio");
            double raggiocorda = Math.Sqrt(Math.Pow(r, 2d) - Math.Pow(corda / 2d, 2d));

            double cangolo = 0d;                                                                                //angolo inizio arco antiorario va da 0 a 360
            if (x - xp < 0d && y - yp >= 0d)
                cangolo = 180d / Math.PI * Math.Acos((x - xp) / corda) - 90d;
            else if (x - xp <= 0d && y - yp < 0d)
                cangolo = 270d - 180d / Math.PI * Math.Acos((x - xp) / corda);
            else if (x - xp > 0d && y - yp <= 0d)
                cangolo = 270d - 180d / Math.PI * Math.Acos((x - xp) / corda);
            else if (x - xp >= 0d && y - yp > 0d)
                cangolo = 270d + 180d / Math.PI * Math.Acos((x - xp) / corda);

            double cx = ((x + xp) / 2) - Math.Cos(Math.PI / 180d * cangolo) * raggiocorda;  //centro x
            double cy = ((y + yp) / 2) - Math.Sin(Math.PI / 180d * cangolo) * raggiocorda;  //centro y

            double angolo = 360d / Math.PI * Math.Asin(corda / 2d / r);                            //angolo compreso dell'arco da 0 a 180
            double lunghezza = Math.PI / 180d * angolo * r;                                            //lunghezza arco
            int passi = Convert.ToInt32(lunghezza / 2d / Math.Sqrt(Math.Pow(r, 2d) - Math.Pow(r - 0.1d, 2d))); //passi calcolati con una tolleranza altezza cordale di 0.1mm 
            double angolopassi = angolo / passi;                                                           // angolo di ogni passo

            double xi = 0, yi = 0, angoloi = 0;
            for (int i = 0; i < passi; i++)
            {
                angoloi += angolopassi;
                xi = (xp - cx) * Math.Cos(Math.PI / 180d * angoloi) - (yp - cy) * Math.Sin(Math.PI / 180d * angoloi);  //rototraslazione per ogni passo
                yi = (xp - cx) * Math.Sin(Math.PI / 180d * angoloi) + (yp - cy) * Math.Cos(Math.PI / 180d * angoloi); //manca la traslazione rispetto al centro va beh dettagli
                lx.Add(xi);
                ly.Add(yi);
                lz.Add(z);
                lf.Add(cf);
            }
        }

        private void interpretaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lx = new List<double>();
            ly = new List<double>();
            lz = new List<double>();
            lf = new List<double>();

            foreach (string l in richTextBox1.Lines)
            {
                if (l.Length != 0)
                {
                    foreach (Match m in re.Matches(l))
                    {
                        if (m.Groups["lettera"].Value == "G") int.TryParse(m.Groups["numero"].Value, out g);
                        else if (m.Groups["lettera"].Value == "X") double.TryParse(m.Groups["numero"].Value, out x);
                        else if (m.Groups["lettera"].Value == "Y") double.TryParse(m.Groups["numero"].Value, out y);
                        else if (m.Groups["lettera"].Value == "Z") double.TryParse(m.Groups["numero"].Value, out z);
                        else if (m.Groups["lettera"].Value == "R") double.TryParse(m.Groups["numero"].Value, out r);
                        else if (m.Groups["lettera"].Value == "F") int.TryParse(m.Groups["numero"].Value, out f);
                    }
                    if (g == 0) lineare(60000);
                    else if (g == 1) lineare(f);
                    else if (g == 2) orario(f);
                    else if (g == 3) antiorario(f);
                    xp = x;
                    yp = y;
                    zp = z;
                }
            }
        }
    }
}

Il carisma è la dote di convincersi che ciò che si dirà è il top e insuperabile.

Avatar utente
v.devis
Newbie
Newbie
Messaggi: 32
Iscritto il: sabato 22 agosto 2009, 9:21
Località: Motta di Livenza

Re: interpolazioni nel CAM

Messaggio da v.devis » venerdì 26 marzo 2010, 21:08

Codice: Seleziona tutto

void orario(int cf)
        {
            double corda;
            if ((corda = Math.Sqrt(Math.Pow(x - xp, 2d) + Math.Pow(y - yp, 2d))) > (r * 2d)) corda = r * 2d;
            double cx = (x + xp) / 2d - Math.Sqrt(Math.Pow(r, 2d) - Math.Pow(corda / 2, 2)) * (yp - y) / corda;
            double cy = (y + yp) / 2d - Math.Sqrt(Math.Pow(r, 2d) - Math.Pow(corda / 2, 2)) * (x - xp) / corda;
            double angolo = 360d / Math.PI * Math.Asin(corda / 2d / r);
            double lunghezza = Math.PI / 180d * angolo * r;
            int passi = Convert.ToInt32(lunghezza / (Math.Sqrt(Math.Pow(r, 2d) - Math.Pow(r - 0.1d, 2d)) * 2d));
            double angolopassi = angolo / passi;
            double xi = 0, yi = 0, angoloi = 0;
            for (int i = 0; i < passi; i++)
            {
                angoloi -= angolopassi;
                xi = (xp - cx) * Math.Cos(Math.PI / 180d * angoloi) - (yp - cy) * Math.Sin(Math.PI / 180d * angoloi);
                yi = (xp - cx) * Math.Sin(Math.PI / 180d * angoloi) + (yp - cy) * Math.Cos(Math.PI / 180d * angoloi);
                lx.Add(xi);
                ly.Add(yi);
                lz.Add(z);
                lf.Add(cf);
            }
        }
quì in esempio senza usare la complessa trigonometria e la scelta del quadrante.

basta dare la x,y di destinazione la xp,yp di inizio arco e il raggio, otterremo una lista di punti d'interpolazione, con tolleranza cordale controllata.
Il carisma è la dote di convincersi che ciò che si dirà è il top e insuperabile.

Rispondi

Torna a “Home Made”