none
Where is the Centre of Rotation of Shapes RRS feed

  • Question

  • Does anyone know where the centre of rotation is when using Shapes.Rotate? So far I have seen rotations apparently about the mid point, the location (50,50) and the end of the line. If you run the test code BZD902, the small line moving at the end is not rotating about any of these.
    I have only looked at lines so far; are other shapes treated similarly?
    Saturday, February 28, 2009 9:16 AM

Answers

  • The center of the rotation occurs at (obj.Left + obj.Width / 2; Obj.Top + Obj.Height / 2).
    It's in fact the middle point of the shape (in case you consider regular shapes like Rectangles or Ellipses).

    There's currently no way to modify this behaviour through Small Basic. If you want to specify another rotation point, you'll need to do some mathematics to apply (manually) a translation to the object.

    Fremy VB & C#
    Saturday, February 28, 2009 1:56 PM
  • FremyCompany,
        I presume you mean by client rectangle the rectangle that " holds" the line. This rectangle appears to originate at (0,0) and be just large enough to completely contain the line.

    Consider the following,

    Line1 = Shapes.AddLine(100, 100, 200, 200)  
    Line2 = Shapes.AddLine(100, 200, 200, 100)   
    GraphicsWindow.MouseDown = OnMouseDown   
      
    CurrentAngle = 0   
    Sub OnMouseDown   
        CurrentAngle = CurrentAngle + 15   
        Shapes.Rotate(Line1, CurrentAngle)   
        Shapes.Rotate(Line2, CurrentAngle)   
    EndSub  

    Both lines require the same enclosing rectangle and therefore share a common centre of rotation, but neither line rotates about its centre.

    A quick test shows that the same logic appears to apply to triangles, that the rotated object is the enclosing rectangle starting at (0,0) and just large enough to enclose the triangle. Does this seem right?
    Saturday, February 28, 2009 4:18 PM
  • moorem34,
        Try this which shows a triangle rotating as well. 

    GraphicsWindow.Show()
    vane = Shapes.AddLine(50,50,100,100)
    tri = Shapes.AddTriangle(40,60,60,40,100,100)
    Shapes.Move(vane, 300, 200)
    Shapes.Move(tri, 200, 300)
    Shapes.Rotate(vane,-45)
    Shapes.Rotate(tri, -45)
    Program.Delay(2000)

    For i = 0 To 360
      Shapes.Rotate(vane,i-45)
      Shapes.Rotate(tri,i-45)
      Program.Delay(100)
    EndFor

    • Edited by Stendec Saturday, February 28, 2009 6:07 PM Spelling correction
    • Marked as answer by FremyCompany [MSFT] Monday, August 3, 2009 10:43 AM
    Saturday, February 28, 2009 5:49 PM

All replies

  • The center of the rotation occurs at (obj.Left + obj.Width / 2; Obj.Top + Obj.Height / 2).
    It's in fact the middle point of the shape (in case you consider regular shapes like Rectangles or Ellipses).

    There's currently no way to modify this behaviour through Small Basic. If you want to specify another rotation point, you'll need to do some mathematics to apply (manually) a translation to the object.

    Fremy VB & C#
    Saturday, February 28, 2009 1:56 PM
  • Sorry, I didn't make myself clear. I was looking at lines and couldn't pin down their centre of rotation. Rectangles and ellipses do, as you say, rotate about their centre but lines do not. I have now looked at triangles and they too do not rotate about their centre.
    Saturday, February 28, 2009 3:35 PM
  • I've tested it, and it seems that, even for lines, the center of rotation is the center of the shape's client rectangle.

    Look at this :
        Line1 = Shapes.AddLine(0, 0, 100, 100)  
        GraphicsWindow.MouseDown = OnMouseDown  
     
        CurrentAngle = 0  
        Sub OnMouseDown  
          CurrentAngle = CurrentAngle + 15  
          Shapes.Rotate(Line1, CurrentAngle)  
        EndSub  
     


    The line rotates around his center.

    ==================================

    For triangle, it's a little more comlex, since the center of the client rectangle is not the center of the triangle. 

    ==================================

    Anyway, I looked at the Small Basic's compiler source code and my impressions were confirmed :

                    transform = New RotateTransform()  
                    Shapes._rotateTransformMap.Item(DirectCast(shapeName, String)) = transform  
                    transform.CenterX = (obj.RenderSize.Width / 2)  
                    transform.CenterY = (obj.RenderSize.Height / 2) 

    There only may have a problem when you changes the size of a shape, but it's not possible with the standard API.


    Fremy VB & C#
    Saturday, February 28, 2009 3:51 PM
  • FremyCompany,
        I presume you mean by client rectangle the rectangle that " holds" the line. This rectangle appears to originate at (0,0) and be just large enough to completely contain the line.

    Consider the following,

    Line1 = Shapes.AddLine(100, 100, 200, 200)  
    Line2 = Shapes.AddLine(100, 200, 200, 100)   
    GraphicsWindow.MouseDown = OnMouseDown   
      
    CurrentAngle = 0   
    Sub OnMouseDown   
        CurrentAngle = CurrentAngle + 15   
        Shapes.Rotate(Line1, CurrentAngle)   
        Shapes.Rotate(Line2, CurrentAngle)   
    EndSub  

    Both lines require the same enclosing rectangle and therefore share a common centre of rotation, but neither line rotates about its centre.

    A quick test shows that the same logic appears to apply to triangles, that the rotated object is the enclosing rectangle starting at (0,0) and just large enough to enclose the triangle. Does this seem right?
    Saturday, February 28, 2009 4:18 PM
  •  Stendec,

    I'm following your confusion on rotating "shapes" as I've been working on the same problem the last day and a half.

    It looks like Fremy has it nailed. The shape "rectangle" rotates about it's mid-point while lines appear to rotate about their origin-endpoint.

    The triangle I tried to rotate appeared to rotate about it's origin x,y coordinate. Not much use to a guy that's trying to make a "pointer" rotate in proportion to a wind vane/anemometer. I'm going back to draing a line in the graphics window, doing some trig based on the input of wind direction and drawing the appropriate line.

    moorem34
    Saturday, February 28, 2009 4:55 PM
  • moorem34,
        I think I've got it!
    The rotated object is the rectangle that starts at (0,0) and is just big enough to contain the line. So, add a line as a shape from (50,50) to (100,100). The centre of the rectangle that contains this line is (50,50) which is one end of the line. Now move this "rectangle" by moving the defined line using Shape.Move(). Remember, it is the imaginary rectangle that is being moved, so the co-ordinates of the point it is being moved to are those of the top left corner of the rectangle. Now if the line is rotated, the enclosing rectangle is rotated about its mid point and as this is one end of the line, the line rotates about its end. Phew!
    The following code shows the above description in action

    GraphicsWindow.Show()
    vane = Shapes.AddLine(50,50,100,100)
    Shapes.Move(vane, 300, 200)
    For i = 0 To 360
      Shapes.Rotate(vane,i)
      Program.Delay(100)
    EndFor

    So basically, for your weathervane pointer, create your Shape.Addline() such that one end of the line is at the centre of the enclosing rectangle. This is where you would decide how big to make it. Then move your line to where it is required, remembering that you are moving the line with respect to the origin (0,0) as this is where the top left of the enclosing rectangle is.
    • Edited by Stendec Saturday, February 28, 2009 5:32 PM Change values to make code clearer
    Saturday, February 28, 2009 5:29 PM
  • moorem34,
        Try this which shows a triangle rotating as well. 

    GraphicsWindow.Show()
    vane = Shapes.AddLine(50,50,100,100)
    tri = Shapes.AddTriangle(40,60,60,40,100,100)
    Shapes.Move(vane, 300, 200)
    Shapes.Move(tri, 200, 300)
    Shapes.Rotate(vane,-45)
    Shapes.Rotate(tri, -45)
    Program.Delay(2000)

    For i = 0 To 360
      Shapes.Rotate(vane,i-45)
      Shapes.Rotate(tri,i-45)
      Program.Delay(100)
    EndFor

    • Edited by Stendec Saturday, February 28, 2009 6:07 PM Spelling correction
    • Marked as answer by FremyCompany [MSFT] Monday, August 3, 2009 10:43 AM
    Saturday, February 28, 2009 5:49 PM
  • Stendec,

    "By Jove, I think he's got it!"

    I see what you're saying. I tried your code. Works as advertised. I even moved the origin of the line back to 0,0 (i.e. the upper left corner of our imaginary rectangle) and then moved the whole thing to center of graphics window and yep, it rotated by it's mid-point as expected. 

    So now I can do a line like the hand of a clock OR I can do a line rotating about it's mid point like the needle on a compass!

    Armed with this new knowledge, I'm going to see if I can place a triangle at the end of the line, then rotate both simultaneously. Will make a nice "pointer".

    thanks for your efforts

    mark

    Saturday, February 28, 2009 5:54 PM
  • Stendec,
     
    sorry...I didn't see your last reply to the thread.

    I'm going to use your triangle...that's even better yet.

    I like!

    moorem34
    Saturday, February 28, 2009 5:58 PM