Results 1 to 6 of 6

Thread: [RESOLVED] Rotate only a Single Graphics Object

  1. #1

    Thread Starter
    Member Clemeit's Avatar
    Join Date
    Sep 2012
    Posts
    32

    Resolved [RESOLVED] Rotate only a Single Graphics Object

    I need to draw some rectangles. One (or more) need to be rotated by different degrees of rotation, like the picture below.
    I know how to use Matrix.Rotate to apply a rotation to the entire image, and in fact the final product needs to use a matrix to rotate, scale, and translate the entire image, but I also need to rotate individual rectangles.
    Is there a relatively simple way of doing this? I thought that I could use different graphic objects, each with its own matrix, and then draw them all on top of each other, but that's hardly an eloquent solution.
    Name:  forums.png
Views: 549
Size:  1.6 KB

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Rotate only a Single Graphics Object

    Whenever you call a Draw* method on a Graphics object, the "object" specified will be drawn using the current orientation. For instance, if you want one box rotated and one not then draw one box first, then rotate the Graphics object, then draw the other one. E.g.
    vb.net Code:
    1. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    2.     e.Graphics.TranslateTransform(10, 0)
    3.  
    4.     e.Graphics.DrawString("Hello World", Me.Font, Brushes.Black, 0, 0)
    5.  
    6.     e.Graphics.RotateTransform(45)
    7.  
    8.     e.Graphics.DrawString("Hello World", Me.Font, Brushes.Red, 0, 0)
    9. End Sub
    Only the second String will be rotated.

  3. #3

    Thread Starter
    Member Clemeit's Avatar
    Join Date
    Sep 2012
    Posts
    32

    Re: Rotate only a Single Graphics Object

    Wow, that works perfectly. Thanks!

    I was previously using a timer to draw on the form, and I was using code like

    Code:
    Using backbuffer As New Bitmap(500, 500)
         Using g = Graphics.FromImage(backbuffer)
              g.Clear(Color.White)
              g.FillRectangle(Brushes.Black, New Rectangle(New Point(10, 10), New Size(10, 10)))
              Me.CreateGraphics.DrawImage(backbuffer, New Rectangle(New Point(0, 0)))
    Is this method frowned upon, and if so, why? I've always liked it because it allows you to work with a backbuffer, eliminating flickering. The only downside being that the solution you propose doesn't work with this.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Rotate only a Single Graphics Object

    If you were going to call CreateGrapahics then you really must dispose the Graphics object you created when you're done with it. Any object you create that supports it should be disposed when you're done with it.

    That said, you should never call CreateGraphics. Any time you want to draw on a form or other control, you handle the Paint event of that control and use the Graphics object that it provides, as demonstrated above. You don't create that Graphics object so you don't have to dispose it either. If you wanted to force repaints using a Timer then you would call Invalidate on the form or control in the Tick event handler and that would cause the Paint event to be raised, so you would still do the actual drawing in the Paint event handler.

    It is not true that the solution I proposed doesn't work when manually double-buffering. Calling Graphics.FromImage creates a Graphics object for the Image rather than a control but it's still a Graphics object, so you can draw, transform and then draw again in exactly the same way. Note that you are creating that Graphics object so you are responsible for disposing it, which you are doing via that Using block.

    There's probably no need to do that though. If you use a PictureBox to draw on then it is already fully optimised for GDI+ so there's no issue there. If you can't do that then you can set the DoubleBuffered property of your form to True and it will then pretty much do automatically in the background what you're doing manually.

    By the way, it is considered good practice to call Invalidate and specify the smallest area you can to encompass all the area that has or may have changed. That way, the actual painting to the screen - which is the slowest part - is minimised. You don't want to make your calculations too complex but don't just invalidate the whole form if you know that only a small box may have changed.

  5. #5

    Thread Starter
    Member Clemeit's Avatar
    Join Date
    Sep 2012
    Posts
    32

    Re: Rotate only a Single Graphics Object

    Awesome explanation. Thanks again for the help.

  6. #6
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Rotate only a Single Graphics Object

    For some other examples of rotating individual objects, here are some links to examples I've posted helping others. There are quite a few others as well, but these three may be of some value and interest.

    Bottling plant conveyor animation

    The mouse dragging an object with is linked to a number of other objects that get dragged along with it.

    Manuipulating the parts of a "paper puppet"

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width