Results 1 to 9 of 9

Thread: [RESOLVED] Rotating Linked Images

  1. #1

    Thread Starter
    Fanatic Member sridharavijay's Avatar
    Join Date
    Sep 2002
    Location
    http://www.vijaysridhara.in
    Posts
    589

    Resolved [RESOLVED] Rotating Linked Images

    Hi ... I am developing a comic software, where the character can be posed.
    The character is built using various body parts, and each body part has the following properties
    1) Location 2) Rotation Point (Joint) and 3) Rotation Angle

    They are each individually set and a default pose is created. (You can check the first image)

    Now I want to allow the user to be able to create a new pose for this. While doing this, I have to rotate attached parts together (For example, if lower arm is rotated, the palm should rotate). Unfortunately I am unable to arrive at the right logic, probably due to my limited capability of thought. Can some one help me here ? I have attached 2nd Image which talks about it (Lower arm is rotated, but the palm is going elsewhere)

    I tried these methods
    Method A:
    1) TranslateTransform to RotLoc of Lower arm,
    2) RotateTransform by new angle required
    3) Draw Lower arm
    4) TranslateTransform to RotLoc of Palm,
    5) Rotate Transform by Palms original angle
    6) Draw Palm
    8) Reset Transform
    Method B
    1) TranslateTransform to RotLoc of Lower arm,
    2) RotateTransform by new angle required
    3) Draw Lower arm
    4) Find out new RotLoc of Palm by the sweep of newangle-old angle using two methods
    newX= oldX+ radius * cos(angle)
    newX= oldY+ radius* cos(angle)
    5) Translate to the newX,newY
    6) Rotate Transform by Palms original angle
    7) Draw Palm

    I failed in both.. Can some one throw light
    Attached Images Attached Images   

  2. #2
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: Rotating Linked Images

    First of all what you are trying to do is more complex than I think you think it is.

    Basically you are going to have to keep track of all rotation center points you want to animate, what body parts own those points and what body parts use them for rotation.

    Some of those points will be relocating to new positions as the body parts move.

    For basic 2D rotation I can show you this example link

    See post #5 and #6 in that thread.

    The Protected Overrides Sub OnPaint() Event is where the magic happens.

    Beyond that I would suggest you try to request help from passel. He is well versed in graphics.
    Last edited by Gruff; Jun 21st, 2016 at 11:00 AM.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  3. #3

    Thread Starter
    Fanatic Member sridharavijay's Avatar
    Join Date
    Sep 2002
    Location
    http://www.vijaysridhara.in
    Posts
    589

    Re: Rotating Linked Images

    Quote Originally Posted by Gruff View Post
    First of all what you are trying to do is more complex than I think you think it is.

    Basically you are going to have to keep track of all rotation center points you want to animate, what body parts own those points and what body parts use them for rotation.

    Some of those points will be relocating to new positions as the body parts move.

    For basic 2D rotation I can show you this example link

    See post #5 and #6 in that thread.

    The Protected Overrides Sub OnPaint() Event is where the magic happens.

    Beyond that I would suggest you try to request help from passel. He is well versed in graphics.
    Yeah I know the level of complexity involved. In the default pose, each image is individually handled, and so, the join points, locations, angles are saved. From there, for posing, it is a different path I need to follow. Images are linked. So I started with a basic set of two objects (Lower arm and Palm), so that once successful, I can work with others.

  4. #4
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: Rotating Linked Images

    Okay. Up to you. What the sample code shows it that you translate the center point of the image to 0,0 ,rotate, then translate back to the original position. (or something similar.)
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  5. #5

    Thread Starter
    Fanatic Member sridharavijay's Avatar
    Join Date
    Sep 2002
    Location
    http://www.vijaysridhara.in
    Posts
    589

    Re: Rotating Linked Images

    Quote Originally Posted by Gruff View Post
    Okay. Up to you. What the sample code shows it that you translate the center point of the image to 0,0 ,rotate, then translate back to the original position. (or something similar.)
    Yep, thanks for it. I already achieved it in setting the Default Pose.

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

    Re: Rotating Linked Images

    Without the images to play with, or a project, I can't do a lot.
    But perhaps a recent example in another thread might be useful.
    Its quite simple, so won't fit what you're doing exactly, but it does contain a number of visual objects, that are connected together (essentially a chain) so that they twist and move together.
    The images are around 200 pixels wide, so the logic is that you drag from one end, it rotates around its center, and there is a "hitch" point at the other end where the next images is attached by its drag point.

    Perhaps it can be useful.
    It is in this thread, Post #6.

    In Post #3 of that thread is another example, but this time is not as related, as it is just an example showing the start of drawing an avionics instrument. The interesting part, I think, is that is has an interactive Step by Step mode that goes through the drawing process, explaining what the code is doing, and illustrates the point of view I take when interpreting how the drawing context is managed.
    That is, rather than thinking of the matrix as moving an object to 0,0 acting on it, and moving it back to where it was, I think of the drawing process as moving the coordinate system origin out to some point, and transforming the coordinate system and drawing the object always the same way (i.e. straight up), but it isn't drawn straight up because the coordinate system has been rotated.

    Both ways of viewing how the transformations work are valid interpretations and have the same result, I just find it easier when drawing multiple objects at different areas and rotations as viewing that from the objects perspective, the coordinate system never changes, (0,0) is always at the center of rotation of whatever part is being manipulated, it is just like you're constantly moving the graph paper that your object is draw on around, and rotating and or scaling that.

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

    Re: Rotating Linked Images

    Don't know if you are digesting the previous examples, but I thought this would be entertaining enough, that I've worked up another example. Didn't quite finish all the parts (the feet are the last parts I planned for the example, but I've got some other work to do, so will pack this up as is.

    To start working on the example, I wanted to find a suitable image to work with I did a search on Paper Puppets, the cardboard figures with a rivet at the joints where you can rotate the parts, and found a site which had a good size image with the rivet points identified, so captured it and worked in paint to pull it into pieces, and get the offset numbers for the various points.

    The reference point (in this context) of an image is the pixel offset (x,y) in the bitmap that you want to align with a joint, which the image will rotate around. The joint of a part is the pixel offset (x,y) relative to the reference point of that part, where the next part's reference point is to be located.
    So, a hand which is at the end of a series of connect points will have a reference point (its point to be attached), but no joint point, as there is not a subsequent part to be attached to the hand. (the class does have a joint point, but it isn't set to anything, and the fact that there is not a "next part" object reference in the class is what indicates this is the end of the connected parts.

    So, the parts are linked reference point to joint in a hierarchy.
    The top level is the body, and the reference point for the body is an (x,y) offset somewhere near the center of the body. The reference point is the point that specifies the objects position, and is what the object rotates around if you want that.

    The Joints that are part of the body (left,right shoulder (I misspelled shoulder throughout my code and notes) and left and right hips) are defined relative to the reference point, so the left side coordinates have a negative X offset, and the shoulders, which are above the bodies reference point have a negative value.

    So, the method I use to draw the body follow this outline
    Code:
    Paint
      TransLate to Center of body Pin
      Call DrawBody 
        Rotate body
        Save Matrix
        TransLate to LeftSholder Pin
        Call LeftShoulder
          Rotate Sholder
          Save Matrix
          Tranlate to Left Arm Pin
          Call LeftArm
            Rotate LeftArm
            Save Matrix
            Translate to Hand Pin
            Call LeftHand
              Rotate LeftHand
              Draw Hand
              Return
            Restore Matrix
            Draw LeftArm
            Return
          Restore Matrix
          Draw Sholder
          Return
        Restore Matrix
        Translate to RightSholder Pin
        Call RightSholder
          ....
        Restore Matrix
        Translate to LeftHip Pin
        Call LeftHip
          ...
        Restore Matrix
        Translate to RightHip Pin
        Call RightHip
    Note that in this example I draw in order from the hand back to the body. This is because that is the way paper puppets are put together, overlapping from center to extremities.
    In actual practice, there would probably be a more involved drawing order, with parts of the main body probably drawn at different times in the process, likely with some clipping areas, so that the arms can show in front of the body, and not go behind the body because of the drawing order.

    Used a couple of classes to reduce redundant code, one that supports a single chain of parts (hooked reference point to joint, with a reference to the next part in the chain.
    The other is the main body part, which has a list of parts that are linked to it. (which I guess technically is using a small class within the class to tie those joints to the first part of a chain (possibly) of parts.

    Before I wrote any code, once I selected the picture, I wrote down some notes about the offsets in the picture also what things I figured I wanted in a class to support the task, and an outline of the logic flow when painting (which I copied and pasted above).
    I'll include the notes file as well, although there shouldn't be much to glean from that at this point.

    p.s. I forgot to mention you can drag with the left mouse on the picturebox to re-position the figure. Dragging left or right with the right mouse will change the size of the drawing.
    Attached Files Attached Files
    Last edited by passel; Jan 24th, 2019 at 01:52 PM.

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

    Re: Rotating Linked Images

    For no particular reason, I thought I'd create a doppelganger puppet, (a mini-me) for a little entertainment, using the existing parts defined for the first puppet. Since they use the same parts, they should move in synchronization when the parts are manipulated.
    So in the declaration's area where the first puppet is created, create a second one, but locate it further to the right and up a bit (since it will be smaller) from the other.
    Code:
      Private aPuppet As New Puppet(My.Resources.body, New Point(200, 300), New Point(65, 247))    '(image, location, rotation point)
    
      'For extra entertainment, lets create a doppleganger puppet to mimic the first, (but will make it smaller later)
      Private puppetB As New Puppet(My.Resources.body, New Point(600, 150), New Point(65, 247))    '(image, location, rotation point)
    In the Form_Load event handler, link the same parts to it by copying the code from the first (Changed to using a 'With clause' to make copy easier). Also scale the second puppet to 1/2 size.
    Code:
      Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        With aPuppet
          .Add(LeftUpperArm, New Point(-39, -83))
          .Add(rightUpperArm, New Point(37, -83))
          .Add(leftUpperLeg, New Point(-28, 74))
          .Add(rightUpperLeg, New Point(29, 74))
        End With
    
        With puppetB
          .Add(LeftUpperArm, New Point(-39, -83))
          .Add(rightUpperArm, New Point(37, -83))
          .Add(leftUpperLeg, New Point(-28, 74))
          .Add(rightUpperLeg, New Point(29, 74))
        End With
        puppetB.Scale = 0.5
      End Sub
    Then add the code to draw the second puppet in the Paint event, resetting the drawing matrix to its default value between puppet drawings
    Code:
      Private Sub PictureBox1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        With aPuppet
          e.Graphics.TranslateTransform(.Location.X, .Location.Y)
          .Draw(e.Graphics)
        End With
    
        e.Graphics.ResetTransform()
    
        With puppetB
          e.Graphics.TranslateTransform(.Location.X, .Location.Y)
          .Draw(e.Graphics)
        End With
      End Sub
    That's it. Could actually use an array and create a bunch of puppets all moving in sync with the control inputs, but not much point in that.

    p.s. .... but, what the hay.
    Code:
      Private gang(8) As Puppet
    
      Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        With aPuppet
          .Add(LeftUpperArm, New Point(-39, -83))
          .Add(rightUpperArm, New Point(37, -83))
          .Add(leftUpperLeg, New Point(-28, 74))
          .Add(rightUpperLeg, New Point(29, 74))
        End With
    
        With puppetB
          .Add(LeftUpperArm, New Point(-39, -83))
          .Add(rightUpperArm, New Point(37, -83))
          .Add(leftUpperLeg, New Point(-28, 74))
          .Add(rightUpperLeg, New Point(29, 74))
        End With
        puppetB.Scale = 0.5
    
        Dim b As Bitmap = New Bitmap(My.Resources.body)
        Dim rp As Point = New Point(65, 247)
        Dim p As Integer
        For y As Integer = 0 To 2
          For x As Integer = 0 To 2
            p = y * 3 + x
            gang(p) = New Puppet(b, New Point(400 + x * 75, 300 + y * 150), rp)
            With gang(p)
              .Add(LeftUpperArm, New Point(-39, -83))
              .Add(rightUpperArm, New Point(37, -83))
              .Add(leftUpperLeg, New Point(-28, 74))
              .Add(rightUpperLeg, New Point(29, 74))
              .Scale = 0.25
            End With
          Next
        Next
      End Sub
    
    '...
      Private Sub PictureBox1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        With aPuppet
          e.Graphics.TranslateTransform(.Location.X, .Location.Y)
          .Draw(e.Graphics)
        End With
    
        e.Graphics.ResetTransform()
    
        With puppetB
          e.Graphics.TranslateTransform(.Location.X, .Location.Y)
          .Draw(e.Graphics)
        End With
    
        For Each p As Puppet In gang
          e.Graphics.ResetTransform()
          e.Graphics.TranslateTransform(p.Location.X, p.Location.Y)
          p.Draw(e.Graphics)
        Next
      End Sub
    Last edited by passel; Jun 22nd, 2016 at 03:28 PM.

  9. #9

    Thread Starter
    Fanatic Member sridharavijay's Avatar
    Join Date
    Sep 2002
    Location
    http://www.vijaysridhara.in
    Posts
    589

    Re: Rotating Linked Images

    Quote Originally Posted by passel View Post
    Don't know if you are digesting the previous examples, but I thought this would be entertaining enough, that I've worked up another example. Didn't quite finish all the parts (the feet are the last parts I planned for the example, but I've got some other work to do, so will pack this up as is.

    To start working on the example, I wanted to find a suitable image to work with I did a search on Paper Puppets, the cardboard figures with a rivet at the joints where you can rotate the parts, and found a site which had a good size image with the rivet points identified, so captured it and worked in paint to pull it into pieces, and get the offset numbers for the various points.

    The reference point (in this context) of an image is the pixel offset (x,y) in the bitmap that you want to align with a joint, which the image will rotate around. The joint of a part is the pixel offset (x,y) relative to the reference point of that part, where the next part's reference point is to be located.
    So, a had which is at the end of a series of connect points will have a reference point (its point to be attached), but no joint point, as there is not a subsequent part to be attached to the hand. (the class does have a joint point, but it isn't set to anything, and the fact that there is not a "next part" object reference in the class is what indicates this is the end of the connected parts.

    So, the parts are linked reference point to joint in a hierarchy.
    The top level is the body, and the reference point for the body is an (x,y) offset somewhere near the center of the body. The reference point is the point that specifies the objects position, and is what the object rotates around if you want that.

    The Joints that are part of the body (left,right shoulder (I misspelled shoulder throughout my code and notes) and left and right hips) are defined relative to the reference point, so the left side coordinates have a negative X offset, and the shoulders, which are above the bodies reference point have a negative value.

    So, the method I use to draw the body follow this outline
    Code:
    Paint
      TransLate to Center of body Pin
      Call DrawBody 
        Rotate body
        Save Matrix
        TransLate to LeftSholder Pin
        Call LeftShoulder
          Rotate Sholder
          Save Matrix
          Tranlate to Left Arm Pin
          Call LeftArm
            Rotate LeftArm
            Save Matrix
            Translate to Hand Pin
            Call LeftHand
              Rotate LeftHand
              Draw Hand
              Return
            Restore Matrix
            Draw LeftArm
            Return
          Restore Matrix
          Draw Sholder
          Return
        Restore Matrix
        Translate to RightSholder Pin
        Call RightSholder
          ....
        Restore Matrix
        Translate to LeftHip Pin
        Call LeftHip
          ...
        Restore Matrix
        Translate to RightHip Pin
        Call RightHip
    Note that in this example I draw in order from the hand back to the body. This is because that is the way paper puppets are put together, overlapping from center to extremities.
    In actual practice, there would probably be a more involved drawing order, with parts of the main body probably drawn at different times in the process, likely with some clipping areas, so that the arms can show in front of the body, and not go behind the body because of the drawing order.

    Used a couple of classes to reduce redundant code, one that supports a single chain of parts (hooked reference point to joint, with a reference to the next part in the chain.
    The other is the main body part, which has a list of parts that are linked to it. (which I guess technically is using a small class within the class to tie those joints to the first part of a chain (possibly) of parts.

    Before I wrote any code, once I selected the picture, I wrote down some notes about the offsets in the picture also what things I figured I wanted in a class to support the task, and an outline of the logic flow when painting (which I copied and pasted above).
    I'll include the notes file as well, although there shouldn't be much to glean from that at this point.

    p.s. I forgot to mention you can drag with the left mouse on the picturebox to re-position the figure. Dragging left or right with the right mouse will change the size of the drawing.
    This is awesome... The first example, though I understood drag and hitch points, I couldn't really make use of them in my piece of work. The second example you gave exactly suits my requirement. I will look into the code and keep you posted, how it worked for me. I am sure it would work 100% for me. Thank you so much.

    There is a little more extension on the Q, how do you arrive at the Ref Point and Join point, dynamically?
    Last edited by sridharavijay; Jun 23rd, 2016 at 03:36 AM.

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