my bezier

General FreeBASIC programming questions.
owen
Posts: 555
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

my bezier

Postby owen » Jan 10, 2020 4:23

left click adds control points
right click deletes control points
editing (moving points) drag the control point

Code: Select all

Type point2d
   x As double
   y As double
End Type
Type bezier
   as integer n=-1
   pt(any) As point2d 'anchors and control points (p0 thru pN)
   declare sub append_pt(x as double, y as double)
   declare sub delete_pt(d as integer)
   declare sub plot(pres as integer)
End Type
sub bezier.append_pt(x as double, y as double)
   n+=1
   redim preserve pt(n)
   pt(n).x=x
   pt(n).y=y
End Sub
sub bezier.delete_pt(d as integer)
   for i as integer = d to n-1
      pt(i)=pt(i+1)
   Next
   n-=1
   redim preserve pt(n)
End Sub
sub bezier.plot(pres as integer)
   dim as point2d c(n,n)
   dim as double x_range,y_range
   pset(pt(0).x,pt(0).y)
   for t as integer = 1 to pres
      for i as integer = 0 to n-1
         x_range=pt(i+1).x - pt(i).x
         y_range=pt(i+1).y - pt(i).y
         c(i,0).x=pt(i).x+x_range*t/pres
         c(i,0).y=pt(i).y+y_range*t/pres
      Next
      for k as integer = 0 to n
         for i as integer = 0 to n-(k+2)
            x_range=c(i+1,k).x - c(i,k).x
            y_range=c(i+1,k).y - c(i,k).y
            c(i,k+1).x=c(i,k).x+x_range*t/pres
            c(i,k+1).y=c(i,k).y+y_range*t/pres
            if n<(k+3) then line -(c(i,k+1).x,c(i,k+1).y)
         Next
      Next
   next
End Sub
sub updatebz(pres as integer,byref bz as bezier)
   screenlock
   ScreenSet 0,1
   cls
   with bz
      for i as integer=0 to bz.n
         circle(.pt(i).x,.pt(i).y),6
      Next
      select case .n
         case 1
            line(.pt(0).x,.pt(0).y)-(.pt(1).x,.pt(1).y)
         case is > 1
            .plot(pres)
      End Select
   end with
   screencopy 0,1
   screenset 1,1
   screenunlock
End Sub



Dim As bezier bz
Dim As Integer mouse_x, mouse_y, mouse_wheel, mouse_button, click_count
dim as integer selected_point
Dim As BOOLEAN mouse_button_released,snap,edit
ScreenRes 400,400,,2
ScreenSet 1,1
Do
   Select Case InKey
      Case Chr(27),Chr(255)+"k"
         Exit Do
   End Select
   GetMouse(mouse_x, mouse_y, mouse_wheel, mouse_button)
   if edit=false then
      snap=false
      screencopy 0,1
      for i as integer=0 to bz.n
         with bz
            select case mouse_x
               case .pt(i).x -3 to .pt(i).x+3
                  select case mouse_y
                     case .pt(i).y -3 to .pt(i).y+3
                        snap=true
                        selected_point=i
                        screenset 1,1
                        circle(.pt(i).x,.pt(i).y),6,3,,,,f
                        exit for
                  End Select
            End Select
         End With
      Next
   endif
   Select Case mouse_button
      case 0
         mouse_button_released = TRUE
         if edit=true then
            edit=false
            updatebz(100,bz)
         EndIf
      Case 1
         If mouse_button_released = TRUE Then
            mouse_button_released = FALSE
            if snap=true then
               edit=true
            else
               bz.append_pt(mouse_x,mouse_y)
               updatebz(100,bz)
            EndIf
         endif
      case 2
         If mouse_button_released = TRUE Then
            mouse_button_released = FALSE
            if snap=true then
               snap=false
               bz.delete_pt(selected_point)
               updatebz(100,bz)
            EndIf
         endif
   End Select
   if edit=true then
      with bz
         .pt(selected_point).x=mouse_x
         .pt(selected_point).y=mouse_y
      end with
      updatebz(10,bz)
   EndIf
   Sleep 1
Loop
owen
Posts: 555
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: my bezier

Postby owen » Jan 10, 2020 5:54

draw curves using multiple control points then press the A key on the keyboard to animate the plot

Code: Select all

Type point2d
   x As double
   y As double
End Type
Type bezier
   as integer n=-1
   pt(any) As point2d 'anchors and control points (p0 thru pN)
   declare sub append_pt(x as double, y as double)
   declare sub delete_pt(d as integer)
   declare sub plot(pres as integer)
   declare sub plot_details(pres as integer, t as integer)
End Type
sub bezier.append_pt(x as double, y as double)
   n+=1
   redim preserve pt(n)
   pt(n).x=x
   pt(n).y=y
End Sub
sub bezier.delete_pt(d as integer)
   for i as integer = d to n-1
      pt(i)=pt(i+1)
   Next
   n-=1
   redim preserve pt(n)
End Sub
sub bezier.plot(pres as integer)
   dim as point2d c(n,n)
   dim as double x_range,y_range
   pset(pt(0).x,pt(0).y)
   for t as integer = 1 to pres
      for i as integer = 0 to n-1
         x_range=pt(i+1).x - pt(i).x
         y_range=pt(i+1).y - pt(i).y
         c(i,0).x=pt(i).x+x_range*t/pres
         c(i,0).y=pt(i).y+y_range*t/pres
      Next
      for k as integer = 0 to n
         for i as integer = 0 to n-(k+2)
            x_range=c(i+1,k).x - c(i,k).x
            y_range=c(i+1,k).y - c(i,k).y
            c(i,k+1).x=c(i,k).x+x_range*t/pres
            c(i,k+1).y=c(i,k).y+y_range*t/pres
            if n<(k+3) then line -(c(i,k+1).x,c(i,k+1).y)
         Next
      Next
   next
End Sub

sub bezier.plot_details(pres as integer, t as integer)
   dim as point2d c(n,n)
   dim as double x_range,y_range
   pset(pt(0).x,pt(0).y)
   for i as integer = 0 to n-1
      line (pt(i).x,pt(i).y)-(pt(i+1).x,pt(i+1).y)
      x_range=pt(i+1).x - pt(i).x
      y_range=pt(i+1).y - pt(i).y
      c(i,0).x=pt(i).x+x_range*t/pres
      c(i,0).y=pt(i).y+y_range*t/pres
      circle(c(i,0).x,c(i,0).y),4,14,,,,f
   Next
   pset(pt(0).x,pt(0).y)
   for k as integer = 0 to n
      for i as integer = 0 to n-(k+2)
         x_range=c(i+1,k).x - c(i,k).x
         y_range=c(i+1,k).y - c(i,k).y
         c(i,k+1).x=c(i,k).x+x_range*t/pres
         c(i,k+1).y=c(i,k).y+y_range*t/pres
         if n<(k+3) then circle (c(i,k+1).x,c(i,k+1).y),6,4,,,,f
       line (c(i,k).x,c(i,k).y)-(c(i+1,k).x,c(i+1,k).y),abs(14-k) mod 15
      Next
   Next
End Sub

sub updatebz(pres as integer,byref bz as bezier)
   screenlock
   ScreenSet 0,1
   cls
   with bz
      for i as integer=0 to bz.n
         circle(.pt(i).x,.pt(i).y),6
      Next
      select case .n
         case 1
            line(.pt(0).x,.pt(0).y)-(.pt(1).x,.pt(1).y)
         case is > 1
            .plot(pres)
      End Select
   end with
   screencopy 0,1
   screenset 1,1
   screenunlock
End Sub



Dim As bezier bz
Dim As Integer mouse_x, mouse_y, mouse_wheel, mouse_button, click_count
dim as integer selected_point
Dim As BOOLEAN mouse_button_released,snap,edit
ScreenRes 400,400,,2
ScreenSet 1,1
Do
   Select Case InKey
      Case Chr(27),Chr(255)+"k"
         Exit Do
      case lcase("a")
         for i as integer = 1 to 100
         screenlock
         screencopy 0,1
         screenset 1,1
         bz.plot_details(100, i)
         screenunlock
         sleep 50
         next
         
   End Select
   GetMouse(mouse_x, mouse_y, mouse_wheel, mouse_button)
   if edit=false then
      snap=false
      screencopy 0,1
      for i as integer=0 to bz.n
         with bz
            select case mouse_x
               case .pt(i).x -3 to .pt(i).x+3
                  select case mouse_y
                     case .pt(i).y -3 to .pt(i).y+3
                        snap=true
                        selected_point=i
                        screenset 1,1
                        circle(.pt(i).x,.pt(i).y),6,3,,,,f
                        exit for
                  End Select
            End Select
         End With
      Next
   endif
   Select Case mouse_button
      case 0
         mouse_button_released = TRUE
         if edit=true then
            edit=false
            updatebz(100,bz)
         EndIf
      Case 1
         If mouse_button_released = TRUE Then
            mouse_button_released = FALSE
            if snap=true then
               edit=true
            else
               bz.append_pt(mouse_x,mouse_y)
               updatebz(100,bz)
            EndIf
         endif
      case 2
         If mouse_button_released = TRUE Then
            mouse_button_released = FALSE
            if snap=true then
               snap=false
               bz.delete_pt(selected_point)
               updatebz(100,bz)
            EndIf
         endif
   End Select
   if edit=true then
      with bz
         .pt(selected_point).x=mouse_x
         .pt(selected_point).y=mouse_y
      end with
      updatebz(10,bz)
   EndIf
   Sleep 1
Loop


Return to “General”

Who is online

Users browsing this forum: No registered users and 11 guests