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