Home > front end >  2D rotation of an object along a custom axis
2D rotation of an object along a custom axis

Time:01-31

I'm trying to wrap my head around how to rotate a 2d object around any axis, which could be anywhere, including outside of the shape itself.

The langage I happen to use for this is VBA, but any pseudocode will do.

I am looking for a function similar to this:

function rotate(obj, axisX, axisY, angle)
    obj.rotate(angle)
    obj.x = ?
    obj.y = ?

I'm not sure if that is relevant, but for the sake of simplicity, we can assume the shape is a rectangle.

And the x, y coordinates once the shape is rotated would be that of a square containing the rotated shape.

CodePudding user response:

The common approach to this to divide the operation in three basic steps:

  1. move the object to the local space (also called object space)

  2. rotate around the origin

  3. move the object back (also called world space)

     function rotate(obj, axisX, axisY, angle) {
         // 1.
         obj.x -= axisX
         obj.y -= axisY
    
         // 2.
         obj.rotate(angle)
    
         // 3.
         obj.x  = axisX
         obj.y  = axisY
     }
    

Edit some notes on obj.rotate: the approach assumes that the rotate function rotates globally (world space) that is, if the object is not at the origin, it will be rotated in a orbit like fashion. But if rotate rotates the object locally (object space) the object will always be rotated around its center, regardless where it is in world space. In this case, you need to additionally compute the new position yourself (but with the same principle):

ox = obj.x - axisX
oy = obj.y - axisY

// apply 2D rotation matrix
obj.x = ox * cos(angle) - oy * sin(angle)
obj.y = ox * sin(angle)   oy * cos(angle)

obj.x  = axisX
obj.y  = axisY

CodePudding user response:

Well I can see we already have the general answer, but I had a bit of fun making this so I'll post it anyway.
It shows how all the concepts come together so Might help someone.

Option Explicit
Type ObjLocData
    X As Long
    Y As Long
End Type
Sub Rotate_Object_About_Axis()

    Dim RotObj As Shape
    Dim RotLoc1 As ObjLocData
    Dim RotLoc2 As ObjLocData
    Dim AxisObj As Shape
    Dim AxisLoc As ObjLocData
    Dim R_Rad As Double
    Dim Pi As Double
    
    R_Rad = 0.1
    Pi = 3.14159
    
    Set AxisObj = ActiveSheet.Shapes("AxisObj")
    AxisLoc = ObjectLocation(AxisObj)
    Set RotObj = ActiveSheet.Shapes("RotObj")
    RotLoc1 = ObjectLocation(RotObj)
    Debug.Print AxisLoc.X
    
    RotLoc2 = RotateCoordinates(AxisLoc.X, AxisLoc.Y, RotLoc1.X, RotLoc1.Y, R_Rad)
    With RotObj
        .Left = RotLoc2.X - (.Width / 2)
        .Top = RotLoc2.Y - (.Height / 2)
        .Rotation = .Rotation   (R_Rad * 360 / (2 * Pi))
    End With
    
End Sub
Function ObjectLocation(Shp As Object) As ObjLocData
    ObjectLocation.X = Shp.Left   (Shp.Width / 2)
    ObjectLocation.Y = Shp.Top   (Shp.Height / 2)
End Function
Function RotateCoordinates(Xa, Ya, X, Y, R) As ObjLocData
    RotateCoordinates.X = ((X - Xa) * Cos(R)) - ((Y - Ya) * Sin(R))   Xa
    RotateCoordinates.Y = ((X - Xa) * Sin(R))   ((Y - Ya) * Cos(R))   Ya
End Function
'Location Formulas
'X'=(x-p)cos(?)-(y-q)sin(?) p,
'y'=(x-p)sin(?) (y-q)cos(?) q.

Example:
enter image description here
enter image description here
enter image description here

  • Related