Struttura di dati

Ciao gente,

confesso che non sono un gran esperto ed acquisisco ll mio sapere in modo empirico. Magari dovrei anche prendere un libro e cercare di migliorare. Ma sono inconstante.
Allora il problema:

come fare una struttura che contiene una serie di informazioni da ricavarne un determinato indice.
Sono imbattuto nel caso di una tastiera su touchscreen. Colto dalla curiosità ho pensato di costruire una struttura, ma non so bene come si possa descrivere tale struttura.
Pensando che ci possano essere un certo numero di tasti => NUMKEYS
Per capire quale tasto si è toccato sul touchscreen ci si aspetta che ritornino 2 valori che sarebbero le coordinate cartesiane dello schermo.
Ora è chiaro che ci vuole una certa tolleranza che permette di attribuire un certo tasto in una determinata area. Ho pensato che si possa usare una costante => TOLERANCE

Quindi la struttura, pensavo dovrebbe essere

#define NUMKEYS (3 * 4)
#define TOLERANCE 30
const struct keymap {
   int x_min           NUMKEYS;
   int x_max           NUMKEYS;
   int y_min           NUMKEYS;
   int y_max           NUMKEYS;
};

keymap.xmin[3] = 100 - TOLERANCE;
keymap.xmax[3] = 100 + TOLERANCE;
keymap.ymin[3] = 200 - TOLERANCE;
keymap.ymax[3] = 200  + TOLERANCE;

In ogni modo lo scopo è di percepire la posizione con una certe tolleranza.
Ma il mio scopo è quello di capire come si si potrebbe definire una tabella che con due valori delle coordinate passate se entro la tolleranza si possa risalire all' indice che sarebbe quello che determina quale tasto si è indicato su un touchscreen.

?? Ma nella struct cosa vuol dire

int x_min           NUMKEYS;

visto che NUMKEYS viene sostituito con (3*4) ?

Seguirei un altra strada per determinare la pressione di un tasto.
Rilevi in qualche modo le coordinate X Y, e poi confronti con degli if()

Non parlando di un hardware particolare, e di metodi per ricavare le coordinate, è solo un esempio astratto.

typedef struct {

    int x;
    int y;

}coo;

coo coordinate[5]; //coordinate di 5 pulsanti su schermo

coordinate[0].x=10; //coordinate centro pulsante
coordinate[0].y=20;//coordinate centro pulsante
coordinate[1].x=40; //coordinate centro pulsante
coordinate[1].y=60;//coordinate centro pulsante

// continuare per tutti i pulsanti

int x=0;
int y=0;

void loop(){
        x=leggoCoordinateX();
        y=leggoCoordinataY();
       
        if((x>= coordinate[0].x-larghezza/2)&&(x<=coordinate[0].x+larghezza/2)&&(y>= coordinate[0].y-altezza/2)&&(y<=coordinate[0].y+altezza/2)) {

        Pulsante Premuto = primo pulsante;

}

// tradotto in linguaggio naturale

controllo che il valore x e il valore y, siano tra minimo e massimo  >= minimo o <= massimo
dove minimo è centro pulsante meno larghezza/2 per la x, e altezza/2 per la y, mentre massimo è centro pulsante + larghezza/2 per la x, e altezza/2 per la y

in pratica confronto le coordinate lette, con posizione massima e minima in x y, di ciascun pulsante, sapendo la posizione centro del pulsante, per ricavare la posizione massima e minima in x e y, sommo e sottraggo meta della larghezza per la x, e meta dell'altezza per la y.

}

nid69ita:
?? Ma nella struct cosa vuol dire

int x_min           NUMKEYS;

visto che NUMKEYS viene sostituito con (3*4) ?

Ah, allora è già una cosa che ho capito poco.
Io intendevo il risultato del prodotto. Nel modo che se uno meno esperto potrebbe intervenire cambiando solo un paio di #define. Questo nell' intento di intervenire sul programma per impostare valori più appropriati, oppure per sperimentare nuovi parametri.
Per avere il prodotto, devo togliere le parentesi, vero ?

torn24:
Seguirei un altra strada per determinare la pressione di un tasto.

Avevo pensato anche questo metodo, il mio ragionamento si orientava a ridurre i cicli di calcolo per ricavare la posizione valida. Forse nella misura di 5 tasti non è pesante il ciclo di risposta. Volendo andare a mettere una simil-tastiera forse è alquanto rallentato.
Comunque, mi intendevo che la struttura dovesse contenere/avere lo spazio per tutte le posizioni.
Che poi siano le posizioni centrali o estreme, sarebbe un passo successivo.
Infatti la struttura si presentava con

keymap.xmin[3] = 100 - TOLERANCE;
keymap.xmax[3] = 100 + TOLERANCE;
keymap.ymin[3] = 200 - TOLERANCE;
keymap.ymax[3] = 200  + TOLERANCE;

// oppure con una struct di punti centrali
#define TOLERANCE 160;

keymap.x[3] = 100 
keymap.y[3] = 200

Comunque vorrei tenerli dentro la struct

avere 20 pulsanti e altrettante strutture di controllo if(), non genera un ritardo considerevole, un processore esegue un elevato numero di operazioni al secondo, pur modesto che sia.

Il tuo ragionamento non può funzionare, non puoi stabilire la pressione di un tasto avendo solo valori massimo e minimo, ti servono delle condizioni per verificare il range. SE maggiore di minino E minore di
massimo, if(x>= minino && x<=massimo).

Non porta da nessuna parte il tuo ragionamento. :slight_smile: non riuscirai ad ottenere niente senza istruzioni condizionali…

ExperimentUno:
Ah, allora è già una cosa che ho capito poco.
Io intendevo il risultato del prodotto. Nel modo che se uno meno esperto potrebbe intervenire cambiando solo un paio di #define. Questo nell' intento di intervenire sul programma per impostare valori più appropriati, oppure per sperimentare nuovi parametri.
Per avere il prodotto, devo togliere le parentesi, vero ?

No, scusa, ma comunque che senso ha ? con la sostituzione della define ottieni
int x_min (3*4); ??
o ci metti le quadre per avere una array (le tonde sono in basic) oppure un = per il risultato.

Posso dire la mia ?

  1. si divide lo schermo in una serie di quadrati/rettangoli e si calcola il centro di ciascuno di essi identificandolo come Xn, Yn.

  2. si mettono tutti gli Xn in un array e gli Yn in un altro array

  3. si rivela il punto in cui tocco X,Y e si fa con X una veloce ricerca nell'array per trovare l'Xn più vicino (abs(Xn - X) minore) e si ricava la colonna, stessa cosa con Y e si ricava la riga. Data riga e colonna si sa il quadratoi/rettangolo che si è toccato.

Guglielmo

gpb01:
si divide lo schermo in una serie di quadrati/rettangoli

Se l'uso di una griglia di celle perfettamente adiacenti è possibile, e bisogna vedere se nel caso specifico lo è, allora c'è una soluzione ancora più semplice: basta dividere (divisione intera) la lettura (immagino le coordinate "ad alta risoluzione" del pixel centrale toccato) per le dimensioni delle celle della griglia, e si ottengono automaticamente le coordinate "a bassa risoluzione" della cella.

Da queste ottenere un key code da 0 a (numeroColonne*numeroRighe - 1) è semplicissimo:

yCella = letturaY / altezzaCella;
xCella = letturaX / larghezzaCella;
keyCode = yCella*numeroColonne + xCella;

gpb01:
Posso dire la mia ?

Benvenuto, certamente :slight_smile:

gpb01:

  1. si divide lo schermo in una serie di quadrati/rettangoli e si calcola il centro di ciascuno di essi identificandolo come Xn, Yn.

  2. si mettono tutti gli Xn in un array e gli Yn in un altro array

Ci potrebbe anche essere che le aree, non siano (o non necessitano) adiacenti.
Ecco qui, mi incuriosisce. Come faresti il calcolo ?
Se il programma dovrebbe essere alquanto flessibile, non credi si debba passare dal preprocessore e fargli fare i calcoli a modino.
Oppure è un mero uso del calcolatore e mettere i parametri negli array ?

Scusate. Piuttosto che quello che si vuole ottenere con un touchscreen, buone anche le soluzioni, mi ero orientato a capire come usufruire di una struct. Che non ha molto di particolare, per sé. Permette solo di avere dei nomi alle variabili con maggiore intelligibilità. Almeno questo è la mia idea

nid69ita:
o ci metti le quadre per avere una array (le tonde sono in basic) oppure un = per il risultato

Io mi aspetterei che il preprocessore mi metta il risultato della moltiplicazione.

#define NUMKEYS NUMCOLS * NUMROWS

struct {
    int x_min  NUMKEYS;
} keytable;

Io intenderei che la struct dovrebbe contenere un sequenza di int in una quantità stabilita dal preprocessore che farebbe il calcolo di NUMKEYS.
Dov'è l' errore ?
Facile che non ci vuole le parentesi tonde.

Scusa, ma una volta che il preprocessore fa le sostituzioni ed esce:

int x 10;

Questo cosa dovrebbe fare? Quel che nid sta cercando di dirti è che in C questo non vuol dire niente! Quel che vuoi è un array, quindi tipo:

int x[10];

E dunque:

int x[NUMKEYS];

Quanto alla struct, è ben più di quel che dici! Non si tratta solo di leggibilità, ma soprattutto del fatto che i dati sono raggruppati insieme. Puoi quindi farne array, passarli tutti ad una funzione in un colpo solo, e quant’altro. La massima comodità ed espressività la raggiungi quando dentro alla struct ci metti anche le funzioni che lavorano sui suoi dati, creando quelle che si chiamano classi e passando alla programmazione ad oggetti.