I don't know where this problem coming from. Can anyone help me out?!
The function FillArea() is used on line 258 of the code below.
Code: Select all
; Exercise 7
; Animation of a two link planar arm with rotary joints
; Copyright © 2006 Serge Visser en Jos de Jong
; Written with the programming language PureBasic
; create program constants
#winmain = 1
#winpaint = 2
#timerID = 3
#start = 4
#t1_scroll = 5
#t2_scroll = 6
#t1_text = 7
#t2_text = 8
#font_Verdana = 10
#font_Verdana_big = 11
#refreshinterval = 50 ;millisecs
#scroll_max = 40
; create global variables and declare functions
Declare CreateAnimation()
Global x0.f, y0.f
Global x1.f, y1.f
Global x2.f, y2.f
Global L1.f, L2.f
Global theta1.f, theta2.f ;angle of the links
Global theta1_ref.f, theta2_ref.f ;position of the scrollbars
Global pi.f
Global delta.f
Global animT12
Global animXY
Global animcount
Global animpos
Global animating
Global animfinished
Dim animT12.f(1000,1)
Dim animXY.f(1000,1)
; create program variables
pi = 4*ATan(1)
x0 = 300
y0 = 350
L1 = 150
L2 = L1/2
theta1 = 0.2*pi
theta2 = 0.25*pi
theta1_ref = theta1
theta2_ref = theta2
delta = 0.02*pi
animating = #False
animfinished = #False
; create some colors used for the graphics
Global darkgray :darkgray = RGB(96,96,96)
Global gray :gray = RGB(180,180,180)
Global black :black = RGB(0,0,0)
Global red :red = RGB(255,0,0)
Global white :white = RGB(255,255,255)
Global brown :brown = RGB(128,64,0)
Global pink :pink = RGB(255,128,192)
Global purple :purple = RGB(128,0,128)
Global green :green = RGB(0,255,0)
Global darkgreen :darkgreen = RGB(0,128,0)
Procedure CreateWindow()
; create the mainwindow with gadgets and 2D directX window
OpenWindow(#winmain, 100, 100, 600, 500, #PB_Window_SystemMenu, "Two-link Animation")
CreateGadgetList(WindowID())
ButtonGadget(#start,10,10, 120,35, "&Start Animation")
; create a scrollbar for theta1
TextGadget(#t1_text, 160, 5, 150, 20, "Theta1")
ScrollBarGadget(#t1_scroll, 160, 25,150, 20, 0, #scroll_max, 1)
SetGadgetState(#t1_scroll, #scroll_max * theta1/pi)
; create a scrollbar for theta2
TextGadget(#t2_text, 320, 5, 150, 20, "Theta2")
ScrollBarGadget(#t2_scroll, 320, 25,150, 20, 0, #scroll_max, 1)
SetGadgetState(#t2_scroll, #scroll_max * (theta2+0.5*pi)/(1.5*pi))
; create a directX screen in the main window
If InitSprite()=0
MessageRequester("Error","Can't open DirectX",0)
End ;stop the program
EndIf
OpenWindowedScreen(WindowID(), 0, 55, 600, 445, 0, 0, 0)
CreateAnimation()
LoadFont(#font_Verdana, "Verdana", 10, 0)
LoadFont(#font_Verdana_big, "Verdana", 13, #PB_Font_Bold)
FlipBuffers()
ClearScreen(255,255,255)
EndProcedure
Procedure CreateAnimation()
; create the data needed to do the animation.
; the positions for the arm are saved in a matrix with two columns:
; first column contains theta1 for each moment,
; second column contains theta2 for each moment
t1.f = 0
t2.f = 0.5*pi
animcount=0
Repeat
animcount = animcount + 1
animT12(animcount, 0) = t1
animT12(animcount, 1) = t2
animXY(animcount,0) = x0 + L1*Cos(-t1) + L2*Cos(-t1-t2)
animXY(animcount,1) = y0 + L1*Sin(-t1) + L2*Sin(-t1-t2)
t2 = t2+delta
Until t2 >= 1*Pi
t2 = pi
Repeat
animcount = animcount + 1
animT12(animcount, 0) = t1
animT12(animcount, 1) = t2
animXY(animcount,0) = x0 + L1*Cos(-t1) + L2*Cos(-t1-t2)
animXY(animcount,1) = y0 + L1*Sin(-t1) + L2*Sin(-t1-t2)
t1 = t1+delta
Until t1 >= 1*Pi
t1 = pi
t2 = pi
Repeat
animcount = animcount + 1
animT12(animcount, 0) = t1
animT12(animcount, 1) = t2
animXY(animcount,0) = x0 + L1*Cos(-t1) + L2*Cos(-t1-t2)
animXY(animcount,1) = y0 + L1*Sin(-t1) + L2*Sin(-t1-t2)
t2 = t2-delta
Until t2 <=0
t1=pi
t2=0
Repeat
animcount = animcount + 1
animT12(animcount, 0) = t1
animT12(animcount, 1) = t2
animXY(animcount,0) = x0 + L1*Cos(-t1) + L2*Cos(-t1-t2)
animXY(animcount,1) = y0 + L1*Sin(-t1) + L2*Sin(-t1-t2)
t1 = t1-delta
Until t1 <=0
t1=0
t2=0
Repeat
animcount = animcount + 1
animT12(animcount, 0) = t1
animT12(animcount, 1) = t2
animXY(animcount,0) = x0 + L1*Cos(-t1) + L2*Cos(-t1-t2)
animXY(animcount,1) = y0 + L1*Sin(-t1) + L2*Sin(-t1-t2)
t2 = t2-delta
Until t2 <= -0.5*pi
t1=0
t2=-0.5*pi
Repeat
animcount = animcount + 1
animT12(animcount, 0) = t1
animT12(animcount, 1) = t2
animXY(animcount,0) = x0 + L1*Cos(-t1) + L2*Cos(-t1-t2)
animXY(animcount,1) = y0 + L1*Sin(-t1) + L2*Sin(-t1-t2)
t1 = t1+delta
Until t1 >= 0.32*pi
EndProcedure
Procedure PlayAnimation()
; play the stored animation
animpos=0
animating = #True
animfinished = #False
EndProcedure
Procedure StopAnimation()
; play the stored animation
animating = #False
animfinished = #True
EndProcedure
Procedure PaintLink(x.f, y.f, theta.f, length.f)
; paint a link with a joint using primitive graphics (yes thats fun! :)
#armwidth = 5
#jointradius = 8
#jointradiusinner = 5
bottom1x.f = x+#armwidth*Cos(theta+0.5*Pi)
bottom1y.f = y+#armwidth*Sin(theta+0.5*Pi)
bottom2x.f = x+#armwidth*Cos(theta-0.5*Pi)
bottom2y.f = y+#armwidth*Sin(theta-0.5*Pi)
top1x.f = bottom1x.f + length*Cos(theta)
top1y.f = bottom1y.f + length*Sin(theta)
top2x.f = bottom2x.f + length*Cos(theta)
top2y.f = bottom2y.f + length*Sin(theta)
LineXY(x, y, x+length*Cos(theta), y+length*Sin(theta), black)
;LineXY(bottom1x, bottom1y, top1x, top1y, black)
;LineXY(bottom2x, bottom2y, top2x, top2y, black)
;LineXY(bottom1x, bottom1y, bottom2x, bottom2y, black)
;LineXY(top1x, top1y, top2x, top2y, black)
; fillx.f = x+0.5*length*Cos(theta)
; filly.f = y+0.5*length*Sin(theta)
; FillArea(fillx, filly, black, gray)
Circle(x, y, #jointradius, black)
Circle(x, y, #jointradius-1, white)
Circle(x, y, #jointradiusinner, black)
EndProcedure
Procedure Paint2Link()
; paint the arm on the screen
; paint the base of the arm
w0 = 100
h0 = 50
r = 5
border = 3
FrontColor(0,0,0)
Box(x0-0.5*w0, y0, w0, h0, black)
Box(x0-0.5*w0+border, y0+border, w0-2*border, h0-2*border, red)
; paint the first link and the base joint
PaintLink(x0, y0, -theta1, L1)
; paint the second link
x1 = x0 + L1*Cos(-theta1)
y1 = y0 + L1*Sin(-theta1)
PaintLink(x1, y1, -theta1-theta2, L2)
; paint a joint on the end
x2 = x1 + L2*Cos(-theta1-theta2)
y2 = y1 + L2*Sin(-theta1-theta2)
PaintLink(x2, y2, -theta1-theta2, 0)
EndProcedure
Procedure PaintWorkarea()
; paint the workarea reached so far during the animation
posmax = animpos
If posmax>animcount :posmax = animcount :EndIf
If animfinished = #True :posmax = animcount :EndIf
;paint the border of the workarea
For pos = 2 To posmax
LineXY(animXY(pos-1,0),animXY(pos-1,1), animXY(pos,0),animXY(pos,1), darkgreen)
Next
; after the last animation, fill up the workarea
If posmax=animcount
FillArea(x0, y0-L1, darkgreen, green)
EndIf
EndProcedure
Procedure PaintText()
;paint some text in the window
DrawingFont(UseFont(#font_Verdana_big))
Locate(10,60)
DrawText("Exercise 7 - Reachable workspace for a two-link planar arm")
DrawingFont(UseFont(#font_Verdana))
Locate(10,475)
DrawText("Copyright © 2006 Serge Visser en Jos de Jong")
EndProcedure
Procedure UpdateScrollvariables()
pos.f
;update theta1
pos = GetGadgetState(#t1_scroll)
pos = pos/#scroll_max * Pi
theta1_ref = pos
SetGadgetText(#t1_text, "Theta1 = "+StrF(theta1_ref/pi,2) + " * Pi")
;update theta2
pos = GetGadgetState(#t2_scroll)
pos = pos/#scroll_max * (1.5*Pi) - 0.5*Pi
theta2_ref = pos
SetGadgetText(#t2_text, "Theta2 = "+StrF(theta2_ref/pi,2) + " * Pi")
EndProcedure
Procedure UpdateScrollBar()
; update the scrollbar positions with given theta1_ref and theta2_ref
;update theta1
theta1_ref = theta1
SetGadgetState(#t1_scroll, #scroll_max * theta1_ref/pi)
;update theta2
theta2_ref = theta2
SetGadgetState(#t2_scroll, #scroll_max * (theta2_ref+0.5*pi)/(1.5*pi))
EndProcedure
; Create the window
CreateWindow()
UpdateScrollvariables()
SetTimer_(WindowID(), #timerID, #refreshinterval, 0) ; start a timer
;-Eventhandler
;{
Repeat
WhichEvent = WaitWindowEvent() ;Wait for an Event
WhichWindow = EventWindowID() ;Number of Window which fires the event
WhichGadget = EventGadgetID() ;Is an Gadget used ?
WhichEventType = EventType() ;The event type
If WhichWindow = #winmain
Select WhichEvent
Case #PB_EventGadget
Select WhichGadget
Case #start
; if user pressed the button "start animation" then start the animation
PlayAnimation()
Case #t1_scroll
UpdateScrollvariables()
Case #t2_scroll
UpdateScrollvariables()
EndSelect
Case #PB_Event_CloseWindow
; quit the program
KillTimer_(WindowID(), #timerID)
End
Case #WM_TIMER
; timer routine
Select EventwParam()
Case #timerID
If animating = #True
; go to the next animation position.
; stop the animation if the end is reached
animpos = animpos + 1
;If animpos>animcount :animpos = animcount :EndIf
If animpos<=animcount
; get new positions for theta1 and theta2
theta1 = animT12(animpos,0)
theta2 = animT12(animpos,1)
Else
; stop the animation if the end of the data is reached
StopAnimation()
UpdateScrollBar()
EndIf
EndIf
If animating = #False
;update position for link1
If theta1_ref<>theta1
theta1 = theta1 + delta * Abs(theta1_ref-theta1)/(theta1_ref-theta1)
If Abs(theta1_ref-theta1) < delta
theta1 = theta1_ref
EndIf
EndIf
;update position for link2
If theta2_ref<>theta2
theta2 = theta2 + delta * Abs(theta2_ref-theta2)/(theta2_ref-theta2)
If Abs(theta2_ref-theta2) < delta
theta2 = theta2_ref
EndIf
EndIf
EndIf
; repaint the arm
FlipBuffers()
ClearScreen(255,255,255) ;empty the paint window
If StartDrawing(WindowOutput())
If animating=#True Or animfinished = #True
PaintWorkarea() ;paint the workarea
EndIf
Paint2Link()
PaintText()
StopDrawing()
EndIf
EndSelect
EndSelect
EndIf
ForEver
;}
Jos