Turtle
Posted: Mon Jul 11, 2005 5:50 pm
PBTurtle
by einander
PB 3.93
Draws lines and polygons using a string of commands, coordinates and angles, based on HPGL plotter and LOGO turtle graphics.
Angles are entered betweeen 0 And 3600. The following commands are available:
FD n Moves the drawing pencil n pixels Forward
BK n Moves the drawing pencil n pixels Backwards
LT a Turns the drawing pencil Left a/10 degrees
RT a Turns the drawing pencil Right a/10 degrees
MA a Turns the drawing pencil to Absolute Angle a/10 degrees, pointing as follows:
a= 0 Or 3600 Right
a= 900 Down
a= 1800 Left
a= 2700 Up
PU Lifts the pen Up; move without drawing
PD Lowers the pen Down to draw (Default)
AT X Y Sets pencil position At Absolute coordinates X Y without drawing - Ignores Pen Down
To X Y Draws line from actual pen position To Absolute coordinates X Y - Ignores Pen Up
CO c Sets drawing colour To c
PW w Sets pen Width To w
If command succeeds, it returns the address where last used values are stored, as 5 Longs
These values are:
Addr : X position
Addr+4 : Y position
Addr+8 : Pen Width
Addr+12 : Pen Color
Addr+16 : Absolute Angle*10
If Command fails, it returns 0
The parameters for individual commands must be specified using strings - See example.
Syntax: Turtle(DC, Command$)
DC = Device Context handle , as returned by StartDrawing()
Command$= string with commands to move pen, case insensitive, using commas or spaces as separators.
Beware of missing inner separators!
by einander
PB 3.93
Draws lines and polygons using a string of commands, coordinates and angles, based on HPGL plotter and LOGO turtle graphics.
Angles are entered betweeen 0 And 3600. The following commands are available:
FD n Moves the drawing pencil n pixels Forward
BK n Moves the drawing pencil n pixels Backwards
LT a Turns the drawing pencil Left a/10 degrees
RT a Turns the drawing pencil Right a/10 degrees
MA a Turns the drawing pencil to Absolute Angle a/10 degrees, pointing as follows:
a= 0 Or 3600 Right
a= 900 Down
a= 1800 Left
a= 2700 Up
PU Lifts the pen Up; move without drawing
PD Lowers the pen Down to draw (Default)
AT X Y Sets pencil position At Absolute coordinates X Y without drawing - Ignores Pen Down
To X Y Draws line from actual pen position To Absolute coordinates X Y - Ignores Pen Up
CO c Sets drawing colour To c
PW w Sets pen Width To w
If command succeeds, it returns the address where last used values are stored, as 5 Longs
These values are:
Addr : X position
Addr+4 : Y position
Addr+8 : Pen Width
Addr+12 : Pen Color
Addr+16 : Absolute Angle*10
If Command fails, it returns 0
The parameters for individual commands must be specified using strings - See example.
Syntax: Turtle(DC, Command$)
DC = Device Context handle , as returned by StartDrawing()
Command$= string with commands to move pen, case insensitive, using commas or spaces as separators.
Beware of missing inner separators!
Code: Select all
#Deg2rad=3.14159265 / 1800
Structure Dat
X.l
Y.l
Wid.l
RGB.l
Angle.l
EndStructure
Procedure Turtle(DC,C$)
Static X,Y,Ang.f,Angle.l,Wid,RGB,PenUp
P.Dat
If Wid=0:Wid=1:EndIf ; default pen width
C$=UCase(C$)
ReplaceString(C$,","," ",2) ; comma to SPC
C$=ReplaceString(C$," "," ") ; double SPC to single SPC
Repeat ; HEX to DEC
INS= FindString(C$,"$",1)
If INS=0 :Break
Else
a$=StringField(Mid(C$,INS,Len(C$)),1," ")
LE=Len(a$)
For i=2 To LE
Dec<<4 : D$=Mid(a$,i,1)
a=PeekB(@D$)
If a>60 : Dec+a-55
Else : Dec+a-48
EndIf
Next
C$= ReplaceString(C$,a$,Str(Dec))
EndIf
ForEver
C$=Trim(C$)
Repeat ; parser
Po+1 : a$=StringField(C$,Po," ") ; command
If a$="":Break:EndIf
Select a$
Case "FD"
Po+1:Val=Val(StringField(C$,Po," "))
X+Val*Cos(Ang) : Y+Val*Sin(Ang)
If PenUp=0 ; if Penup =1 , keep position without drawing
pen=CreatePen_(#PS_SOLID,Wid,RGB)
SelectObject_(DC,pen)
LineTo_(DC,X,Y)
DeleteObject_(pen)
EndIf
Case "BK"
Po+1:Val=Val(StringField(C$,Po," "))
X-Val*Cos(-Ang) : Y-Val*Sin(-Ang)
If PenUp=0
pen=CreatePen_(#PS_SOLID,Wid,RGB)
SelectObject_(DC,pen)
LineTo_(DC,X,Y)
DeleteObject_(pen)
EndIf
Case "PD" : PenUp=0
Case "PU" : PenUp= 1
Case "RT"
Po+1:Angle=Val(StringField(C$,Po," "))
Ang+Angle*#Deg2rad
Case"LT"
Po+1:Angle=Val(StringField(C$,Po," "))
Ang-Angle*#Deg2rad
Case "MA"
Po+1:Angle=Val(StringField(C$,Po," "))
Ang= Angle*#Deg2rad
Case"CO"
Po+1:RGB=Val(StringField(C$,Po," "))
Case "PW"
Po+1:Wid=Val(StringField(C$,Po," "))
Case "AT"
Po+1:X=Val(StringField(C$,Po," "))
Po+1:Y=Val(StringField(C$,Po," "))
MoveToEx_(DC,X,Y,0)
Case "TO"
Po+1:X=Val(StringField(C$,Po," "))
Po+1:Y=Val(StringField(C$,Po," "))
pen=CreatePen_(#PS_SOLID,Wid,RGB)
SelectObject_(DC,pen)
LineTo_(DC,X,Y)
DeleteObject_(pen)
Default
; MessageRequester("Error !","Unknown command "+Chr(13)+a$,0)
ProcedureReturn 0 ; if unknown command
EndSelect
ForEver
P\X=X
P\Y=Y
P\Wid=Wid
P\RGB=RGB
P\Angle=Angle
ProcedureReturn @P
EndProcedure
;______________________________________________________________________-
; TEST
OpenWindow(0,0,0,0,0,#WS_OVERLAPPEDWINDOW | #WS_MAXIMIZE,"PBTurtle - LogoParser")
XX=WindowWidth()/2 : YY=WindowHeight()/2
_D=StartDrawing(WindowOutput())
Turtle(_D," PW 3 co "+Str(Random($FFFFFF))) ; case insensitive, pen width=3, random color
Turtle(_D,"at 100 100 to 100 200 to 200 200 to 200 100 to 100 100") ; draw box from coordinates
Turtle(_D,"co 255 at "+Str(WindowWidth()-100)+ " 100 pd rt 900 fd 100 rt 900 fd 100 rt 900 fd 100 rt 900 fd 100" ) ; box from angles and sides
Turtle(_D,"at "+Str(XX)+" "+Str(YY))
;Octagon And cubes *********************************
For i=1 To 8
For j=1 To 8
Addr=Turtle(_D,"FD "+Str(50)+" RT 450") ; replace 50 by any value or numeric variable
X=PeekL(Addr)
Y=PeekL(Addr+4)
; Wid=PeekL(Addr+8)
Color=PeekL(Addr+12)
; Angle=PeekL(Addr+16)
Circle(X,Y,5,Color)
Next
Turtle(_D,"co "+Str(Random($FFFFFF))+" rT 450")
Next
Turtle(_D,"at 150 150 pw 1 co $aaaaaa") ; move to 150 150 without drawing , color gray
; ;rotanting Pentagons *****************************************
For i=1 To 16
For j=1 To 4
Turtle(_D,"FD 100 RT 900 ")
Next
Turtle(_D," RT 300")
Next
Turtle(_D,"PW 2 co 255 to "+Str(XX)+" "+Str(YY)) ; move to xx yy drawing red ; Don't forget inner separators!
Turtle (_D,"to "+Str(WindowWidth()-150)+" "+Str(150))
Circle(PeekL(Addr),PeekL(Addr+4),10,#Yellow)
Repeat
Until WaitWindowEvent()= #PB_Event_CloseWindow
End