It is currently Fri Aug 23, 2019 12:43 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: Rotation to angle / to position?
PostPosted: Tue Jul 23, 2019 11:09 am 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 353
Location: France
Hi,

Code:
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.


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 7:39 am 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 353
Location: France
Hmm I guess my questions are dull :)

This is as far as I can get:

Code:
  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:
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)


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 9:56 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 10:06 am
Posts: 774
Location: Denmark
Code:
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)

_________________
“Tell me and I forget. Teach me and I remember. Involve me and I learn.”
— Benjamin Franklin
Current configurations: Windows 7/10, Intel 6800K, Gtx 970, 32 gb ram.


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 10:32 am 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 353
Location: France
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 :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 11:32 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 10:06 am
Posts: 774
Location: Denmark
ahhh..okay. My bad.
May I suggest, that you skip the spriterotation and
do something like this?
Left click to reposition.
Code:


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)

_________________
“Tell me and I forget. Teach me and I remember. Involve me and I learn.”
— Benjamin Franklin
Current configurations: Windows 7/10, Intel 6800K, Gtx 970, 32 gb ram.


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 1:14 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 353
Location: France
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. :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 2:19 pm 
Offline
Addict
Addict

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 1021
Location: right here
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:

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:

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)


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 3:54 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 353
Location: France
#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:
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.


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 4:59 pm 
Offline
Addict
Addict

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 1021
Location: right here
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:
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:
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:
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:
... (Cos(Radian(a)) * (pvx+10))
... (Sin(Radian(a)) * (pvx+10))


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 6:29 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 353
Location: France
And to answer my third question about orientation towards a destination:

Code:
Degree(ATan2((position\x - destination\x), (position\y - destination\y)))


Top
 Profile  
Reply with quote  
 Post subject: Re: Rotation to angle / to position?
PostPosted: Thu Jul 25, 2019 6:47 pm 
Offline
Addict
Addict
User avatar

Joined: Mon Jul 25, 2005 3:51 pm
Posts: 3568
Location: Utah, USA
If these lines are modified the results are closer:
Code:
;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

_________________
Image


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye