Rotation to angle / to position?

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

Rotation to angle / to position?

Post by Joubarbe »

Hi,

Code: Select all

EnableExplicit

#screen_width = 1920
#screen_height = 1080
#app_title = "TITLE"

Define sprite_mouse.i, sprite_fps.i, sprite_line.i, sprite_dot.i
Define frame.i, frame_refresh, frame_time.i, event.i
Global delta.d

InitKeyboard() : InitMouse() : InitSprite()

OpenWindow(0, 0, 0, #screen_width, #screen_height, #app_title, #PB_Window_BorderLess | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #screen_width, #screen_height, #False, 0, 0, #PB_Screen_SmartSynchronization)

sprite_mouse = CreateSprite(#PB_Any, 7, 7)
StartDrawing(SpriteOutput(sprite_mouse))
Box(0, 0, OutputWidth(), OutputHeight(), #Black)
Box(0, 0, OutputWidth() - 2, OutputHeight() - 2, #White)
StopDrawing()

sprite_fps = CreateSprite(#PB_Any, 40, 20)

sprite_dot = CreateSprite(#PB_Any, 2, 2)
StartDrawing(SpriteOutput(sprite_dot))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()

sprite_line = CreateSprite(#PB_Any, 2, 100)
StartDrawing(SpriteOutput(sprite_line))
Box(0, 0, OutputWidth(), OutputHeight(), #White)
StopDrawing()

MouseLocate(DesktopMouseX(), DesktopMouseY())

Repeat
  Repeat
    event.i = WindowEvent()
    If event = #PB_Event_CloseWindow : Break 2 : EndIf
  Until event = 0
  
  ClearScreen(RGB(50, 65, 70))
  
  ExamineKeyboard() : ExamineMouse()
  MouseLocate(DesktopMouseX(), DesktopMouseY())
  
  DisplaySprite(sprite_line, #screen_width / 2, #screen_height / 2)
  RotateSprite(sprite_line, 1, #PB_Relative)
  DisplaySprite(sprite_dot, #screen_width / 2, #screen_height / 2)

  
  DisplaySprite(sprite_fps, 0, 0)
  DisplaySprite(sprite_mouse, MouseX(), MouseY())
  
  ; FPS and Delta Time
  frame + 1
  If ElapsedMilliseconds() > frame_refresh
    StartDrawing(SpriteOutput(sprite_fps))
    DrawText(0, 0, "fps:" + frame)
    StopDrawing()
    frame_refresh = ElapsedMilliseconds() + 1000
    frame = 0
  EndIf
  delta = (ElapsedMilliseconds() - frame_time) / 1000
  frame_time = ElapsedMilliseconds()
  
  FlipBuffers()   
Until KeyboardReleased(#PB_Key_Escape)
I'd like to reposition my line on the red dot after every rotation. In other words, I would like the line to rotate around the dot. I read a few threads, and they all mention that the default behavior of RotateSprite() is to rotate around the top left 0,0. It's obviously not the case.

1/ Am I missing something, or did PureBasic change that behavior?
2/ In my project, I'm always using #PB_Absolute with an "angle" variable, and I don't need to do the rotation in real time. I would simply do Rotate(*sprite, 45), and boom, the line would have a 45° and the top would be on the red dot. Being terrible at maths, I would really appreciate the magic formula for this :)
3/ Also, a bonus question: is there a function that gives the angle to a point? I thought there was something like that in the Sprite library, but I'm maybe confusing with another language. My goal would be to have: RotateTo(*sprite, x.d, y.d).

Thanks.
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Rotation to angle / to position?

Post by Joubarbe »

Hmm I guess my questions are dull :)

This is as far as I can get:

Code: Select all

  a = 45
  ptx = #screen_width / 2
  pvx = ptx + SpriteWidth(sprite_line) / 2
  pty = #screen_height / 2
  pvy = pty + SpriteHeight(sprite_line) / 2
  x = (ptx - pvx) * Cos(Radian(a)) + (pty - pvy) * Sin(Radian(a)) + pvx
  y = (pty - pvy) * Cos(Radian(a)) + (ptx - pvx) * Sin(Radian(a)) + pvy
  DisplaySprite(sprite_line, x, y)
  RotateSprite(sprite_line, a, #PB_Absolute)
  DisplaySprite(sprite_dot, #screen_width / 2, #screen_height / 2)
I don't get why there is an offset on Y. X seems good.

Full code:

Code: Select all

EnableExplicit

#screen_width = 1920
#screen_height = 1080
#app_title = "TITLE"

Define sprite_mouse.i, sprite_fps.i, sprite_line.i, sprite_dot.i
Define frame.i, frame_refresh, frame_time.i, event.i, x.i, y.i, ptx.i, pty.i, pvx.i, pvy.i, a.i
Global delta.d

InitKeyboard() : InitMouse() : InitSprite()

OpenWindow(0, 0, 0, #screen_width, #screen_height, #app_title, #PB_Window_BorderLess | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #screen_width, #screen_height, #False, 0, 0, #PB_Screen_SmartSynchronization)

sprite_mouse = CreateSprite(#PB_Any, 7, 7)
StartDrawing(SpriteOutput(sprite_mouse))
Box(0, 0, OutputWidth(), OutputHeight(), #Black)
Box(0, 0, OutputWidth() - 2, OutputHeight() - 2, #White)
StopDrawing()

sprite_fps = CreateSprite(#PB_Any, 40, 20)

sprite_dot = CreateSprite(#PB_Any, 2, 2)
StartDrawing(SpriteOutput(sprite_dot))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()

sprite_line = CreateSprite(#PB_Any, 2, 100)
StartDrawing(SpriteOutput(sprite_line))
Box(0, 0, OutputWidth(), OutputHeight(), #White)
StopDrawing()

MouseLocate(DesktopMouseX(), DesktopMouseY())

Repeat
  Repeat
    event.i = WindowEvent()
    If event = #PB_Event_CloseWindow : Break 2 : EndIf
  Until event = 0
  
  ClearScreen(RGB(50, 65, 70))
  
  ExamineKeyboard() : ExamineMouse()
  MouseLocate(DesktopMouseX(), DesktopMouseY())
  
  a = 45
  ptx = #screen_width / 2
  pvx = ptx + SpriteWidth(sprite_line) / 2
  pty = #screen_height / 2
  pvy = pty + SpriteHeight(sprite_line) / 2
  x = (ptx - pvx) * Cos(Radian(a)) + (pty - pvy) * Sin(Radian(a)) + pvx
  y = (pty - pvy) * Cos(Radian(a)) + (ptx - pvx) * Sin(Radian(a)) + pvy
  DisplaySprite(sprite_line, x, y)
  RotateSprite(sprite_line, a, #PB_Absolute)
  DisplaySprite(sprite_dot, #screen_width / 2, #screen_height / 2)

  
  DisplaySprite(sprite_fps, 0, 0)
  DisplaySprite(sprite_mouse, MouseX(), MouseY())
  
  ; FPS and Delta Time
  frame + 1
  If ElapsedMilliseconds() > frame_refresh
    StartDrawing(SpriteOutput(sprite_fps))
    DrawText(0, 0, "fps:" + frame)
    StopDrawing()
    frame_refresh = ElapsedMilliseconds() + 1000
    frame = 0
  EndIf
  delta = (ElapsedMilliseconds() - frame_time) / 1000
  frame_time = ElapsedMilliseconds()
  
  FlipBuffers()   
Until KeyboardReleased(#PB_Key_Escape)
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Rotation to angle / to position?

Post by DK_PETER »

Code: Select all

EnableExplicit
Structure vector2D
  x.f
  y.f
EndStructure

Declare OrbitCalc2D(*ReturnVec.vector2D, CenterX.f, CenterY.f, AngleX.f, AngleY.f, Radius.i)
Global spos.vector2D, ro.f = 0.0

Procedure OrbitCalc2D(*ReturnVec.vector2D, CenterX.f, CenterY.f, AngleX.f, AngleY.f, Radius.i)
  *ReturnVec\X = CenterX + Radius*Cos(AngleY)*Cos(AngleX)
  *ReturnVec\Y = CenterY + Radius*Sin(AngleX)
EndProcedure

#screen_width = 1920
#screen_height = 1080
#app_title = "TITLE"

Define sprite_mouse.i, sprite_fps.i, sprite_line.i, sprite_dot.i
Define frame.i, frame_refresh, frame_time.i, event.i
Global delta.d

InitKeyboard() : InitMouse() : InitSprite()

OpenWindow(0, 0, 0, #screen_width, #screen_height, #app_title, #PB_Window_BorderLess | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #screen_width, #screen_height, #False, 0, 0, #PB_Screen_SmartSynchronization)

sprite_mouse = CreateSprite(#PB_Any, 7, 7)
StartDrawing(SpriteOutput(sprite_mouse))
Box(0, 0, OutputWidth(), OutputHeight(), #Black)
Box(0, 0, OutputWidth() - 2, OutputHeight() - 2, #White)
StopDrawing()

sprite_fps = CreateSprite(#PB_Any, 40, 20)

sprite_dot = CreateSprite(#PB_Any, 2, 2)
StartDrawing(SpriteOutput(sprite_dot))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()

sprite_line = CreateSprite(#PB_Any, 2, 100)
StartDrawing(SpriteOutput(sprite_line))
Box(0, 0, OutputWidth(), OutputHeight(), #White)
StopDrawing()

MouseLocate(DesktopMouseX(), DesktopMouseY())


Repeat
  Repeat
    event.i = WindowEvent()
    If event = #PB_Event_CloseWindow : Break 2 : EndIf
  Until event = 0
  ro + 0.01
  If ro > 359 : ro = 0 : EndIf
  ClearScreen(RGB(50, 65, 70))
  
  ExamineKeyboard() : ExamineMouse()
  MouseLocate(DesktopMouseX(), DesktopMouseY())
  
  OrbitCalc2D(spos, (#screen_width / 2) - (SpriteWidth(sprite_line)/2) , (#screen_height / 2) - (SpriteHeight(sprite_line)/2),  ro, 0, 120)
  DisplaySprite(sprite_line, spos\x, spos\y)
  RotateSprite(sprite_line, 1, #PB_Relative)
  DisplaySprite(sprite_dot, #screen_width / 2, #screen_height / 2)
  
  DisplaySprite(sprite_fps, 0, 0)
  DisplaySprite(sprite_mouse, MouseX(), MouseY())
  
  ; FPS and Delta Time
  frame + 1
  If ElapsedMilliseconds() > frame_refresh
    StartDrawing(SpriteOutput(sprite_fps))
    DrawText(0, 0, "fps:" + frame)
    StopDrawing()
    frame_refresh = ElapsedMilliseconds() + 1000
    frame = 0
  EndIf
  delta = (ElapsedMilliseconds() - frame_time) / 1000
  frame_time = ElapsedMilliseconds()
  
  FlipBuffers()   
Until KeyboardReleased(#PB_Key_Escape)
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Rotation to angle / to position?

Post by Joubarbe »

Uhh thank you for your answer, but this is not what I'm trying to do. What I'd like is to rotate, then have the top point of the line on the red dot. In my previous post, I'm not far from that result.

Or maybe it's me not understanding your function :)
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Rotation to angle / to position?

Post by DK_PETER »

ahhh..okay. My bad.
May I suggest, that you skip the spriterotation and
do something like this?
Left click to reposition.

Code: Select all



InitSprite()
InitKeyboard()
InitMouse()

Structure Vector2D
  x.f
  y.f
EndStructure
Global v.Vector2D

Structure SpriteDat
  id.i
  p.Vector2D
EndStructure
Global Spr.SpriteDat, dot.SpriteDat, r.i = 0

Procedure EndPosition(*v.SpriteDat, Degree.i)
  Protected cDgr = 360 - degree + 180
  *v\p\x = Sin(cDgr * (2 * #PI / 360))
  *v\p\y = Cos(cDgr * (2 * #PI / 360))
EndProcedure


OpenWindow(0, 0, 0, 1024, 768, "Clock Hand", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768)

Spr\id = CreateSprite(#PB_Any, 200, 200)
StartDrawing(SpriteOutput(Spr\id))
Box(0, 0, 100, 100, 0)
StopDrawing()
TransparentSpriteColor(Spr\id, 0)

dot\id = CreateSprite(#PB_Any, 10, 10)
StartDrawing(SpriteOutput(dot\id))
Circle(5, 5, 2, $FF00FF)
StopDrawing()
TransparentSpriteColor(dot\id, 0)

Repeat
  ClearScreen(0)
  Repeat : ev.i = WindowEvent() : Until ev = 0
    
  ExamineMouse()
  If MouseButton(#PB_MouseButton_Left) : dot\p\x = MouseX()-(SpriteWidth(Spr\id)/2) : dot\p\y = MouseY() - (SpriteHeight(Spr\id)/2) : EndIf
  DisplayTransparentSprite(dot\id, MouseX(), MouseY())
  
  If r + 1 > 359 : r = 0 : Else : r + 1 : EndIf
  EndPosition(Spr, r)

  StartDrawing(SpriteOutput(Spr\id))
  Box(0,0, OutputWidth(), OutputHeight(), $0)
  LineXY(OutputWidth()/2, OutputHeight()/2, (OutputWidth()/2) + (Spr\p\x * OutputWidth()/3), (OutputHeight()/2) + (Spr\p\y * OutputHeight()/3), $FFFFFF)
  StopDrawing()
  
  DisplayTransparentSprite(Spr\id, dot\p\x, dot\p\y)

  ExamineKeyboard()
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Rotation to angle / to position?

Post by Joubarbe »

No, that's exactly what I'm trying to avoid, redrawing... I need to recalculate new rotation values in real time on many objects, so I want only 1 rotate-able sprite.

That, really. :)
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Rotation to angle / to position?

Post by #NULL »

The easiest would be to simply use a larger sprite which contains the line going from its center, but that will render a lot of unused pixels. It subtracts half the sprite size (which is the center of rotation) from position 100,100, so that the actual line will start at 100,100:

Code: Select all


InitSprite()
InitKeyboard()

ww=800
wh=600

win=OpenWindow(#PB_Any, 50,100, ww,wh, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(win), 0,0, ww,wh, 1,0,0)

w = 200
h = 200
spr = CreateSprite(#PB_Any, w, h, #PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(spr))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, w, h, $00000000) ; clear
  Box(0, 0, w, h, $11ffffff) ; show size
  Box(w/2, h/2, 1, h/2, $ffffffff) ; line from center to bottom
StopDrawing()

Repeat
  ExamineKeyboard()
  
  Repeat
    event = WindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        quit = #True
    EndSelect
  Until Not event
  
  StartDrawing(ScreenOutput())
  Circle(100, 100, 5, $00aa00)
  StopDrawing()
  
  DisplayTransparentSprite(spr, 100-w/2, 100-h/2)
  RotateSprite(spr, 1, #PB_Relative)
  
  FlipBuffers()
  ClearScreen($333333)
Until quit Or KeyboardPushed(#PB_Key_Escape)
The next code uses only a sprite size of the line dimensions, also does the rotation center offset, but also uses an additional offset depending on the current rotation. Note that the rotation center offset uses w and h respectively, but the multiplication with the current rotation offset uses w in both cases because that's the larger dimension and so it's kind of the radius of the rotation.

Code: Select all


InitSprite()
InitKeyboard()

ww=800
wh=600

win=OpenWindow(#PB_Any, 50,100, ww,wh, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(win), 0,0, ww,wh, 1,0,0)

w = 100
h = 10
spr = CreateSprite(#PB_Any, w, h, #PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(spr))
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, w, h, $ffffffff) ; line
StopDrawing()

a.f = 0.0

Repeat
  ExamineKeyboard()
  
  Repeat
    event = WindowEvent()
    Select event
      Case #PB_Event_CloseWindow
        quit = #True
    EndSelect
  Until Not event
  
  StartDrawing(ScreenOutput())
  Circle(100, 100, 5, $00aa00)
  StopDrawing()
  
  ;DisplayTransparentSprite(spr, 100, 100)
  ;DisplayTransparentSprite(spr, 100 - w/2, 100 - h/2)
  DisplayTransparentSprite(spr, 
                           100 - w/2 + (Cos(Radian(a)) * w/2), 
                           100 - h/2 + (Sin(Radian(a)) * w/2) )
  
  a + 1.1
  RotateSprite(spr, a, #PB_Absolute)
  
  FlipBuffers()
  ClearScreen($333333)
Until quit Or KeyboardPushed(#PB_Key_Escape)
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Rotation to angle / to position?

Post by Joubarbe »

#NULL: thank you! Your second code works ok. At the end, the thing that was really confusing for me was that I was drawing a line with wider height than width...

Code: Select all

EnableExplicit

#screen_width = 600
#screen_height = 600
#app_title = "TITLE"

Define sprite_line.i, sprite_dot.i
Define event.i, x.i, y.i, ptx.i, pty.i, pvx.i, pvy.i, a.d

InitKeyboard() : InitMouse() : InitSprite()

OpenWindow(0, 0, 0, #screen_width, #screen_height, #app_title, #PB_Window_BorderLess | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #screen_width, #screen_height, #False, 0, 0, #PB_Screen_SmartSynchronization)

sprite_dot = CreateSprite(#PB_Any, 2, 2)
StartDrawing(SpriteOutput(sprite_dot))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()

; sprite_line = CreateSprite(#PB_Any, 2, 100)
; StartDrawing(SpriteOutput(sprite_line))
; Box(0, 0, OutputWidth(), OutputHeight(), #White)
; StopDrawing()

sprite_line = CreateSprite(#PB_Any, 100, 2)
StartDrawing(SpriteOutput(sprite_line))
Box(0, 0, OutputWidth(), OutputHeight(), #White)
StopDrawing()

MouseLocate(DesktopMouseX(), DesktopMouseY())

Repeat
  Repeat
    event.i = WindowEvent()
    If event = #PB_Event_CloseWindow : Break 2 : EndIf
  Until event = 0
  
  ClearScreen(RGB(50, 65, 70))
  
  ExamineKeyboard() : ExamineMouse()
  MouseLocate(DesktopMouseX(), DesktopMouseY())
  
  a + 1.1
  ptx = #screen_width / 2
  pty = #screen_height / 2
  pvx = SpriteWidth(sprite_line) / 2
  pvy = SpriteHeight(sprite_line) / 2
  x = ptx - pvx + (Cos(Radian(a)) * pvx)
  y = pty - pvy + (Sin(Radian(a)) * pvx)
  DisplaySprite(sprite_line, x, y)
  RotateSprite(sprite_line, a, #PB_Absolute)
  DisplaySprite(sprite_dot, ptx, pty)
  
  FlipBuffers()   
Until KeyboardReleased(#PB_Key_Escape)
Is there any way to make the rotation more precise? You can see in this example that at some angles, the line is pixels away from the red dot.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Rotation to angle / to position?

Post by #NULL »

I tried using floating point types for variables and literals. That doesn't really change anything but might be something to keep in mind.

Code: Select all

Define event.i, x.f, y.f, ptx.f, pty.f, pvx.f, pvy.f, a.d
  ptx = #screen_width / 2.0
  pty = #screen_height / 2.0
  pvx = SpriteWidth(sprite_line) / 2.0
  pvy = SpriteHeight(sprite_line) / 2.0
And I tried using odd sprite sizes so that the sprites have an actual pixel as center. And also drawing the dot with an offset according to its size

Code: Select all

sprite_dot = CreateSprite(#PB_Any, 3, 3)
sprite_line = CreateSprite(#PB_Any, 101, 3)

DisplaySprite(sprite_dot, ptx-1, pty-1)
I don't know how it could be made more precise without using subpixel rendering like the vector drawing library allows. But I'm not sure, maybe there is something odd about how purebasic does the rotation and the repositioning, or my formula isn't completely right. On the other hand it looks precise when testing with some fixed angles and with single pixel size line and dot:

Code: Select all

EnableExplicit

#screen_width = 600
#screen_height = 600
#app_title = "TITLE"

Define sprite_line.i, sprite_dot.i
Define event.i, x.f, y.f, ptx.f, pty.f, pvx.f, pvy.f, a.d

InitKeyboard() : InitMouse() : InitSprite()

OpenWindow(0, 0, 0, #screen_width, #screen_height, #app_title, #PB_Window_BorderLess | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, #screen_width, #screen_height, #False, 0, 0, #PB_Screen_SmartSynchronization)

sprite_dot = CreateSprite(#PB_Any, 1, 1)
StartDrawing(SpriteOutput(sprite_dot))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()

; sprite_line = CreateSprite(#PB_Any, 2, 100)
; StartDrawing(SpriteOutput(sprite_line))
; Box(0, 0, OutputWidth(), OutputHeight(), #White)
; StopDrawing()

sprite_line = CreateSprite(#PB_Any, 101, 1)
StartDrawing(SpriteOutput(sprite_line))
Box(0, 0, OutputWidth(), OutputHeight(), #White)
;Box(0, 1, 1, 1, #Red)
StopDrawing()

MouseLocate(DesktopMouseX(), DesktopMouseY())

Repeat
  Repeat
    event.i = WindowEvent()
    If event = #PB_Event_CloseWindow : Break 2 : EndIf
  Until event = 0
 
  ClearScreen(RGB(50, 65, 70))
 
  ExamineKeyboard() : ExamineMouse()
  MouseLocate(DesktopMouseX(), DesktopMouseY())
 
  ;a = 0
  ;a = 90
  a = 180
  ;a = 270
  ;a + 1;.1
  
  ptx = #screen_width / 2.0
  pty = #screen_height / 2.0
  pvx = SpriteWidth(sprite_line) / 2.0
  pvy = SpriteHeight(sprite_line) / 2.0
  x = ptx - pvx + (Cos(Radian(a)) * (pvx))
  y = pty - pvy + (Sin(Radian(a)) * (pvx))
  DisplaySprite(sprite_line, x, y)
  RotateSprite(sprite_line, a, #PB_Absolute)
  DisplaySprite(sprite_dot, ptx, pty)
 
  FlipBuffers()   
Until KeyboardReleased(#PB_Key_Escape)
Depending on what you are doing, you can also play with shifting the line away from (or backwards towards to / over) the dot to make the glitch less apparent

Code: Select all

... (Cos(Radian(a)) * (pvx+10))
... (Sin(Radian(a)) * (pvx+10))
Joubarbe
Enthusiast
Enthusiast
Posts: 555
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Rotation to angle / to position?

Post by Joubarbe »

And to answer my third question about orientation towards a destination:

Code: Select all

Degree(ATan2((position\x - destination\x), (position\y - destination\y)))
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Rotation to angle / to position?

Post by Demivec »

If these lines are modified the results are closer:

Code: Select all

;line 8
Define event.i, x.i, y.i, ptx.d, pty.d, pvx.d, pvy.d, a.d ;use doubles for intermediate calculations

;line 25
sprite_line = CreateSprite(#PB_Any, 101, 2) ;create and odd width for sprite to give it a 'center'

;lines 48 & 49
  x = Round((ptx + (SpriteWidth(sprite_dot) / 2)) - pvx + (Cos(Radian(a)) * pvx), #PB_Round_Nearest) ;include offset to center of dot and rounding
  y = Round((pty + (SpriteHeight(sprite_dot) / 2)) - pvy + (Sin(Radian(a)) * pvx), #PB_Round_Nearest) ;include offset to center of dot and rounding
Post Reply