How do I clear a FillEllipse without clearin the graphics of my image

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kspiros
    New Member
    • Oct 2008
    • 16

    #1

    How do I clear a FillEllipse without clearin the graphics of my image

    I have a picture box which contains an image and some drawn ellipses. while a thread pass by the ellipses increase the alpha of the ellipse but when the tread leaves the ellipse range i can't change the alpha value because it paints it over. how can I erase only the ellipse without touching anything else in the image.
    image linksimage1 image2

    my code

    Code:
    public void work()
            {
    
                Graphics xGraph;
                
                xGraph = Graphics.FromImage(pictureBox_Map.Image);
    
                    for (int i = 0; i < 5; i++)
                    {
                        
                        Thread.Sleep(draw_delay);
                   
                        double a;
                        a = Math.Sqrt(Math.Pow(pointcheck[0] - X[i], 2) + Math.Pow(pointcheck[1] - Y[i], 2));
                        int d = Convert.ToInt32(a);
    
                        if (Math.Abs(d) < R[i])
                        {
                            if ((elegxos[i] == 0) && (change[i] == false))
                            {
    
                                SolidBrush Brush = new SolidBrush(Color.FromArgb(255, Red[i], Green[i], Blue[i]));
                            
                                pictureBox_Map.CreateGraphics().FillEllipse(Brush, X[i] - R[i], Y[i] - R[i], R[i], R[i]);
                                elegxos[i] = 1;
                                this.Invalidate();
                                change[i] = true;
                            }
                        }
                        else
                        {
                            SolidBrush Brush = new SolidBrush(Color.FromArgb(50, Red[i], Green[i], Blue[i]));
    
                            pictureBox_Map.CreateGraphics().FillEllipse(Brush, X[i] - R[i], Y[i] - R[i], R[i], R[i]);
                            this.Invalidate();
                            change[i] = false;
                        }    
                       
                    }
                    xGraph.Dispose();
    
                    this.Invalidate();
            }
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    Don't keep drawing the elipse?

    Comment

    • tlhintoq
      Recognized Expert Specialist
      • Mar 2008
      • 3532

      #3
      Originally posted by kspiros
      I have a picture box which contains an image and some drawn ellipses. while a thread pass by the ellipses increase the alpha of the ellipse but when the tread leaves the ellipse range i can't change the alpha value because it paints it over. how can I erase only the ellipse without touching anything else in the image.
      image linksimage1 image2

      my code

      Code:
      public void work()
              {
      
                  Graphics xGraph;
                  
                  xGraph = Graphics.FromImage(pictureBox_Map.Image);
      
                      for (int i = 0; i < 5; i++)
                      {
                          
                          Thread.Sleep(draw_delay);
                     
                          double a;
                          a = Math.Sqrt(Math.Pow(pointcheck[0] - X[i], 2) + Math.Pow(pointcheck[1] - Y[i], 2));
                          int d = Convert.ToInt32(a);
      
                          if (Math.Abs(d) < R[i])
                          {
                              if ((elegxos[i] == 0) && (change[i] == false))
                              {
      
                                  SolidBrush Brush = new SolidBrush(Color.FromArgb(255, Red[i], Green[i], Blue[i]));
                              
                                  pictureBox_Map.CreateGraphics().FillEllipse(Brush, X[i] - R[i], Y[i] - R[i], R[i], R[i]);
                                  elegxos[i] = 1;
                                  this.Invalidate();
                                  change[i] = true;
                              }
                          }
                          else
                          {
                              SolidBrush Brush = new SolidBrush(Color.FromArgb(50, Red[i], Green[i], Blue[i]));
      
                              pictureBox_Map.CreateGraphics().FillEllipse(Brush, X[i] - R[i], Y[i] - R[i], R[i], R[i]);
                              this.Invalidate();
                              change[i] = false;
                          }    
                         
                      }
                      xGraph.Dispose();
      
                      this.Invalidate();
              }
      I need to make sure I understand what it is you're trying to do.

      You have a graphic. The streetmap background for example.
      Then you are painting onto it the various ellipses that represent different signals, such as WiFi.
      Later, you want to take away the ellipses you painted and have your background street map still intact, and not have big holes in from your ellipses.
      Does that sound right?

      You can't really. If you only have one graphic in memory, and you change it, then you've changed it. There is nothing holding the data that used to be there before you changed it.

      I think you will have to make a more significant change to your program in order to restore the underlying graphic. You can't just draw on your base and forget where/what was done and try to figure it out in a later method.

      I think you will have better luck if you actually keep track of the drawn ellipses as objects. Create a "Signal" Class with properties like SignalType, SignalCenter, SignalRange etc. Give the class methods for drawing itself, and other basic functionality. Then for each signal create an instance of the class and stick them in an array. A SignalClass[ ].

      Now you can call
      Code:
      mySignalClassArray[3].SetSignalAs(ENUMERATEDSIGNAL_WIFI);
      mySignalClassArray[3].SetCenter(50,200);// Point x, Point y
      mySignalClassArray[3].SetRange(45);// 1 pixel = 1 map scale foot
      mySignalClassArray[3].DrawEllipse(nSignalStregth);//Weak signal becomes more transparant

      If you keep one copy of the base street map in memory you can use it as a source to copy from.

      So you make a new copy of the map to a graphic in memory,
      Loop through all your SignalArray iterations painting ellipses,
      Replace the displayed graphic with your newly created graphic.
      pause
      repeat with a fresh map background.

      Your signals will then appear to move, fade in strength or dissappear all together depending on the values you feed them.

      Later when you want to change behavior, you only have to change the SignalClass one time, one place. If you find a better way to do the replace your update doesn't have to become a nightmare. If you want to add a sound effect to taking away the signal, no big deal.

      Your mantra is... "Small discrete methods that have one task. Not massive methods that try to do everything."

      Its easier to create a behavior by calling methods in the order:
      A, B, C, D, E

      Then later get an all new behavior by just changing the order to:
      A, B, E, D, C

      If all those methods exist as a complex set of If... else... switch clauses it is much harder to make a second behavior that is close to the first, but not quite. You have to copy that entire big method and make changes. Now you have two nearly identical methods to keep changes synchronized.

      Sorry if I got a little side tracked. The goal after all is better code practices in general and not just the shortest answer to the question, if that answer is just going to create a bigger nightmare for you later down the line.

      Comment

      • kspiros
        New Member
        • Oct 2008
        • 16

        #4
        Originally posted by Plater
        Don't keep drawing the elipse?
        How can i dispose it?

        Comment

        • kspiros
          New Member
          • Oct 2008
          • 16

          #5
          Originally posted by tlhintoq
          I need to make sure I understand what it is you're trying to do.

          You have a graphic. The streetmap background for example.
          Then you are painting onto it the various ellipses that represent different signals, such as WiFi.
          This is correct, this what I am trying to do
          Originally posted by tlhintoq
          Later, you want to take away the ellipses you painted and have your background street map still intact, and not have big holes in from your ellipses.
          Does that sound right?
          I am trying not to take away all the ellipses at the same time. I will explain . I have a map in a picture box in this picture box i can click only twice and only in the roads then a thread is painting the road between the first and the second click. What I mean is it starts from the first click and slowly draws the road to the second click as a gps of a car. While lets say driving it passes by from various networks with different capabilities each. What i am trying to show is when lets say the car is in range i increase the alpha of the network and when is out of rage i decrease it. The problem is that i can not dispose any ellipse i want without touching the image.
          Originally posted by tlhintoq
          You can't really. If you only have one graphic in memory, and you change it, then you've changed it. There is nothing holding the data that used to be there before you changed it.

          I think you will have to make a more significant change to your program in order to restore the underlying graphic. You can't just draw on your base and forget where/what was done and try to figure it out in a later method.

          I think you will have better luck if you actually keep track of the drawn ellipses as objects. Create a "Signal" Class with properties like SignalType, SignalCenter, SignalRange etc. Give the class methods for drawing itself, and other basic functionality. Then for each signal create an instance of the class and stick them in an array. A SignalClass[ ].
          I have everything in my database
          Originally posted by tlhintoq
          Now you can call
          Code:
          mySignalClassArray[3].SetSignalAs(ENUMERATEDSIGNAL_WIFI);
          mySignalClassArray[3].SetCenter(50,200);// Point x, Point y
          mySignalClassArray[3].SetRange(45);// 1 pixel = 1 map scale foot
          mySignalClassArray[3].DrawEllipse(nSignalStregth);//Weak signal becomes more transparant

          If you keep one copy of the base street map in memory you can use it as a source to copy from.
          What do you mean?
          Originally posted by tlhintoq
          So you make a new copy of the map to a graphic in memory,
          Loop through all your SignalArray iterations painting ellipses,
          Replace the displayed graphic with your newly created graphic.
          pause
          repeat with a fresh map background.

          Your signals will then appear to move, fade in strength or dissappear all together depending on the values you feed them.

          Later when you want to change behavior, you only have to change the SignalClass one time, one place. If you find a better way to do the replace your update doesn't have to become a nightmare. If you want to add a sound effect to taking away the signal, no big deal.

          Your mantra is... "Small discrete methods that have one task. Not massive methods that try to do everything."

          Its easier to create a behavior by calling methods in the order:
          A, B, C, D, E

          Then later get an all new behavior by just changing the order to:
          A, B, E, D, C

          If all those methods exist as a complex set of If... else... switch clauses it is much harder to make a second behavior that is close to the first, but not quite. You have to copy that entire big method and make changes. Now you have two nearly identical methods to keep changes synchronized.

          Sorry if I got a little side tracked. The goal after all is better code practices in general and not just the shortest answer to the question, if that answer is just going to create a bigger nightmare for you later down the line.
          [/QUOTE]
          I will give you more photos. I am not very good in graphics because it is the first time i use them image3 image4 image5

          Comment

          • tlhintoq
            Recognized Expert Specialist
            • Mar 2008
            • 3532

            #6
            Originally posted by kspiros
            This is correct, this what I am trying to do

            I am trying not to take away all the ellipses at the same time. I will explain . I have a map in a picture box in this picture box i can click only twice and only in the roads then a thread is painting the road between the first and the second click. What I mean is it starts from the first click and slowly draws the road to the second click as a gps of a car. While lets say driving it passes by from various networks with different capabilities each. What i am trying to show is when lets say the car is in range i increase the alpha of the network and when is out of rage i decrease it. The problem is that i can not dispose any ellipse i want without touching the image.

            I have everything in my database

            What do you mean?


            I will give you more photos. I am not very good in graphics because it is the first time i use them image3 image4 image5
            I kinda had a feeling this was the direction of the project based on the graphics you posted with the street map and the various signal types in the legend of the graphic.

            Let me try rephrasing the suggestions of the earlier post.

            Quit thinking you are going to keep just one image on screen.
            Instead, consider posting a new image on screen once per second.
            You don't have to "undo" what you've already painted. Just replace one graphic with an updated graphic.

            You can use a Timer for this. Each time the timer ticks it will call a function such as MakeNewMap(), then put a newly created image in your picture box.
            Code:
            Bitmap myTempMap = null;// member variable
            Bitmap BaseMapImage = null; // set this to your street map so you always have a clean copy of it to use later
            MakeNewMap()
            {
                 myTempMap = BaseMapImage;
                 UpdateWiFi();// This method will draw an ellipse for the WiFi signal
                 UpdateWiMax();// This method will draw an ellipse for the WiMax signal
                 UpdateUMTS();// you get the drift
            
            }
            private void timer1_Tick(object sender, System.EventArgs e)
             {
                 MakeNewMap();
                 pictureBox_map.Image = myTempMap;
            }

            Comment

            • kspiros
              New Member
              • Oct 2008
              • 16

              #7
              Solved

              Originally posted by tlhintoq
              I kinda had a feeling this was the direction of the project based on the graphics you posted with the street map and the various signal types in the legend of the graphic.

              Let me try rephrasing the suggestions of the earlier post.

              Quit thinking you are going to keep just one image on screen.
              Instead, consider posting a new image on screen once per second.
              You don't have to "undo" what you've already painted. Just replace one graphic with an updated graphic.

              You can use a Timer for this. Each time the timer ticks it will call a function such as MakeNewMap(), then put a newly created image in your picture box.
              Code:
              Bitmap myTempMap = null;// member variable
              Bitmap BaseMapImage = null; // set this to your street map so you always have a clean copy of it to use later
              MakeNewMap()
              {
                   myTempMap = BaseMapImage;
                   UpdateWiFi();// This method will draw an ellipse for the WiFi signal
                   UpdateWiMax();// This method will draw an ellipse for the WiMax signal
                   UpdateUMTS();// you get the drift
              
              }
              private void timer1_Tick(object sender, System.EventArgs e)
               {
                   MakeNewMap();
                   pictureBox_map.Image = myTempMap;
              }
              thank you these was extremely helpful!!! thanks a lot!!!

              Comment

              • kspiros
                New Member
                • Oct 2008
                • 16

                #8
                I have another problem now. the circles are not painted in the exact location which I want them to. For example, I want to paint them in coordinates lets say x=200
                y=200 and r=200, that is why i use
                Code:
                xGraph.FillEllipse(Brush, 200, 200, 200,200);
                but in the picture it does not go exactly on the point (200,200) of the picture with exactly r=200 but instead goes to about (300,300) with r=100. How can i solve this?

                Comment

                • Plater
                  Recognized Expert Expert
                  • Apr 2007
                  • 7872

                  #9
                  The dimensions that you supply to the drawing are not the center point but the bounding rectangle, have you been formulating for that?

                  Comment

                  • kspiros
                    New Member
                    • Oct 2008
                    • 16

                    #10
                    Originally posted by Plater
                    The dimensions that you supply to the drawing are not the center point but the bounding rectangle, have you been formulating for that?
                    you are correct i did not notice that it was the diameter. i can fix that by putting 2*r
                    Code:
                    xGraph.FillEllipse(Brush, 200, 200,2* 200,2*200); //2*200=2*r
                    how can i use them to put the center? By saying bounding rectangle what do you mean what x and y means?

                    Comment

                    • kspiros
                      New Member
                      • Oct 2008
                      • 16

                      #11
                      I found the reason why these is the answer!!!
                      Code:
                      xGraph.FillEllipse(Brush, X - R, Y - R, 2 * R, 2 * R);
                      Thanks a lot for all your help!!!

                      Comment

                      Working...