01/03 10:11
nightwolf
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
aaa
01/03 15:48
Carlo
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#
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Ruota_Immagine
{
public partial class Form1 : Form
{
Image bussola = new Bitmap("bussola.png"); // bmp in ram dal file originale, deve esistere nella cartella dell'eseguibile
Label lb = new Label(); // label con il valore di rotazione
HScrollBar hsb = new HScrollBar(); // simulazione dato di rotazione
public Form1()
{
InitializeComponent();
this.BackgroundImageLayout = ImageLayout.Zoom; // adatta l'immagine al ridimensionamento
this.DoubleBuffered = true; // elimina sfarfallio
hsb.Left = lb.Width; // posizione della scrollbar
hsb.Width = this.ClientSize.Width - lb.Width; // larghezza della scrollbar
hsb.Maximum = 370; // valore massimo scrollbar
this.Controls.Add(lb); // label nel form
this.Controls.Add(hsb); // scrollbar nel form
lb.TextChanged += Lb_TextChanged; // evento cambio testo nella label
hsb.Scroll += Hsb_Scroll; // evento cambiovalore nella scrollbar
lb.Text = "000";
Lb_TextChanged(lb, new EventArgs()); // primo disegno
}
private void Hsb_Scroll(object sender, EventArgs e)
{
lb.Text = hsb.Value.ToString("000"); // cambia il valore nella label (simula il tuo valore)
}
private void Lb_TextChanged(object sender, EventArgs e) // al cambio del valore
{
int valoreGradi = Convert.ToUInt16(lb.Text); // valore in gradi
Image rot0 = (Image)bussola.Clone(); // partenza sempre dall'originale a zero gradi
Graphics g = Graphics.FromImage(rot0); // layer grafico di lavoro
// centro immagine
int centerX = rot0.Width / 2;
int centerY = rot0.Height / 2;
// Crea una matrice di trasformazione per ruotare l'immagine
Matrix matrix = new Matrix();
matrix.Translate(centerX, centerY); // coordinate di riferimento al centro
matrix.Rotate(valoreGradi); // rotazione
// Applica la trasformazione all'immagine
g.Transform = matrix;
// Disegna l'immagine ruotata nella bitmap centrata
g.DrawImage(rot0, -centerX, -centerY);
this.BackgroundImage = rot0; // la bitmap nel form
this.Refresh(); // aggiorna il form
}
}
}
Codice commentato ma se vuoi più info chiedi
Invece non ho compreso la richiesta: ...la direzione, (nord, sud, est, west)
Ultima modifica effettuata da Carlo 01/03 16:33
in programmazione tutto è permesso
01/03 23:30
nightwolf
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.
aaa
02/03 9:09
Thejuster
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
i.ibb.co/fSPwn4X/…
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;
Ultima modifica effettuata da Thejuster 02/03 9:34
02/03 11:56
Carlo
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
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Ruota_Immagine
{
public partial class Form1 : Form
{
Image bussola = new Bitmap("bussola.png"); // bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
int destinazione;
int avanzamento;
int direzione;
public Form1()
{
InitializeComponent();
this.BackgroundImageLayout = ImageLayout.Zoom; // adatta l'immagine al ridimensionamento
this.DoubleBuffered = true; // elimina sfarfallio
Lb_TextChanged(lb, new EventArgs()); // primo disegno
}
private void Lb_TextChanged(object sender, EventArgs e) // al cambio del valore
{
int valoreGradi = Convert.ToUInt16(lb.Text); // valore in gradi
Image rot0 = (Image)bussola.Clone(); // partenza sempre dall'originale a zero gradi
Graphics g = Graphics.FromImage(rot0); // layer grafico di lavoro
// centro immagine
int centerX = rot0.Width / 2;
int centerY = rot0.Height / 2;
// Crea una matrice di trasformazione per ruotare l'immagine
Matrix matrix = new Matrix();
matrix.Translate(centerX, centerY); // coordinate di riferimento al centro
matrix.Rotate(valoreGradi); // rotazione
// Applica la trasformazione all'immagine
g.Transform = matrix;
// Disegna l'immagine ruotata nella bitmap centrata
g.DrawImage(rot0, -centerX, -centerY );
this.BackgroundImage = rot0; // la bitmap nel form
this.Refresh(); // aggiorna il form
}
private void timer1_Tick(object sender, EventArgs e)
{
avanzamento += direzione;
lb.Text = avanzamento.ToString("000");
if (avanzamento == destinazione) timer1.Enabled = false;
}
private void butNord_Click(object sender, EventArgs e)
{
destinazione = 0;
// esce se già in posizione
if (destinazione == avanzamento || avanzamento == 360) return;
// sceglie la direzione di rotazione
if (avanzamento > 180)
{
direzione = 2;
destinazione = 360;
}
else
{
direzione = -2;
destinazione = 0;
}
timer1.Enabled = true;
}
private void butEst_Click(object sender, EventArgs e)
{
destinazione = 90;
// esce se già in posizione
if (destinazione == avanzamento) return;
// normalizza
if (avanzamento == 360) avanzamento = 0;
// sceglie la direzione di rotazione
if (avanzamento > 90) direzione = -2; else direzione = 2;
timer1.Enabled = true;
}
private void butSud_Click(object sender, EventArgs e)
{
destinazione = 180;
// esce se già in posizione
if (destinazione == avanzamento) return;
// sceglie la direzione di rotazione
if (avanzamento > 180) direzione = -2; else direzione = 2;
timer1.Enabled = true;
}
private void butWest_Click(object sender, EventArgs e)
{
destinazione = 270;
// esce se già in posizione
if (destinazione == avanzamento) return;
// normalizza
if (avanzamento == 0) avanzamento = 360;
// sceglie la direzione di rotazione
if (avanzamento > 180) direzione = -2; else direzione = 2;
timer1.Enabled = true;
}
}
}
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...
in programmazione tutto è permesso
02/03 13:39
Carlo
Se ti trovi meglio con VB.Net
Ecco il codice (allegato anche progetto):
Imports System.Drawing.Drawing2D
Public Class Form1
Private bussola As Image = New Bitmap("bussola.png") ' bmp in ram dal file originale, deve esistere nella cartelle dell'eseguibile
Private destinazione As Integer
Private avanzamento As Integer
Private direzione As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
rotate(0) ' primo disegno
End Sub
Private Sub rotate(ByVal valoreGradi As Integer) ' aggiorna rotazione
Dim rot0 As Image = DirectCast(bussola.Clone(), Image) ' partenza sempre dall'originale a zero gradi
Dim g As Graphics = Graphics.FromImage(rot0) ' layer grafico di lavoro
' centro immagine
Dim centerX As Integer = rot0.Width \ 2
Dim centerY As Integer = rot0.Height \ 2
' Crea una matrice di trasformazione per ruotare l'immagine
Dim matrix As New Matrix()
matrix.Translate(centerX, centerY) ' coordinate di riferimento al centro
matrix.Rotate(avanzamento) ' rotazione
' Applica la trasformazione all'immagine
g.Transform = matrix
' Disegna l'immagine ruotata nella bitmap centrata
g.DrawImage(rot0, -centerX, -centerY)
Me.BackgroundImage = rot0 ' la bitmap nel form
Me.Refresh() ' aggiorna il form
End Sub
Private Sub timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timer1.Tick
avanzamento += direzione
avanzamento = avanzamento Mod 360 ' azzera a 360°
rotate(avanzamento)
lb1.Text = avanzamento.ToString("000°")
Dim west As Integer = (avanzamento + 180) Mod 360 ' azzera a 360°
lb2.Text = west.ToString("000°")
If avanzamento = destinazione Then
timer1.Enabled = False
End If
End Sub
Private Sub butNord_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butNord.Click
' esce se già in posizione
If avanzamento = 0 Then Exit Sub
destinazione = 0
' sceglie la direzione di rotazione
If avanzamento < 180 Then direzione = -2 Else direzione = 2
timer1.Enabled = True
End Sub
Private Sub butEst_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butEst.Click
' esce se già in posizione
If avanzamento = 90 Then Exit Sub
destinazione = 90
' sceglie la direzione di rotazione
If avanzamento > 90 Then direzione = -2 Else direzione = 2
timer1.Enabled = True
End Sub
Private Sub butSud_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butSud.Click
' esce se già in posizione
If avanzamento = 180 Then Exit Sub
destinazione = 180
' sceglie la direzione di rotazione
If avanzamento > 180 Then direzione = -2 Else direzione = 2
timer1.Enabled = True
End Sub
Private Sub butWest_Click(ByVal sender As Object, ByVal e As EventArgs) Handles butWest.Click
' esce se già in posizione
If avanzamento = 270 Then Exit Sub
destinazione = 270
' normalizza
If avanzamento = 0 Then avanzamento = 360
' sceglie la direzione di rotazione
If avanzamento > 180 Then direzione = -2 Else direzione = 2
timer1.Enabled = True
End Sub
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é
Ultima modifica effettuata da Carlo 02/03 13:42
in programmazione tutto è permesso