Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it L'avatar di escocat
    Registrato dal
    Feb 2012
    Messaggi
    308

    [C#] re-draw continuo di pictureBox

    Sono di nuovo qui con un problema "babbo" ma la cosa strana è che faccio cose incredibili in Xna e mi perdo per babbarie in C#. Ma come è possibile? No non è questa la domanda...

    Ero abituato in VB5 a tracciare pixel su una picturebox e vederli tracciare uno per uno, oppure - sempre se volevo - potevo far apparire la picturebox solo alla fine del tracciato e vederlo completo, applicando il famoso "AutoRedraw" a picturebox.

    Col C.... C# riesco a far questo solo nel passaggio dalla grafica vettoriale alla grafica raster, mentre all'interno del ciclo della grafica raster non funziona. Ecco il codice:

    codice:
    //creo una bitmap "vuota" che ha solo delle misure
    
    bit = new Bitmap(pictureBox1.Width, pictureBox1.Height);
    
    //associo una grafica alla bitmap appena creata
    
    Graphics gra = Graphics.FromImage(bit);
    
    //per riempire le forme
    
    SolidBrush bru = new SolidBrush(Color.Blue);
    
    //disegno un cerchio pieno di centro P0,Q0 e raggio ra con il brush e l'unità U
    
    FillCircle(gra, P0, Q0, R, bru, U);
    
    //aggiorno la pictureBox con la nuova bitmap
    
    pictureBox1.Image = bit;
    
    //ora traccio i pixel
    
    for (int i = 0; i < t; i++)
    {
       //...
       //(calcolo le coordinate del pixel P e Q)
                   
       if (P > 0 & P < pictureBox1.Width & Q > 0 & Q < pictureBox1.Height)
          bit.SetPixel(P, Q, Color.DarkRed);
       //aggiorno di nuovo la pictureBox ad ogni pixel tracciato
       pictureBox1.Image = bit;
    }
    Io vorrei vedere il cerchio e dopo - uno ad uno - vorrei vedere ogni pixel che si aggiunge nel tracciato, infatti faccio aggiornare la picturebox all'interno del ciclo. E invece vedo il cerchio e tutto il tracciato completo "di botto". M-ma p-perc-chè? Comincio a balbettare.
    Ultima modifica di escocat; 19-11-2013 a 00:09

  2. #2
    Utente di HTML.it L'avatar di escocat
    Registrato dal
    Feb 2012
    Messaggi
    308
    AH scusate FillCircle è una procedura statica che ho fatto io per "comodità" di espressione:

    codice:
     //Disegna un cerchio (riempito)
    publicstaticvoid FillCircle(Graphics graphics, int Cx, int Cy, float r, SolidBrush bru, int u)
    {
    graphics.FillEllipse(bru, Cx - r / u, Cy - r / u, 2 * r / u, 2 * r / u);
    }
    
    U è una unità grafica (una sorta di "scala").

  3. #3
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,537
    Ciao,
    dove lo hai collocato quel codice? a cosa si riferisce t? ad occhio, in base al fatto che fai un ciclo, direi che nel momento del ciclo hai già tutti i pixel da "oscurare", di conseguenza deduco che tu non imposti un solo pixel per chiamata, ma tutti insieme, ergo vengono disegnati tutti insieme...

  4. #4
    Utente di HTML.it L'avatar di escocat
    Registrato dal
    Feb 2012
    Messaggi
    308
    Ciao.
    "t" è il numero di tracce (pixel) che voglio disegnare. Ogni traccia viene calcolata dentro il ciclo. E la pictureBox si "aggiorna" dopo ogni tracca aggiunta, sempre dentro il ciclo. Però io vedo solo "l'ultima videata", quella con tutte le tracce. Ti posto ilo codice completo all'interno di un button_click:

    codice:
           private void button3_Click(object sender, EventArgs e)
            {
                button3.Enabled = false;
                string a;
                int n1, t = int.Parse(textBox16.Text), P, Q, P0 = 600, Q0 = 200,U = int.Parse(label6.Text);
                float R1, D1, F1, V1, K = float.Parse(textBox17.Text);
                bit = new Bitmap(pictureBox1.Width, pictureBox1.Height);//creiamo una bitmap "vuota" che ha solo delle misure
                Graphics gra = Graphics.FromImage(bit);//associamo una grafica alla bitmap appena creata
                SolidBrush bru = new SolidBrush(Color.LightYellow);//per riempire le forme
                Pen pen = new Pen(bru);//strumento di disegno
                //DrawCircle(gra, P0, Q0, R, pen, U);//disegna una circonferenza di centro P0,Q0 e raggio ra con la pen e l'unità U
                FillCircle(gra, P0, Q0, R, bru, U);//disegna un cerchio di centro P0,Q0 e raggio ra con la pen e l'unità U
                pictureBox1.Image = bit;//aggiorna la pictureBox con la nuova bitmap
                if (listBox1.Items.Count == 0)
                    return;
                //            1         2         3         4     
                //   1234567890123456789012345678901234567890123456
                //   nnnnnn RRRRRRR DDDDDDD FFFFFFF VVVV.VVVVV PPPs 
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    a = listBox1.Items[i].ToString();
                    if (int.Parse(Mid(a, 8, 7)) > 0)
                    {
                        n1 = int.Parse(Left(a, 6));//6-8-8-10
                        R1 = float.Parse(Mid(a, 7, 8));
                        D1 = float.Parse(Mid(a, 15, 8));
                        F1 = float.Parse(Mid(a, 23, 8));
                        V1 = float.Parse(Mid(a, 31, 10));
                        float Ax = 0f, Ay = 0f, Vx = 0f, Vy = -V1, X = n1 * R, Y = 0f, d3;
                        //ora tracciamo i pixel
                        for (int j = 0; j < t; j++)
                        {
                            //bit.SetPixel(oldp, oldq, Color.Black);
                            d3 = (float)Math.Pow(X * X + Y * Y, 3f / 2f);
                            Ax = -G * M * X / d3;
                            Ay = -G * M * Y / d3;
                            Vx += Ax;
                            Vy += Ay;
                            X += Vx;
                            Y += Vy;
                            P = P0 + (int)(X / U);
                            Q = Q0 + (int)(Y / U / K);
                            if (P > 0 & P < pictureBox1.Width & Q > 0 & Q < pictureBox1.Height)
                                bit.SetPixel(P, Q, Color.DarkRed);
    
                           pictureBox1.Image = bit;//aggiorniamo di nuovo la pictureBox   
    
                        }
                    }
                    
                }
                            
                button3.Enabled = true;
            }
    All'interno di un Timer la cosa mi riesce, ma vorrei capire perchè non riesce senza usare il timer_Tick....
    Ultima modifica di escocat; 19-11-2013 a 19:26

  5. #5
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,537
    la PictureBox si aggiorna solo all'uscita del metodo, non ad ogni iterazione del ciclo... diversamente devi impostare i pixel chiamando un thread diverso (new Thread(()=>{//tuo codice setPixel//this.pictureBox1.Image = bit;}).Start(); ) per ogni modifica che vuoi appaia in una volta (ad esempio per ogni pixel o per ogni gruppo di pixel), in quel caso riesci a vedere il cambio 1 per volta, pur sempre considerando la velocità in cui questo può accadere... infatti considera che potrebbe essere abbastanza veloce da vederli quasi come se fossero un unico disegno
    Ultima modifica di U235; 19-11-2013 a 19:49

  6. #6
    Utente di HTML.it L'avatar di escocat
    Registrato dal
    Feb 2012
    Messaggi
    308
    OK U235 grazie per essere intervenuto. Forse io sono ancora fermo a certi aspetti romantici del VB5 ... ho risolto tutto con un controllo Timer e gira come voglio io che è una bellezza. Questo C# è favoloso .... Ciao grazie.

    Posto il codice caso mai interessa a qualcuno.....

    codice:
    
     
          private void button8_Click(object sender, EventArgs e)
            {
                //            1         2         3         4     
                //   1234567890123456789012345678901234567890123456
                //   nnnnnn RRRRRRR DDDDDDD FFFFFFF VVVV.VVVVV PPPs 
                int n1;
                float V1;
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    string a = listBox1.Items[i].ToString();
                    if (int.Parse(Mid(a, 8, 7)) > 0)
                    {
                        n1 = int.Parse(Left(a, 6)); 
                        V1 = float.Parse(Mid(a, 31, 10));
                        Vx[i] = 0f;
                        Vy[i] = -V1;
                        X[i] = n1 * R;
                        Y[i] = 0f;
                    }
                }
                if (button8.Text == "GO !")
                {
                    timer1.Enabled = true;
                    button8.Text = "Stop";
                }
                else 
                {
                    timer1.Enabled = false;
                    button8.Text = "GO !";      
                }
            }
            private void timer1_Tick_1(object sender, EventArgs e)
            {
                if (listBox1.Items.Count == 0)
                    return;
                FillCircle(gra, P0, Q0, R, bru, U);//disegna un cerchio di centro P0,Q0 e raggio ra con la pen e l'unità U
                pictureBox1.Image = bit;//aggiorna la pictureBox con la nuova bitmap
                //            1         2         3         4     
                //   1234567890123456789012345678901234567890123456
                //   nnnnnn RRRRRRR DDDDDDD FFFFFFF VVVV.VVVVV PPPs 
                int P, Q;
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    //Cancella i pixel precedenti
                    P = P0 + (int)(oldx[i] / U);
                    Q = Q0 + (int)(oldy[i] / U / K);
                    if (P > 0 & P < pictureBox1.Width & Q > 0 & Q < pictureBox1.Height)
                    {
                        bit.SetPixel(P, Q, Color.Black);
                        bit.SetPixel(P+1, Q, Color.Black);
                        bit.SetPixel(P, Q+1, Color.Black);
                        bit.SetPixel(P+1, Q+1, Color.Black);
                    }
                    //ora tracciamo i nuovi pixel
                        
                    //bit.SetPixel(oldp, oldq, Color.Black);
                    float d3 = (float)Math.Pow(X[i] * X[i] + Y[i] * Y[i], 3f / 2f);
                    float Ax = -G * M * X[i] / d3;
                    float Ay = -G * M * Y[i] / d3;
                    Vx[i] += Ax;
                    Vy[i] += Ay;
                    X[i] += Vx[i];
                    Y[i] += Vy[i];
                    P = P0 + (int)(X[i] / U);
                    Q = Q0 + (int)(Y[i] / U / K);
                    if (P > 0 & P < pictureBox1.Width & Q > 0 & Q < pictureBox1.Height)
                    {
                        bit.SetPixel(P, Q, Color.DarkRed);
                        bit.SetPixel(P+1, Q, Color.DarkRed);
                        bit.SetPixel(P, Q+1, Color.DarkRed);
                        bit.SetPixel(P+1, Q+1, Color.DarkRed);
                    }
                    pictureBox1.Image = bit;//aggiorniamo di nuovo la pictureBox   
                    oldx[i] = X[i];
                    oldy[i] = Y[i];
                                                                                                                              
                    gra.DrawString("CIAO", stringFont, Brushes.White, new PointF(0, 0));                                                                                                                   
                                                                         
                }
            }
    Ultima modifica di escocat; 19-11-2013 a 20:41

  7. #7
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,537
    Figurati
    comunque come preferisci però sarebbe stato sufficiente fare una cosa del genere:

    codice:
    new Thread(()=>{
       for (int i = 0; i < t; i++)
       {
          //...
          //(calcolo le coordinate del pixel P e Q)
                   
          if (P > 0 & P < pictureBox1.Width & Q > 0 & Q < pictureBox1.Height)
             bit.SetPixel(P, Q, Color.DarkRed);
          //aggiorno di nuovo la pictureBox ad ogni pixel tracciato
          pictureBox1.Image = bit;
       }
    }).Start();
    ma come si dice : gusti e colori non si discutono!

  8. #8
    Utente di HTML.it L'avatar di escocat
    Registrato dal
    Feb 2012
    Messaggi
    308
    Dunque vediamo... ho scritto questo piccolo codice per capire e provare il tuo suggerimento:


    codice:
    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.Threading;
    namespace newThread
    {
        public partial class Form1 : Form
        {
            public static Bitmap bit;
            public static Graphics gra;
            public static SolidBrush bru;
            //Disegna un cerchio (riempito)
            public static void FillCircle(Graphics graphics, int Cx, int Cy, float ra, SolidBrush bru, int u)
            {
                graphics.FillEllipse(bru, Cx - ra / u, Cy - ra / u, 2 * ra / u, 2 * ra / u);
            }
            public Form1()
            {
                InitializeComponent();
            }
     
            private void button2_Click(object sender, EventArgs e)
            {
                //creo una bitmap "vuota" che ha solo delle misure 
                bit = new Bitmap(pictureBox1.Width, pictureBox1.Height);
                //associo una grafica alla bitmap appena creata 
                Graphics gra = Graphics.FromImage(bit);
                //per riempire le forme 
                SolidBrush bru = new SolidBrush(Color.Blue);
                //disegno un cerchio pieno di centro P0,Q0 e raggio ra con il brush e l'unità U 
                FillCircle(gra, 300, 100, 100, bru, 128);
                //aggiorno la pictureBox con la nuova bitmap 
                pictureBox1.Image = bit;
                //ora traccio i pixel 
                float x=0,y=200;
                int t = 100000, P, Q = (int)y;  
                
                new Thread(()=> { 
                    for (int i = 0; i < t; i++)
                    {
                        x += 0.007f;
                        P = (int)x;
                        if (P > 0 & P < pictureBox1.Width & Q > 0 & Q < pictureBox1.Height)
                            bit.SetPixel(P, Q, Color.DarkRed);
                        //aggiorno di nuovo la pictureBox ad ogni pixel tracciato 
    
                        pictureBox1.Image = bit; <<<=================
                   }
                } ).Start();
            }
             
        }
    }
    .... ma si blocca in quella riga dicendomi che "L'oggetto è correntemente utilizzato altrove."


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.