Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - creare una bussola
Forum - C# / VB.NET - creare una bussola

Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] Precedente | Prossimo
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 11:11
Venerdì, 01/03/2024
buon giorno a tutti, sto continuando il mio progetto riguardante uno stereo interattivo, dopo aver completato la parte audio, stazione radio e musica, adesso mi è venuto il pallino di avere una bussola in macchina, vedendola nella macchina di mia moglie, ho detto perchè non averla anchio.
tramite arduino e un gps posso inviare al mio progetto la direzione, (nord, sud, est, west), adesso, il problema sta nel disegnare la bussola e cioè nel far girare la bussola di un gradoalla volta in base alla direzione presente nella label. mi spiego meglio,
se nella label1 c'è scritto "nord" la bussola devo girare dal punto dove si trova fino ad arrivare al grado "0" o "360", cosi x il resto delle coordinate, ho visto alcuni esempi, ma fanno girare l immagine con un timer all' infinito. come posso fare? credo che bisogna avere un timer sempre attivo, perchè ogni qualvolta che la label cambia text questo devo far ruotare l immagine, ma di più non so.
grazie mille
questo è l immagine che intendo usare


nightwolf ha allegato un file: bussola.png (118470 bytes)
Clicca qui per guardare l'immagine
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2308
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 16:22
Venerdì, 01/03/2024
Partiamo dal timer.

Il timer è un elemento indispensabile, perché serve ad invalidare o meglio a ridisegnare la scena.
insomma il refresh per ridisegnare tutto.

per l'indicatore si usa da sempre la semplice formula del PI.

rotazioneGradi = 120 Esempio.

Per essere sicuri che i gradi siano da 0 ad un max di 360
rotazioneGradi %= 360;

angoloRadiante = rotazioneGradi * Math.PI / 180;


In questo modo, hai ottenuto l'angolo dei gradi in radianti.

Per il comparto grafico,  dai un occhiata qui.

http://www.pierotofy.it/pages/sorgenti/dettagli/19517-Orol ...

apri il sorgente e cerca di capire come è strutturato il funzionamento dell'orologio.
Applicando la stessa teoria alla tua bussola.

Se ti serve anche una buona libreria grafica e performante, ti consiglio il mio progetto.

http://www.pierotofy.it/pages/projects/project.php?id=683

puoi sfruttare tutta la GDI in seguito direttamente nel void Draw.
La differenza e che non hai bisogno di nessun timer, e tutto già pre-impostato,
ed hai la possibilità di avere un zoom o una telecamera 2d.










https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1351
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 16:48
Venerdì, 01/03/2024
Per il timer sei a posto, Thejuster è stato chiaro.

Ti propongo un codice che al variare del contenuto in gradi di una label ruota l'immagine di conseguenza:

1) ho inserito una scrollbar che simula la variazione del valore in gradi nella label (entrambi creati in runtime).
2) ho ridimensionato l'immagine e ritagliata circolare in modo che possa essere sovrapposta a qualsiasi altro disegno (allegata).
3) codice in C#

Codice sorgente - presumibilmente C#

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5.  
  6. namespace Ruota_Immagine
  7. {
  8.     public partial class Form1 : Form
  9.     {
  10.         Image bussola = new Bitmap("bussola.png"); // bmp in ram dal file originale, deve esistere nella cartella dell'eseguibile
  11.         Label lb = new Label(); // label con il valore di rotazione
  12.         HScrollBar hsb = new HScrollBar(); // simulazione dato di rotazione
  13.         public Form1()
  14.         {
  15.             InitializeComponent();
  16.             this.BackgroundImageLayout = ImageLayout.Zoom; // adatta l'immagine al ridimensionamento
  17.             this.DoubleBuffered = true; // elimina sfarfallio
  18.             hsb.Left = lb.Width; // posizione della scrollbar
  19.             hsb.Width =  this.ClientSize.Width - lb.Width; // larghezza della scrollbar
  20.             hsb.Maximum = 370; // valore massimo scrollbar
  21.             this.Controls.Add(lb); // label nel form
  22.             this.Controls.Add(hsb); // scrollbar nel form
  23.             lb.TextChanged += Lb_TextChanged; // evento cambio testo nella label
  24.             hsb.Scroll += Hsb_Scroll; // evento cambiovalore nella scrollbar
  25.             lb.Text = "000";
  26.             Lb_TextChanged(lb, new EventArgs()); // primo disegno
  27.         }
  28.  
  29.         private void Hsb_Scroll(object sender, EventArgs e)
  30.         {
  31.             lb.Text = hsb.Value.ToString("000"); // cambia il valore nella label (simula il tuo valore)
  32.         }
  33.  
  34.         private void Lb_TextChanged(object sender, EventArgs e) // al cambio del valore
  35.         {
  36.             int valoreGradi = Convert.ToUInt16(lb.Text); // valore in gradi
  37.             Image rot0 = (Image)bussola.Clone(); // partenza sempre dall'originale a zero gradi
  38.             Graphics g = Graphics.FromImage(rot0); // layer grafico di lavoro
  39.             // centro immagine
  40.             int centerX = rot0.Width / 2;
  41.             int centerY = rot0.Height / 2;
  42.             // Crea una matrice di trasformazione per ruotare l'immagine
  43.             Matrix matrix = new Matrix();
  44.             matrix.Translate(centerX, centerY); // coordinate di riferimento al centro
  45.             matrix.Rotate(valoreGradi); // rotazione
  46.             // Applica la trasformazione all'immagine
  47.             g.Transform = matrix;
  48.             // Disegna l'immagine ruotata nella bitmap centrata
  49.             g.DrawImage(rot0, -centerX, -centerY);
  50.             this.BackgroundImage = rot0; // la bitmap nel form
  51.             this.Refresh(); // aggiorna il form
  52.         }
  53.     }
  54. }



Codice commentato ma se vuoi più info chiedi

Invece non ho compreso la richiesta: ...la direzione, (nord, sud, est, west)



Carlo ha allegato un file: Bussola.png (100666 bytes)
Clicca qui per guardare l'immagine

Ultima modifica effettuata da Carlo il 01/03/2024 alle 17:33


in programmazione tutto è permesso
PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 0:30
Sabato, 02/03/2024
la mia richiesta è che se il testo nella label1 è "NORD", la bussola devrebbe indicare in nord, cosi come se il testo della label1 è sud la bussola dovrebbe indicare il sud, ma non semplicemente cambiando imagine, perchè fin li, riesco anchio, ma vedendola muovere o solamente verso destra, o solamente verso sinistra, di grado in grado, come una bussola vera.

PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2308
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 10:09
Sabato, 02/03/2024
Solitamente non regalo sorgenti.
Ma visto il mal tempo, non avevo nulla da fare, ed eccomi qui.

Non lo faccio non per cattiveria, ma perché lo scopo del forum e quello di aiutare, consigliare ed imparare
non di regalare sorgenti pronti.

Non è rivolto semplicemente a te nightwolf ma alla community in generale.

Ho fatto questo piccolo esempio suppongo che sia questo quello che cerchi.
con tanto di animaizone.

Spostando la trackbar ed assegnando un nuovo valore, la lancetta ruoterà un pò alla volta fino a raggiungere il valore.



Edit:
screenshoot

https://i.ibb.co/fSPwn4X/Screenshot-2024-03-02-101024.png

L'angolo parte da 0, ovvero W 270
basta modificare la variabile

angoloattuale = 90.0;  per ottenere come punto di partenza lo 0

quindi ad esempio  se la bussola dovrebbe puntare a Nord 5 gradi


addizione = 90.0;

angoloattuale = 5.0 + addizione;


Thejuster ha allegato un file: Bussola.zip (406022 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Thejuster il 02/03/2024 alle 10:34


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1351
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 12:56
Sabato, 02/03/2024
Mi sembra che oggi ti vada bene, Thejuster ti ha regalato la bussola con l'ago.

Io ti regalo la bussola con il quadrante che ruota (allegato progetto).
L'esempio che ti avevo postato andava integrato con la richiesta nord, est, sud, west
Codice sorgente - presumibilmente C#

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Windows.Forms;
  5.  
  6. namespace Ruota_Immagine
  7. {
  8.     public partial class Form1 : Form
  9.     {
  10.         Image bussola = new Bitmap("bussola.png"); // bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
  11.         int destinazione;
  12.         int avanzamento;
  13.         int direzione;
  14.         public Form1()
  15.         {
  16.             InitializeComponent();
  17.             this.BackgroundImageLayout = ImageLayout.Zoom; // adatta l'immagine al ridimensionamento
  18.             this.DoubleBuffered = true; // elimina sfarfallio
  19.             Lb_TextChanged(lb, new EventArgs()); // primo disegno
  20.         }
  21.  
  22.         private void Lb_TextChanged(object sender, EventArgs e) // al cambio del valore
  23.         {
  24.             int valoreGradi = Convert.ToUInt16(lb.Text); // valore in gradi
  25.             Image rot0 = (Image)bussola.Clone(); // partenza sempre dall'originale a zero gradi
  26.             Graphics g = Graphics.FromImage(rot0); // layer grafico di lavoro
  27.             // centro immagine
  28.             int centerX = rot0.Width / 2;
  29.             int centerY = rot0.Height / 2;
  30.             // Crea una matrice di trasformazione per ruotare l'immagine
  31.             Matrix matrix = new Matrix();
  32.             matrix.Translate(centerX, centerY); // coordinate di riferimento al centro
  33.             matrix.Rotate(valoreGradi); // rotazione
  34.             // Applica la trasformazione all'immagine
  35.             g.Transform = matrix;
  36.             // Disegna l'immagine ruotata nella bitmap centrata
  37.             g.DrawImage(rot0, -centerX, -centerY );
  38.             this.BackgroundImage = rot0; // la bitmap nel form
  39.             this.Refresh(); // aggiorna il form
  40.         }
  41.  
  42.         private void timer1_Tick(object sender, EventArgs e)
  43.         {
  44.             avanzamento += direzione;
  45.             lb.Text = avanzamento.ToString("000");
  46.             if (avanzamento == destinazione) timer1.Enabled = false;
  47.         }
  48.  
  49.         private void butNord_Click(object sender, EventArgs e)
  50.         {
  51.             destinazione = 0;
  52.             // esce se già in posizione
  53.             if (destinazione == avanzamento || avanzamento == 360) return;
  54.             // sceglie la direzione di rotazione
  55.             if (avanzamento > 180)
  56.             {
  57.                 direzione = 2;
  58.                 destinazione = 360;
  59.             }
  60.             else
  61.             {
  62.                 direzione = -2;
  63.                 destinazione = 0;
  64.             }
  65.             timer1.Enabled = true;
  66.         }
  67.  
  68.         private void butEst_Click(object sender, EventArgs e)
  69.         {
  70.             destinazione = 90;
  71.             // esce se già in posizione
  72.             if (destinazione == avanzamento) return;
  73.             // normalizza
  74.             if (avanzamento == 360) avanzamento = 0;
  75.             // sceglie la direzione di rotazione
  76.             if (avanzamento > 90) direzione = -2; else direzione = 2;
  77.             timer1.Enabled = true;
  78.         }
  79.  
  80.         private void butSud_Click(object sender, EventArgs e)
  81.         {
  82.             destinazione = 180;
  83.             // esce se già in posizione
  84.             if (destinazione == avanzamento) return;
  85.             // sceglie la direzione di rotazione
  86.             if (avanzamento > 180) direzione = -2; else direzione = 2;
  87.             timer1.Enabled = true;
  88.         }
  89.  
  90.         private void butWest_Click(object sender, EventArgs e)
  91.         {
  92.             destinazione = 270;
  93.             // esce se già in posizione
  94.             if (destinazione == avanzamento) return;
  95.             // normalizza
  96.             if (avanzamento == 0) avanzamento = 360;
  97.             // sceglie la direzione di rotazione
  98.             if (avanzamento > 180) direzione = -2; else direzione = 2;
  99.             timer1.Enabled = true;
  100.         }
  101.     }
  102. }


Come vedi il codice è lo stesso di prima solo che i valori vengono aggiornati con un timer e vanno nel punto cardinale scelto.

Mi aspetto che tu ci esponga i tuoi dubbi, gli esempi sono per iniziare...


Carlo ha allegato un file: Ruota_immagine2.zip (51601 bytes)
Clicca qui per scaricare il file


in programmazione tutto è permesso
PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 13:16
Sabato, 02/03/2024
grazie mille, questa mattina avevo gia iniziato a scrivere questo codice
Codice sorgente - presumibilmente C++

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10.  
  11. namespace bussola_c
  12. {
  13.     public partial class Form1 : Form
  14.     {
  15.         public Form1()
  16.         {
  17.             InitializeComponent();
  18.         }
  19.         int cx = 280, cy = 280, rx = 400, ry = 400;
  20.  
  21.         private void button1_Click(object sender, EventArgs e)
  22.         {
  23.             timer1.Start();
  24.         }
  25.  
  26.         private void timer1_Tick(object sender, EventArgs e)
  27.         {
  28.             angle += 2;
  29.             Invalidate();
  30.  
  31.         }
  32.  
  33.         float angle;
  34.         Bitmap image = Properties.Resources.bussola;
  35.         private void Form1_Paint(object sender, PaintEventArgs e)
  36.         {
  37.             Graphics g = e.Graphics;
  38.                
  39.             g.RotateTransform(angle, System.Drawing.Drawing2D.MatrixOrder.Append);
  40.             g.TranslateTransform(cx, cy, System.Drawing.Drawing2D.MatrixOrder.Append);
  41.             g.DrawImage(image, -rx / 2, -ry / 2, rx, ry);
  42.         }
  43.     }
  44. }



e premendo il pulsante start, tutto funzionava, era solo da capire come far girare la bussola se si indicava nord, sud, est o west.
ho provato a convertire il codice in vb.net ma mi dava errore in  g.DrawImage(image, -rx / 2, -ry / 2, rx, ry), e non capivo dove era lo sbaglio, stavo cercando in rete, prima di leggere i vostri esempi.

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1351
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 14:39
Sabato, 02/03/2024
Se ti trovi meglio con VB.Net

Ecco il codice (allegato anche progetto):

Codice sorgente - presumibilmente VB.NET

  1. Imports System.Drawing.Drawing2D
  2.  
  3. Public Class Form1
  4.  
  5.     Private bussola As Image = New Bitmap("bussola.png") ' bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
  6.     Private destinazione As Integer
  7.     Private avanzamento As Integer
  8.     Private direzione As Integer
  9.  
  10.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  11.         rotate(0) ' primo disegno
  12.     End Sub
  13.  
  14.     Private Sub rotate(ByVal valoreGradi As Integer) ' aggiorna rotazione
  15.         Dim rot0 As Image = DirectCast(bussola.Clone(), Image) ' partenza sempre dall'originale a zero gradi
  16.         Dim g As Graphics = Graphics.FromImage(rot0) ' layer grafico di lavoro
  17.         ' centro immagine
  18.         Dim centerX As Integer = rot0.Width \ 2
  19.         Dim centerY As Integer = rot0.Height \ 2
  20.         ' Crea una matrice di trasformazione per ruotare l'immagine
  21.         Dim matrix As New Matrix()
  22.         matrix.Translate(centerX, centerY) ' coordinate di riferimento al centro
  23.         matrix.Rotate(avanzamento) ' rotazione
  24.         ' Applica la trasformazione all'immagine
  25.         g.Transform = matrix
  26.         ' Disegna l'immagine ruotata nella bitmap centrata
  27.         g.DrawImage(rot0, -centerX, -centerY)
  28.         Me.BackgroundImage = rot0 ' la bitmap nel form
  29.         Me.Refresh() ' aggiorna il form
  30.     End Sub
  31.  
  32.     Private Sub timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timer1.Tick
  33.         avanzamento += direzione
  34.         avanzamento = avanzamento Mod 360 ' azzera a 360°
  35.         rotate(avanzamento)
  36.         lb1.Text = avanzamento.ToString("000°")
  37.         Dim west As Integer = (avanzamento + 180) Mod 360 ' azzera a 360°
  38.         lb2.Text = west.ToString("000°")
  39.         If avanzamento = destinazione Then
  40.             timer1.Enabled = False
  41.         End If
  42.     End Sub
  43.  
  44.     Private Sub butNord_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butNord.Click
  45.         ' esce se già in posizione
  46.         If avanzamento = 0 Then Exit Sub
  47.         destinazione = 0
  48.         ' sceglie la direzione di rotazione
  49.         If avanzamento < 180 Then direzione = -2 Else direzione = 2
  50.         timer1.Enabled = True
  51.     End Sub
  52.  
  53.     Private Sub butEst_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butEst.Click
  54.         ' esce se già in posizione
  55.         If avanzamento = 90 Then Exit Sub
  56.         destinazione = 90
  57.         ' sceglie la direzione di rotazione
  58.         If avanzamento > 90 Then direzione = -2 Else direzione = 2
  59.         timer1.Enabled = True
  60.     End Sub
  61.  
  62.     Private Sub butSud_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butSud.Click
  63.         ' esce se già in posizione
  64.         If avanzamento = 180 Then Exit Sub
  65.         destinazione = 180
  66.         ' sceglie la direzione di rotazione
  67.         If avanzamento > 180 Then direzione = -2 Else direzione = 2
  68.         timer1.Enabled = True
  69.     End Sub
  70.  
  71.     Private Sub butWest_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butWest.Click
  72.         ' esce se già in posizione
  73.         If avanzamento = 270 Then Exit Sub
  74.         destinazione = 270
  75.         ' normalizza
  76.         If avanzamento = 0 Then avanzamento = 360
  77.         ' sceglie la direzione di rotazione
  78.         If avanzamento > 180 Then direzione = -2 Else direzione = 2
  79.         timer1.Enabled = True
  80.     End Sub
  81.  
  82. End Class



Come prima, questa è la partenza.
Se ti piace programmare non ti accontentare di copiare codice, approfitta di chi ti può spiegare passo passo i perché


Carlo ha allegato un file: Ruota_immagine2.zip (56272 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Carlo il 02/03/2024 alle 14:42


in programmazione tutto è permesso
PM Quote
Avatar
nightwolf (Normal User)
Pro


Messaggi: 149
Iscritto: 14/09/2010

Segnala al moderatore
Postato alle 15:19
Sabato, 02/03/2024
Grazie mille, non so, ma mi viene più semplice capire vb.net.
Infatti vorrei chiederti tantissime cose su quello che hai scritto. Lo faro in questi giorni. Cosi potrai spiegarmi il perché di certe cose anziché altre.

PM Quote
Pagine: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] Precedente | Prossimo