none
How to make 2D graphics look 3D

    Question

  • Is it possible to make 2D graphics look 3D in visual basic. Or do i need to use XNAEngine or Viewport 3D? - Thanks civilwarrock
    Wednesday, July 07, 2010 9:21 PM

Answers

  • Do you mean you want to know how make the image appear to rotate around the x-axis (it saves a lot of toing-and-froing if you can state you task precisely)?

    As mentioned, you can use the skew operation to make a flat image appear to rotate within a 3D space.

    Imports System.Drawing.Drawing2D
    Public Class Form1
        
    Dim points(2) As Point
        
    Dim R As Double = 0
        
    Dim RIncr As Double = 0.05
        
    Dim XOrg As Double
        Dim YOrg As Double
        Dim X1Org As Double
        Dim Yincr As Double = 0

        
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            points(0) = 
    New Point(PictureBox2.Width * 0.2, PictureBox2.Height * 0.2)
            points(1) = 
    New Point(PictureBox2.Width * 0.8, PictureBox2.Height * 0.2)
            points(2) = 
    New Point(PictureBox2.Width * 0.2, PictureBox2.Height * 0.8)
            XOrg = points(2).X
            YOrg = points(2).Y - (PictureBox2.Height / 3)
            X1Org = points(1).X
        
    End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            Timer1.Interval = 25
            Timer1.Enabled = 
    True
        End Sub

        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Yincr = Math.Sin(R) * PictureBox2.Height / 2
            R += RIncr
            
    If Math.Abs(R) > 0.935 Then RIncr *= -1
            
    Me.Invalidate()
        
    End Sub

        Private Sub Form1_Paint(ByVal sender As ObjectByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            points(0) = 
    New Point(XOrg, YOrg - Yincr)
            points(1) = 
    New Point(X1Org, YOrg - Yincr)
            points(2) = 
    New Point(XOrg, YOrg + Yincr)
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            g.Clear(Color.Transparent)
            g.DrawImage(PictureBox1.Image, points)
            PictureBox2.Image = Bmp1
        
    End Sub
    End
     Class

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Monday, July 12, 2010 12:24 AM
  • Can you tell me how to make a 2d graphic look curved and be able to rotate it? Thanks - civilwarrock


    There is no built in function or method unless you write your own 3D class or structure using GDI+. Read this articles http://www.vcskicks.com/3d_gdiplus_drawing.php

    kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 4:37 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 07, 2010 11:28 PM
  • You rotate a graphic using a transform.  There is a very thorough description here:

    http://www.bobpowell.net/transformations.htm

    Note that the Shear rotation is mainly used for 3D effects.  

    What sort of curve are you trying to achieve?  There is an example at the site below that includes several varieties of curving (or 'warping') of an image, or you can define your own by creating a new case in the MapPixel function.

    http://www.vb-helper.com/howto_net_warp.html

     

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 3:54 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 07, 2010 11:58 PM
  • To rotate an image around the Z axis, use a transform.  Note that you need to set the rotation point - typically it is the centre of the image. Here is some typical code.  The image to draw is being selected from an image list.  The rotation angle is from a text box.

        Dim m As Matrix = New Matrix()
            
    Dim g As Graphics = Graphics.FromImage(bmp1)
            A = Val(txtAngle.Text)
            m.RotateAt(A, 
    New Point(50, 50))
            g.Clear(Color.Transparent)
            g.Transform = m
            g.DrawImage(overlayImages(HScrollBar1.Value), 0, 0, 100, 100)
            PictureBox1.Image = bmp1

    This has nothing to do with making the image look 3D, so I am not sure it is what you meant.    

    You cannot rotate an image up or down.   You can translate an image up or down.   You can use a transform to translate an image.

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 7:21 AM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Thursday, July 08, 2010 3:32 AM
  • Matrix is a class in the System.Drawing.Drawing2D namespace:

    http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.matrix.aspx
    Matrix Class

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 3:54 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Thursday, July 08, 2010 6:25 AM
  • You can't use that code as is - you have to integrate it with your code.  As I indicated when I posted that code, A is the angle of rotation and OverlayImages is an image list.  Replace A with whatever angle your want to rotate by, and replace the image referenced in OverlayImages with the image you want to rotate.
    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 3:53 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Thursday, July 08, 2010 7:16 AM
  • The following code will copy the image from picturebox1 to picturebox2 with a rotation of 27.5 degrees clockwise.

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            
    Dim m As Matrix = New Matrix()
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            
    Dim A As Double = 27.5
            m.RotateAt(A, 
    New Point(PictureBox1.Width \ 2, PictureBox1.Height \ 2))
            g.Clear(Color.Transparent)
            g.Transform = m
            g.DrawImage(PictureBox1.Image, 0, 0)
            PictureBox2.Image = Bmp1
        
    End Sub

    I can't see my earlier post, so I apologise if this appears twice.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Friday, July 09, 2010 1:39 AM
  • Once you have the procedure for using a matirix, you only need to adjust the matrix variables and the matrix operation to do whatever you require.  The following code translates an image 5 pixels left and 12 pixels down.  Note that this translation is relative to the drawing position (0,0) as specificed for the DrawImage method.   So the matrix translation is in addition to any translation you do by specifying a different drawing position.

    Note that the real power of the matrix comes from combiing different matrix operations.

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            
    'Translate
            Dim m As Matrix = New Matrix()
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            m.Translate(-5, 12)
            g.Clear(Color.Transparent)
            g.Transform = m
            g.DrawImage(PictureBox1.Image, 0, 0)
            PictureBox2.Image = Bmp1
        
    End Sub

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Sunday, July 11, 2010 11:19 PM
  • That code works properly when I test it here, so I don't know what might need to be fixed.  Do you have an image in picture box 1? Have you traced it in the debugger to see the state of the variables as each line is executed?

    Unfortunately your description and diagram doesn't tell me much.  I would take 'flipped' to mean rotated either horizontally or vertically by 180 degrees:

    Horizontal Flip (invert about Y axis)   ^-|->     ->     <-|-^
    Vertical Flip (invert about X axis)      ^-|->     ->     v-|->

    The code below demonstrates horizontal, vertical and combined flipping.

    Public Class Form1

        
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            
    Dim points(2) As Point
            points(0) = 
    New Point(0, PictureBox2.Height)
            points(1) = 
    New Point(PictureBox2.Width, PictureBox2.Height)
            points(2) = 
    New Point(0, 0)
            ImageCopy(points)
        
    End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            
    Dim points(2) As Point
            points(0) = 
    New Point(PictureBox2.Width, 0)
            points(1) = 
    New Point(0, 0)
            points(2) = 
    New Point(PictureBox2.Width, PictureBox2.Height)
            ImageCopy(points)
        
    End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            
    Dim points(2) As Point
            points(0) = 
    New Point(PictureBox2.Width, PictureBox2.Height)
            points(1) = 
    New Point(0, PictureBox2.Height)
            points(2) = 
    New Point(PictureBox2.Width, 0)
            ImageCopy(points)
        
    End Sub

        Private Sub ImageCopy(ByVal Points As Point())
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            g.DrawImage(PictureBox1.Image, Points)
            PictureBox2.Image = Bmp1
        
    End Sub

    End
     Class

      

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Monday, July 12, 2010 5:55 AM
  • Ok can you modify this so that if you press the up key it will turn or rotate up or what ever it is you used and if you press the down key it will rotate or turn down. If you could do this i will be done. Thanks for all your help and support it means a lot to me. Thanks - civilwarrock


    Just copy the code from the timer tick event into the up button and down button click events.  Adjust the RIncr value so that the change is actually visible (currently it will be too small) and select to add to or subtract from R according to whether you want to tilt it up or down (you will have to experiment to see which is which).
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Monday, July 12, 2010 8:40 AM
  • What is the code that you now have for the button up and button down events?   Did you make the changes I mentioned?

    To understand the code you need to step throught it line by line in the debugger, noting the values of each of the variables at each line, and consulting the MSDN reference for the method that is being executed.  Everything is actually in the DrawImage method - it's the values that are passed in the Point array that do all the work.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Tuesday, July 13, 2010 7:04 AM
  • I did not just say to copy the code from the timer event.  I also said:

    "Adjust the RIncr value so that the change is actually visible (currently it will be too small) and select to add to or subtract from R according to whether you want to tilt it up or down (you will have to experiment to see which is which)."

    If you just copy the code fromthe timer tick event the change for each click will be too tiny to notice, and will be in the direction dictated by the current value of the incrmenet counter instead of being based whether the code was in the up button or the down button event.   If you make the changes I suggested, it works properly.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Tuesday, July 13, 2010 10:26 PM
  • You have not posted your code, so there is no way that I can tell what is wrong with it.

    There are many ways to do this.  I don't know which of them might be easier to understand, but I suspect this one is about as simple as it gets.  For instance, there is no attempt at perspective.   To understand how it works, trace the code in the debugger line by line, examining the variables at each step.

    R is the amount of rotation. The rotation increment is the change in rotation per timer tick, or per button press in the revised verion.  Currently this is 0.05, which is tiny, but suitable for fast timer ticks.  You should change it to a larger value for button clicks, such as 0.15 or 0.2.

    The display increment (note - it is Y, not R) is the amount that the display changes for each change in R. The display is 2D, but rotation is, of course, a 3D concept.   The Sin function is used in the calculation because the point that moves is the tip of the rectangle, and it is moving in a circle.  The Sin function translates circular (3D) rotation around a 2D axis into a linear distance on the 2D plane.

    The rotation direction is determined by whether the rotation increment is added to or subtracted from R.  You will have to experiment to see which direction is which.

    I'm not sure what you mean by " it just goes up and then back down ", but if you are saying that the first button click is in the wrong direction and later clicks are in the correct direction (or vice versa) then that suggests that you are calculting the increment after the adjustment for R, as per my original code.  This doesn't matter for timer ticks (the end result is the same, just delayed by a tick) but it may be disconcerting for the button-press version.  Put the calculation of the increment before the update of R.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 14, 2010 3:35 AM
  • The R value is initially 0 and varies by the amount of the increment for each button click, which I recommended as +/- 0.15 or +/- 0.2. There is a magic value in the code which is 60% of 90 degrees (0.935).   It is 60% because the rotating image is 60% of the size of the original. This defined the point at which the rotation reversed during the timer tick, but it is not relevant for the button-click version.

    If you want the rotating copy to occupy the whole of the picturebox, adjust the calculation of the points to remove the fractional component of the picture box size - the 0.2 factors become zero (top and left) and the 0.8 factors become 1 (width and height).  Then adjust the rotation point to the middle of the image instead of 1/3 of the image height.  If you want it to be the same size as the original, use Picturebox1 width and height in the calculation of the points, instead of Picturebox2.

      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            points(0) = 
    New Point(0, 0)
            points(1) = 
    New Point(PictureBox2.Width, 0)
            points(2) = 
    New Point(0, PictureBox2.Height)
            XOrg = points(2).X
            YOrg = points(2).Y - (PictureBox2.Height / 2)
            X1Org = points(1).X
        
    End Sub

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 14, 2010 6:37 AM
  • I can't see that you have implemented any of the changes that I said were necessary if you were to move that code from the Timer Tick event to a button up or button down click event.  In particular, you still have the increment to R occurring after the calculation, even though I (apparently) correctly guessed that your problem was that the initial movement on a button click was in the wrong direction.  Make the changes that I suggested and the code will work

    "Adjust the RIncr value so that the change is actually visible (currently it will be too small)" means that you should change the code wo that instead of using RIncr, use a constant such as 0.15 or 0.2. 

    " and select to add to or subtract from R according to whether you want to tilt it up or down (you will have to experiment to see which is which)." means that in one of those routines you should add your constant (eg, 0.2) and in the other routine you should subtract it.

    As a result, RIncr becomes unnecessary, and the test and adjust of RIncr can be removed.

    "Put the calculation of the increment before the update of R." is not entirely clear, but you should have been able to work it out from the context.  I should have said "Put the calculation of the increment to R (whether it be positive or negative) before the calculation that uses the updated value of R". In other words, invert the sequence of calculations so that the change in R aoccurs before it is used, not after.  That is - invert the order of the remaining two lines of code.  That's all there was to it.

     

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 14, 2010 11:21 PM

All replies

  • I do not know of any way to make 2D graphics look 3D in VB.  I would strongly recommend software that is designed for graphics.

    A forum to look into might be:

    http://forums.xna.com/forums/

    • Edited by Max Will Wednesday, July 07, 2010 10:00 PM Updated
    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 4:36 PM
    Wednesday, July 07, 2010 9:58 PM
  • What do you mean by 'look 3D'?  By definition, a 2D graphic is a flat image,  You can make it look like a curved or tilted flat image - that is, a flat object in a 3D space - quite easily by using a transform.   You can rotate it as a flat image around any axis in 3D space.   You can add the effect of a raised or bevelled edge.  But you can't make it look like a 3D image because it doesn't contain any information about the 3rd dimension.   You can convert an image to a 3D shape using other information in the image, such as color, to represent the 3rd dimension (this technique is used to create textures).   Or you can convert it to a 3D image by using information from some other source to provide the data for the 3rd dimension - for instance you can wrap a 2D image around a geometrical shape such as a sphere.  But without knowing what you expect a 2D image to look like in 3D, there is no way to address your query in detail.      

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 4:36 PM
    Wednesday, July 07, 2010 10:59 PM
  • Can you tell me how to make a 2d graphic look curved and be able to rotate it? Thanks - civilwarrock
    Wednesday, July 07, 2010 11:12 PM
  • Can you tell me how to make a 2d graphic look curved and be able to rotate it? Thanks - civilwarrock


    There is no built in function or method unless you write your own 3D class or structure using GDI+. Read this articles http://www.vcskicks.com/3d_gdiplus_drawing.php

    kaymaf


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 4:37 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 07, 2010 11:28 PM
  • You rotate a graphic using a transform.  There is a very thorough description here:

    http://www.bobpowell.net/transformations.htm

    Note that the Shear rotation is mainly used for 3D effects.  

    What sort of curve are you trying to achieve?  There is an example at the site below that includes several varieties of curving (or 'warping') of an image, or you can define your own by creating a new case in the MapPixel function.

    http://www.vb-helper.com/howto_net_warp.html

     

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 3:54 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 07, 2010 11:58 PM
  • What i need to do is rotate a image left right up down. Thanks - civilwarrock
    Thursday, July 08, 2010 2:37 AM
  • To rotate an image around the Z axis, use a transform.  Note that you need to set the rotation point - typically it is the centre of the image. Here is some typical code.  The image to draw is being selected from an image list.  The rotation angle is from a text box.

        Dim m As Matrix = New Matrix()
            
    Dim g As Graphics = Graphics.FromImage(bmp1)
            A = Val(txtAngle.Text)
            m.RotateAt(A, 
    New Point(50, 50))
            g.Clear(Color.Transparent)
            g.Transform = m
            g.DrawImage(overlayImages(HScrollBar1.Value), 0, 0, 100, 100)
            PictureBox1.Image = bmp1

    This has nothing to do with making the image look 3D, so I am not sure it is what you meant.    

    You cannot rotate an image up or down.   You can translate an image up or down.   You can use a transform to translate an image.

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 7:21 AM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Thursday, July 08, 2010 3:32 AM
  • How do i declare or import matrix? Beacause it gives me a error saying Matrix is not defined. - Thanks a whole bunch - civilwarrock
    Thursday, July 08, 2010 6:16 AM
  • Matrix is a class in the System.Drawing.Drawing2D namespace:

    http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.matrix.aspx
    Matrix Class

    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 3:54 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Thursday, July 08, 2010 6:25 AM
  • Acamar, I am having some trouble with your code. first "A" i not declared. And Second "OverlayImages" Is not defined. so if you can help that would be great. Thanks - civilwarrock
    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 7:21 AM
    Thursday, July 08, 2010 7:04 AM
  • You can't use that code as is - you have to integrate it with your code.  As I indicated when I posted that code, A is the angle of rotation and OverlayImages is an image list.  Replace A with whatever angle your want to rotate by, and replace the image referenced in OverlayImages with the image you want to rotate.
    • Marked as answer by civilwarrock Thursday, July 08, 2010 7:20 AM
    • Unmarked as answer by civilwarrock Thursday, July 08, 2010 3:53 PM
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Thursday, July 08, 2010 7:16 AM
  • Ok i tryed what you said and no go. I cant get this line to work g.drawimage(overlayimages(hscrollbar1.value),0,0,100,100) can you modify the code so it uses picturebox1's image as bmp1 and put it into picturebox 2. That would help , Thanks - civilwarrock
    Thursday, July 08, 2010 3:39 PM
  • The following code will copy the image from picturebox1 to picturebox2 with a rotation of 27.5 degrees clockwise.

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            
    Dim m As Matrix = New Matrix()
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            
    Dim A As Double = 27.5
            m.RotateAt(A, 
    New Point(PictureBox1.Width \ 2, PictureBox1.Height \ 2))
            g.Clear(Color.Transparent)
            g.Transform = m
            g.DrawImage(PictureBox1.Image, 0, 0)
            PictureBox2.Image = Bmp1
        
    End Sub

    I can't see my earlier post, so I apologise if this appears twice.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Friday, July 09, 2010 1:39 AM
  • Thats ok, Thanks for the code it worked great! Um Acamar on the first post you posted with the code i could not get to work you said i could translate a image up or down. Do you have a link i could look at on how to do that or any ideas? Thanks - civilwarrock

    Sunday, July 11, 2010 5:55 PM
  • Once you have the procedure for using a matirix, you only need to adjust the matrix variables and the matrix operation to do whatever you require.  The following code translates an image 5 pixels left and 12 pixels down.  Note that this translation is relative to the drawing position (0,0) as specificed for the DrawImage method.   So the matrix translation is in addition to any translation you do by specifying a different drawing position.

    Note that the real power of the matrix comes from combiing different matrix operations.

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            
    'Translate
            Dim m As Matrix = New Matrix()
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            m.Translate(-5, 12)
            g.Clear(Color.Transparent)
            g.Transform = m
            g.DrawImage(PictureBox1.Image, 0, 0)
            PictureBox2.Image = Bmp1
        
    End Sub

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Sunday, July 11, 2010 11:19 PM
  • What i meant was how to turn the image up or down with a 2D image is this possible. Please help - thanks civilwarrock
    Sunday, July 11, 2010 11:34 PM
  • Do you mean you want to know how make the image appear to rotate around the x-axis (it saves a lot of toing-and-froing if you can state you task precisely)?

    As mentioned, you can use the skew operation to make a flat image appear to rotate within a 3D space.

    Imports System.Drawing.Drawing2D
    Public Class Form1
        
    Dim points(2) As Point
        
    Dim R As Double = 0
        
    Dim RIncr As Double = 0.05
        
    Dim XOrg As Double
        Dim YOrg As Double
        Dim X1Org As Double
        Dim Yincr As Double = 0

        
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            points(0) = 
    New Point(PictureBox2.Width * 0.2, PictureBox2.Height * 0.2)
            points(1) = 
    New Point(PictureBox2.Width * 0.8, PictureBox2.Height * 0.2)
            points(2) = 
    New Point(PictureBox2.Width * 0.2, PictureBox2.Height * 0.8)
            XOrg = points(2).X
            YOrg = points(2).Y - (PictureBox2.Height / 3)
            X1Org = points(1).X
        
    End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            Timer1.Interval = 25
            Timer1.Enabled = 
    True
        End Sub

        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Yincr = Math.Sin(R) * PictureBox2.Height / 2
            R += RIncr
            
    If Math.Abs(R) > 0.935 Then RIncr *= -1
            
    Me.Invalidate()
        
    End Sub

        Private Sub Form1_Paint(ByVal sender As ObjectByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            points(0) = 
    New Point(XOrg, YOrg - Yincr)
            points(1) = 
    New Point(X1Org, YOrg - Yincr)
            points(2) = 
    New Point(XOrg, YOrg + Yincr)
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            g.Clear(Color.Transparent)
            g.DrawImage(PictureBox1.Image, points)
            PictureBox2.Image = Bmp1
        
    End Sub
    End
     Class

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Monday, July 12, 2010 12:24 AM
  • Acamar, Sorry But for some reason the code you gave me deos not work. I mean there is no errors but when i test it i just clears picturebox2's image leaving no new one. Can you fix the code? Thanks for the help - civilwarrock

     

    P.S. Here is a example of what i am trying to acomplish and if you can figure this out you will be a life saver!

    Ok so lets say i have a 2D image like this |------|   ok and now its flipped   |  Ok now i want to have it look like the first example but i want the top ------  rotate or turn down ward like in blendar 

                                                                                                              

    Monday, July 12, 2010 5:14 AM
  • That code works properly when I test it here, so I don't know what might need to be fixed.  Do you have an image in picture box 1? Have you traced it in the debugger to see the state of the variables as each line is executed?

    Unfortunately your description and diagram doesn't tell me much.  I would take 'flipped' to mean rotated either horizontally or vertically by 180 degrees:

    Horizontal Flip (invert about Y axis)   ^-|->     ->     <-|-^
    Vertical Flip (invert about X axis)      ^-|->     ->     v-|->

    The code below demonstrates horizontal, vertical and combined flipping.

    Public Class Form1

        
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            
    Dim points(2) As Point
            points(0) = 
    New Point(0, PictureBox2.Height)
            points(1) = 
    New Point(PictureBox2.Width, PictureBox2.Height)
            points(2) = 
    New Point(0, 0)
            ImageCopy(points)
        
    End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            
    Dim points(2) As Point
            points(0) = 
    New Point(PictureBox2.Width, 0)
            points(1) = 
    New Point(0, 0)
            points(2) = 
    New Point(PictureBox2.Width, PictureBox2.Height)
            ImageCopy(points)
        
    End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            
    Dim points(2) As Point
            points(0) = 
    New Point(PictureBox2.Width, PictureBox2.Height)
            points(1) = 
    New Point(0, PictureBox2.Height)
            points(2) = 
    New Point(PictureBox2.Width, 0)
            ImageCopy(points)
        
    End Sub

        Private Sub ImageCopy(ByVal Points As Point())
            
    Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
            
    Dim g As Graphics = Graphics.FromImage(Bmp1)
            g.DrawImage(PictureBox1.Image, Points)
            PictureBox2.Image = Bmp1
        
    End Sub

    End
     Class

      

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Monday, July 12, 2010 5:55 AM
  • Im sorry Acamar, The code i said did not work works witch is this one,

    Imports System.Drawing.Drawing2D
    Public Class Form1
      Dim points(2) As Point
      Dim R As Double = 0
      Dim RIncr As Double = 0.05
      Dim XOrg As Double
      Dim YOrg As Double
      Dim X1Org As Double
      Dim Yincr As Double = 0
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        points(0) = New Point(PictureBox2.Width * 0.2, PictureBox2.Height * 0.2)
        points(1) = New Point(PictureBox2.Width * 0.8, PictureBox2.Height * 0.2)
        points(2) = New Point(PictureBox2.Width * 0.2, PictureBox2.Height * 0.8)
        XOrg = points(2).X
        YOrg = points(2).Y - (PictureBox2.Height / 3)
        X1Org = points(1).X
      End Sub
    
      Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Timer1.Interval = 25
        Timer1.Enabled = True
      End Sub
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Yincr = Math.Sin(R) * PictureBox2.Height / 2
        R += RIncr
        If Math.Abs(R) > 0.935 Then RIncr *= -1
        Me.Invalidate()
      End Sub
    
      Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        points(0) = New Point(XOrg, YOrg - Yincr)
        points(1) = New Point(X1Org, YOrg - Yincr)
        points(2) = New Point(XOrg, YOrg + Yincr)
        Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
        Dim g As Graphics = Graphics.FromImage(Bmp1)
        g.Clear(Color.Transparent)
        g.DrawImage(PictureBox1.Image, points)
        PictureBox2.Image = Bmp1
      End Sub
    End Class
    
    

     

    Ok can you modify this so that if you press the up key it will turn or rotate up or what ever it is you used and if you press the down key it will rotate or turn down. If you could do this i will be done. Thanks for all your help and support it means a lot to me. Thanks - civilwarrock

    Monday, July 12, 2010 6:45 AM
  • Ok can you modify this so that if you press the up key it will turn or rotate up or what ever it is you used and if you press the down key it will rotate or turn down. If you could do this i will be done. Thanks for all your help and support it means a lot to me. Thanks - civilwarrock


    Just copy the code from the timer tick event into the up button and down button click events.  Adjust the RIncr value so that the change is actually visible (currently it will be too small) and select to add to or subtract from R according to whether you want to tilt it up or down (you will have to experiment to see which is which).
    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Monday, July 12, 2010 8:40 AM
  •  Acamar, Ok i still cant seem to get this to work in a up and down arrow key event. Here is the first problem i dont understand the code at all. The second is that when i do put the code from the timer into the events when i go to press the up button it deos go up but the it geos down like in the timer. So if you can explane the code to me and help me get it to were it you press the up key it turns or rotates down and if you press the down key it turns or rotates up. Also can you make it so it keeps the image size the same? if you can do these things for me that would be great! Thanks a ton - civilwarrock

    P.S. YOU SHOULD GET TWO MORE AWARDS FOR HELPING ME!!!! =)

    Tuesday, July 13, 2010 5:58 AM
  • What is the code that you now have for the button up and button down events?   Did you make the changes I mentioned?

    To understand the code you need to step throught it line by line in the debugger, noting the values of each of the variables at each line, and consulting the MSDN reference for the method that is being executed.  Everything is actually in the DrawImage method - it's the values that are passed in the Point array that do all the work.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Tuesday, July 13, 2010 7:04 AM
  • Acamar, I just copped the code from the timer event like you said. But as i said before it just goes up and then back down for the up button, Witch i dont want to happen. So if you could fix the code or tell me how it deos this i may be able to fix it. Thanks - civilwarrock
    Tuesday, July 13, 2010 3:37 PM
  • I did not just say to copy the code from the timer event.  I also said:

    "Adjust the RIncr value so that the change is actually visible (currently it will be too small) and select to add to or subtract from R according to whether you want to tilt it up or down (you will have to experiment to see which is which)."

    If you just copy the code fromthe timer tick event the change for each click will be too tiny to notice, and will be in the direction dictated by the current value of the incrmenet counter instead of being based whether the code was in the up button or the down button event.   If you make the changes I suggested, it works properly.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Tuesday, July 13, 2010 10:26 PM
  • Acamar, I tried what you said and no go. I cant figure the code out. Is there another way to do exacly like this but a little easyer to understand. Iv'e figured out really tough codes before but im stuck on this one. Thanks - civilwarrock
    Wednesday, July 14, 2010 3:09 AM
  • You have not posted your code, so there is no way that I can tell what is wrong with it.

    There are many ways to do this.  I don't know which of them might be easier to understand, but I suspect this one is about as simple as it gets.  For instance, there is no attempt at perspective.   To understand how it works, trace the code in the debugger line by line, examining the variables at each step.

    R is the amount of rotation. The rotation increment is the change in rotation per timer tick, or per button press in the revised verion.  Currently this is 0.05, which is tiny, but suitable for fast timer ticks.  You should change it to a larger value for button clicks, such as 0.15 or 0.2.

    The display increment (note - it is Y, not R) is the amount that the display changes for each change in R. The display is 2D, but rotation is, of course, a 3D concept.   The Sin function is used in the calculation because the point that moves is the tip of the rectangle, and it is moving in a circle.  The Sin function translates circular (3D) rotation around a 2D axis into a linear distance on the 2D plane.

    The rotation direction is determined by whether the rotation increment is added to or subtracted from R.  You will have to experiment to see which direction is which.

    I'm not sure what you mean by " it just goes up and then back down ", but if you are saying that the first button click is in the wrong direction and later clicks are in the correct direction (or vice versa) then that suggests that you are calculting the increment after the adjustment for R, as per my original code.  This doesn't matter for timer ticks (the end result is the same, just delayed by a tick) but it may be disconcerting for the button-press version.  Put the calculation of the increment before the update of R.

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 14, 2010 3:35 AM
  • One queston Acamar, before i get the code. How do you know what the "R" value is? Because i dont know how you know this. Plus like i was saying before how can i keep the image size the same? Thansk Acamar - civilwarrock
    Wednesday, July 14, 2010 5:42 AM
  • The R value is initially 0 and varies by the amount of the increment for each button click, which I recommended as +/- 0.15 or +/- 0.2. There is a magic value in the code which is 60% of 90 degrees (0.935).   It is 60% because the rotating image is 60% of the size of the original. This defined the point at which the rotation reversed during the timer tick, but it is not relevant for the button-click version.

    If you want the rotating copy to occupy the whole of the picturebox, adjust the calculation of the points to remove the fractional component of the picture box size - the 0.2 factors become zero (top and left) and the 0.8 factors become 1 (width and height).  Then adjust the rotation point to the middle of the image instead of 1/3 of the image height.  If you want it to be the same size as the original, use Picturebox1 width and height in the calculation of the points, instead of Picturebox2.

      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            points(0) = 
    New Point(0, 0)
            points(1) = 
    New Point(PictureBox2.Width, 0)
            points(2) = 
    New Point(0, PictureBox2.Height)
            XOrg = points(2).X
            YOrg = points(2).Y - (PictureBox2.Height / 2)
            X1Org = points(1).X
        
    End Sub

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 14, 2010 6:37 AM
  • Acamar, i really appreacate the help. Here is the code for the down event.

    If e.KeyCode = Keys.Down Then
          Yincr = Math.Sin(R) * PictureBox2.Height / 2
          R += RIncr
          If Math.Abs(R) > 0.935 Then RIncr *= -1
          Me.Invalidate()
        End If
    Also you said this before "but if you are saying that the first button click is in the wrong direction and later clicks are in the correct direction (or vice versa)" Now i know you know the problem but what you said before because your right, after it goes up it then reverses direction like in the timer tick. So if you can edit this peace of code and just make it go down i would be thank full. Thanks a whole much Acamar, Your my new best freind - civilwarrock
    Wednesday, July 14, 2010 3:59 PM
  • I can't see that you have implemented any of the changes that I said were necessary if you were to move that code from the Timer Tick event to a button up or button down click event.  In particular, you still have the increment to R occurring after the calculation, even though I (apparently) correctly guessed that your problem was that the initial movement on a button click was in the wrong direction.  Make the changes that I suggested and the code will work

    "Adjust the RIncr value so that the change is actually visible (currently it will be too small)" means that you should change the code wo that instead of using RIncr, use a constant such as 0.15 or 0.2. 

    " and select to add to or subtract from R according to whether you want to tilt it up or down (you will have to experiment to see which is which)." means that in one of those routines you should add your constant (eg, 0.2) and in the other routine you should subtract it.

    As a result, RIncr becomes unnecessary, and the test and adjust of RIncr can be removed.

    "Put the calculation of the increment before the update of R." is not entirely clear, but you should have been able to work it out from the context.  I should have said "Put the calculation of the increment to R (whether it be positive or negative) before the calculation that uses the updated value of R". In other words, invert the sequence of calculations so that the change in R aoccurs before it is used, not after.  That is - invert the order of the remaining two lines of code.  That's all there was to it.

     

    • Marked as answer by civilwarrock Tuesday, July 20, 2010 3:53 PM
    Wednesday, July 14, 2010 11:21 PM
  • Thank you Acamar, I finaly figured it out! And now i know how to make 2d graphics look 3D!!!!! Well i hope everybody reads this article because this probilly is the best thread out there. THANK YOU ALL WHO POSTED!!!!!!!!!!! OK WELL I HAVE TO GO DO SOME THINGS BUT HERE IS THE CODE THAT I USED.     

    Public Class Form1
     Dim points(2) As Point
     Dim R As Double = 0
     Dim RIncr As Double = 0.04
     Dim XOrg As Double
     Dim YOrg As Double
     Dim X1Org As Double
     Dim Yincr As Double = 0
    
     Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
      If e.KeyCode = Keys.Down Then
       Yincr = Math.Sin(R) * PictureBox2.Height
       
       R += RIncr
      
    
       Label1.Text = R
       points(0) = New Point(XOrg, YOrg - Yincr)
       points(1) = New Point(X1Org, YOrg - Yincr)
       points(2) = New Point(XOrg, YOrg + Yincr)
       Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
       Dim g As Graphics = Graphics.FromImage(Bmp1)
       g.Clear(Color.Transparent)
       g.DrawImage(PictureBox1.Image, points)
       PictureBox2.Image = Bmp1
      End If
      If e.KeyCode = Keys.Up Then
       Yincr = Math.Sin(R) * PictureBox2.Height
       If R > 3.16 Then
        R = 0
       End If
       R -= RIncr
    
       Label1.Text = R
       points(0) = New Point(XOrg, YOrg - Yincr)
       points(1) = New Point(X1Org, YOrg - Yincr)
       points(2) = New Point(XOrg, YOrg + Yincr)
       Dim Bmp1 As Bitmap = New Bitmap(PictureBox2.Width, PictureBox2.Height)
       Dim g As Graphics = Graphics.FromImage(Bmp1)
       g.Clear(Color.Transparent)
       g.DrawImage(PictureBox1.Image, points)
       PictureBox2.Image = Bmp1
      End If
     End Sub
    
    
    
    
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      points(0) = New Point(0, 0)
      points(1) = New Point(PictureBox1.Width, 0)
      points(2) = New Point(0, PictureBox1.Height)
      XOrg = points(2).X
      YOrg = points(2).Y - (PictureBox1.Height / 2)
      X1Org = points(1).X
    
     End Sub
    
     Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
      
    
     End Sub
    
     Private Sub PictureBox2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox2.Click
    
     End Sub
    End Class
    
    
    I Had to change the code a little to speed up the program so now it works great and it deos not slow down you program!!!!
    • Proposed as answer by Max Will Thursday, July 15, 2010 3:32 PM
    Thursday, July 15, 2010 3:10 PM