Graphic: Curve throug points

Just starting out? Need help? Post your questions and find answers here.
acreis
Enthusiast
Enthusiast
Posts: 227
Joined: Fri Jun 01, 2012 12:20 am

Graphic: Curve throug points

Post by acreis »

Hi everyone,
I’m looking for a previously published PureBasic code (or example) that displays a graph with multiple points, where:
• A smooth curve passes through the points
• The points can be dragged interactively with the mouse
• The curve updates dynamically as the points move
Has anyone seen something like this shared before? I’d really appreciate a link or any hints on where to find it. Thanks in advance!
User avatar
STARGÅTE
Addict
Addict
Posts: 2255
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Graphic: Curve throug points

Post by STARGÅTE »

Probably you are looking for Spline curves or Bézier curve.
I just linked them to the forum search here.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4981
Joined: Sun Apr 12, 2009 6:27 am

Re: Graphic: Curve throug points

Post by RASHAD »

Hi acreis
Next code by NULL for sprite
Modified by RASHAD for windows
Take it as start :)

Code: Select all

ww=400
wh=400

hWin=OpenWindow(0, 0,0,ww,wh, "Spline",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CanvasGadget(0,0,0,ww,wh)
StartDrawing(CanvasOutput(0))
Box(0,0,ww,wh,#Black)
StopDrawing()

NewList p.POINT()               ; waypoints
x.f = ww/2                      ; object x
y.f = wh/2                      ; object y
angle.f                         ; object angle
speed_move.f = 0.4              ; movement speed
speed_rotate.f = speed_move*0.1 ; rotation speed
distance_tolerance.f = 3.0      ; pixel tolerance to reach waypoint
angle_needed.f                  ; angle from object to next waypoint
angle_diff.f                    ; rotation needed to point straight to next waypoint


Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      quit=1
      
    Case #WM_LBUTTONDOWN            ; add point
      LastElement(p())
      AddElement(p())
      p()\x = WindowMouseX(0)
      p()\y = WindowMouseY(0)
      
    Case #WM_RBUTTONDOWN             ; clear points
      ClearList(p())
      StartDrawing(CanvasOutput(0))
      Box(0,0,ww,wh,#Black)
      StopDrawing()
      
  EndSelect
  If ListSize(p())
    FirstElement(p())
    ; distance check only axis-based. you could use real distance calculation here if prefered
    If Abs(p()\x-x) < distance_tolerance And Abs(p()\y-y) < distance_tolerance
      DeleteElement(p())
    EndIf
  EndIf  
  
  If ListSize(p())
    FirstElement(p())
    angle_needed = ATan2( p()\x-x, p()\y-y )
    
    If angle_needed < 0
      angle_needed + 2*#PI ;
    EndIf
    
    If angle_needed > angle
      If (angle_needed-angle) < #PI
        angle_diff = (angle_needed - angle)
      Else
        angle_diff = -(2*#PI - (angle_needed - angle))
      EndIf
    Else
      If (angle-angle_needed) < #PI
        angle_diff = - (angle - angle_needed)
      Else
        angle_diff =  (2*#PI - (angle - angle_needed))
      EndIf
    EndIf
    
    angle + angle_diff*speed_rotate
    
    While angle > 2*#PI : angle - 2*#PI : Wend
    While angle < 0     : angle + 2*#PI : Wend
    
    x + speed_move*Cos(angle)
    y + speed_move*Sin(angle)
  EndIf
  
  
  StartDrawing(CanvasOutput(0))
  ForEach p()
    Circle(p()\x,p()\y,2,#Red) 
  Next
  DrawingMode(#PB_2DDrawing_Default )
  Plot(x,y,#White)                                      ; position
                                                        ;LineXY(x,y,x+20*Cos(angle_needed),y+20*Sin(angle_needed),#Red)  ; angle needed
                                                        ;LineXY(x,y,x+10*Cos(angle),y+10*Sin(angle),#Green)              ; current angle
  StopDrawing()
  
  
Until quit = 1
Edit : Uncheck DPI for now :)
Egypt my love
acreis
Enthusiast
Enthusiast
Posts: 227
Joined: Fri Jun 01, 2012 12:20 am

Re: Graphic: Curve throug points

Post by acreis »

STARGÅTE wrote: Fri Oct 17, 2025 6:27 pm Probably you are looking for Spline curves or Bézier curve.
I just linked them to the forum search here.
That's right STARGÅTE!

I've been tracking the posts about spline, bezier, curve interpolation the last 15 years.

There's a lot of very good examples, but one I saw, I don't remember when, fits my present needs.

If it is not a false memory or hallucination, it's like I said, "smooth curves by points", "points draggable", and not strange loops when general direction of points change.

I googled the forum before posting about it, but had no success.

So I asked, maybe the author or someone with same need could remember.

Many thanks!
acreis
Enthusiast
Enthusiast
Posts: 227
Joined: Fri Jun 01, 2012 12:20 am

Re: Graphic: Curve throug points

Post by acreis »

RASHAD wrote: Fri Oct 17, 2025 9:31 pm Hi acreis
Next code by NULL for sprite
Modified by RASHAD for windows
Take it as start :)

Code: Select all

ww=400
wh=400

hWin=OpenWindow(0, 0,0,ww,wh, "Spline",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CanvasGadget(0,0,0,ww,wh)
StartDrawing(CanvasOutput(0))
Box(0,0,ww,wh,#Black)
StopDrawing()

NewList p.POINT()               ; waypoints
x.f = ww/2                      ; object x
y.f = wh/2                      ; object y
angle.f                         ; object angle
speed_move.f = 0.4              ; movement speed
speed_rotate.f = speed_move*0.1 ; rotation speed
distance_tolerance.f = 3.0      ; pixel tolerance to reach waypoint
angle_needed.f                  ; angle from object to next waypoint
angle_diff.f                    ; rotation needed to point straight to next waypoint


Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      quit=1
      
    Case #WM_LBUTTONDOWN            ; add point
      LastElement(p())
      AddElement(p())
      p()\x = WindowMouseX(0)
      p()\y = WindowMouseY(0)
      
    Case #WM_RBUTTONDOWN             ; clear points
      ClearList(p())
      StartDrawing(CanvasOutput(0))
      Box(0,0,ww,wh,#Black)
      StopDrawing()
      
  EndSelect
  If ListSize(p())
    FirstElement(p())
    ; distance check only axis-based. you could use real distance calculation here if prefered
    If Abs(p()\x-x) < distance_tolerance And Abs(p()\y-y) < distance_tolerance
      DeleteElement(p())
    EndIf
  EndIf  
  
  If ListSize(p())
    FirstElement(p())
    angle_needed = ATan2( p()\x-x, p()\y-y )
    
    If angle_needed < 0
      angle_needed + 2*#PI ;
    EndIf
    
    If angle_needed > angle
      If (angle_needed-angle) < #PI
        angle_diff = (angle_needed - angle)
      Else
        angle_diff = -(2*#PI - (angle_needed - angle))
      EndIf
    Else
      If (angle-angle_needed) < #PI
        angle_diff = - (angle - angle_needed)
      Else
        angle_diff =  (2*#PI - (angle - angle_needed))
      EndIf
    EndIf
    
    angle + angle_diff*speed_rotate
    
    While angle > 2*#PI : angle - 2*#PI : Wend
    While angle < 0     : angle + 2*#PI : Wend
    
    x + speed_move*Cos(angle)
    y + speed_move*Sin(angle)
  EndIf
  
  
  StartDrawing(CanvasOutput(0))
  ForEach p()
    Circle(p()\x,p()\y,2,#Red) 
  Next
  DrawingMode(#PB_2DDrawing_Default )
  Plot(x,y,#White)                                      ; position
                                                        ;LineXY(x,y,x+20*Cos(angle_needed),y+20*Sin(angle_needed),#Red)  ; angle needed
                                                        ;LineXY(x,y,x+10*Cos(angle),y+10*Sin(angle),#Green)              ; current angle
  StopDrawing()
  
  
Until quit = 1
Edit : Uncheck DPI for now :)
Hi RASHAD,

Thanks a lot!

It's a really good start, I'll try fit it to my needs!
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4981
Joined: Sun Apr 12, 2009 6:27 am

Re: Graphic: Curve throug points

Post by RASHAD »

Hi acreis
I think you mean Bézier by OpenCV-JHPJHP
You can drag the point but it is limited to 2 points
Maybe you can adapt it for your needs
Egypt my love
Post Reply