Rotate sprite around pivot

Advanced game related topics
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Rotate sprite around pivot

Post by Joubarbe »

Hey,

As far as I know, there's no native way to rotate around a given point (a "pivot"). And because my maths are terrible, I'd like to know what exactly should I do to do that. When the pivot is at SpriteWidth()/2 and SpriteHeight()/2, RotateSprite() is enough because it rotates around the center of the sprite, but not when I change it.

I searched on a few website, but everything is bound to a language that include native functions to do this kind of stuff. Maybe I missed a PB function?
User avatar
Demivec
Addict
Addict
Posts: 4085
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Rotate sprite around pivot

Post by Demivec »

Joubarbe wrote:When the pivot is at SpriteWidth()/2 and SpriteHeight()/2, RotateSprite() is enough because it rotates around the center of the sprite, but not when I change it.
RotateSprite() rotates around the upper left corner, not the center point as you mentioned.

What you would use is TransformSprite().

There's more than a few examples on the forum, here's one:
http://www.purebasic.fr/english/viewtopic.php?f=13&t=63579&p=473711#p473711
Last edited by Demivec on Tue Nov 29, 2016 1:53 am, edited 1 time in total.
User avatar
falsam
Enthusiast
Enthusiast
Posts: 630
Joined: Wed Sep 21, 2011 9:11 am
Location: France
Contact:

Re: Rotate sprite around pivot

Post by falsam »

As far as I know, there's no native way to rotate around a given point (a "pivot")
It is true, there is no native function to change the anchor point of a sprite.

A solution with this code

Code: Select all

Structure newSprite
  id.i
  x.f
  y.f
  anchorX.f
  anchorY.f
  angle.f
  radius.f
EndStructure

Declare AnchorSprite(*sprite.newSprite, x.f, y.f)
Declare RotateSpriteAroundAnchor(*sprite.newSprite, angle.f, initialAngle.f = 0, calcSlope.b = #True)

InitSprite() : InitKeyboard()

OpenWindow(0, 0, 0, 800, 600, "Rotate Around Anchor", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)

;Setup Sprite
Global sprite.newSprite\id = CreateSprite(-1, 64, 64)
With sprite
  StartDrawing(SpriteOutput(\id))
  Box(0, 0, 64, 64, RGB(255, 215, 0))
  Box(12, 55, 40, 2, RGB(0, 0, 0))
  Box(2, 60, 60, 2, RGB(0, 0, 0))
  StopDrawing()
  
  ;Setup position
  \x = 400
  \y = 100
EndWith
AnchorSprite(sprite, 400, 300)

;Render
Repeat   
  Repeat
    Event = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
    EndSelect  
  Until Event=0
  
  ClearScreen(RGB(184, 134, 11))
    
  With sprite
    DisplaySprite(\id, \x, \y)
    RotateSpriteAroundAnchor(sprite, 0.5)
  EndWith
  
  ExamineKeyboard()  
  FlipBuffers()  
Until KeyboardPushed(#PB_Key_Escape)

;Setup Sprite Anchor
Procedure AnchorSprite(*sprite.newSprite, x.f, y.f)
  Protected dx.d, dy.d
  With *sprite
    \anchorX = x
    \anchorY = y
    dx.d = \x - \anchorX  ;Horizontal distance
    dy.d = \y - \anchorY  ;Vertical Distance
    \radius = (Sqr(dx*dx + dy*dy)) ;Distance between anchor and sprite position
    \angle = ATan2((\x - \anchorX), (\y - \anchorY) ) * 180 / #PI ;Angle between anchor and sprite position
  EndWith
EndProcedure

;Rotate sprite around anchor 
Procedure RotateSpriteAroundAnchor(*sprite.newSprite, angle.f, initialAngle.f = 0, calcSlope.b = #True)  
  With *sprite
    If \angle = 360 : \angle = 0 : EndIf
    \angle + angle
    \x = \anchorX + \radius * Cos(\angle * #PI / 180)
    \y = \anchorY + \radius * Sin(\angle * #PI / 180)
    If calcSlope = #True
      RotateSprite(\id, ATan2((\x - \anchorX), (\y - \anchorY) ) * 180 / #PI + initialAngle, #PB_Absolute)
    EndIf
  EndWith
EndProcedure

➽ Windows 11 64-bit - PB 6.0 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti

Sorry for my bad english and the Dunning–Kruger effect.
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Rotate sprite around pivot

Post by Joubarbe »

Thanks!
Post Reply