Closed amca01 closed 7 years ago
Hi!
Thanks for trying it out! Yes you are right, these primitives are not yet implemented in furtle. I am planning to add them in the future, but didn't get time to do that yet. I might be able to add it this weekend - or if you want to go ahead and implement it, please send a pull request.
Hi,
Thank you for responding so quickly! I had a quick look through "turtle-main.rkt" and it would seem that all the information is there, it just needs to be made available to the end user. Would something like this work:
(: pos (-> turtle))
(define pos
(let* ([tx (turtle-tx t)]
[ty (turtle-ty t)])
(tx ty)
)
You could either have a separate command for heading, or put everything together in a "state" for example, which gives the user the turtle's current position, heading, and all other attributes. Something like this is done with turtle-state
in the graphics/value-turtles
package.
You see that although I am mostly a newbie in Racket, I'm a complete tyro in Typed Racket!
Hi again!
It's actually possible to access all the information of a turtle and modify it during drawing and still be able to compose the operation with rest of the primitives like forward
, right
using same composition primitives like turtles
and repeat
. The trick is to create a TurtleF
or a function that takes a turtle
and returns a new turtle
. This way we can do whatever we want and the subsequent steps in the drawing will have this modified turtle to work with. We just have to be cautious so that we don't modify the ops
property accidentally. Here is an example:
#lang typed/racket
(require furtle)
(: x Real)
(define x 0)
(: y Real)
(define y 0)
(draw (turtles
(forward 40)
(sarc 360 10)
(right 45)
(forward 40)
(λ ([t : turtle])
; store x and y of current turtle
(set! x (turtle-tx t))
(set! y (turtle-ty t))
; now make a new turtle at a new position
(turtle (+ 50 x)
(+ 50 y)
0
'pendown
#t
(turtle-ops t)))
; continue with the new turtle
(forward 40)
(sarc 360 10)
(right 45)
(forward 40)
; restore saved turtle
(λ ([t : turtle])
(turtle x
y
(turtle-angle t)
(turtle-penstate t)
(turtle-visible t)
(turtle-ops t)))
(forward 80)
(sarc 360 20)
(right 45)
(forward 80)))
This is of course cumbersome to do, but we can write helper functions/macros to ease the verbosity.
I'll go over that in a while... I can make nice fractal drawings, such as are in the early chapters of Prusinkiewicz and Lindenmayer's "Algorithmic Beauty of Plants". So in a sense I can manage without coordinates and headings, but it would be very flexible to have them.
I know that there is a Racket "lindenmayer" package for doing all of this, but I want to be able to develop my own graphics from scratch, using operations as close to Logo's Turtle Graphics as I can.
Here are a few more things which might be nice in furtle (only if they are easy to implement, of course):
Thank you again - I'm having a lot of fun with it!
I have added some new capabilities in the latest commit:
Ability to save and restore turtle step during drawing. This will only work within a turtles
or repeat
construct. The save
and restore
saves the states in a stack - so multiple save and restore can be done. A restore will retrieve the last saved state.
draw
and show!
functions accept optional keyword arguments #:pen-width
, #:pen-color
and #:background-color
arguments which can control the drawing output.
Please take a look at the examples.rkt
file with examples directory for example usage. It should be available in racket pkg index (for doing raco pkg install furtle
) probably a day later, but you can install it directly from github.
Thanks again for using the library - I started writing it to learn two things - functional side effect free coding and this book https://mitpress.mit.edu/books/turtle-geometry. :-)
Thank you again - I'll look at the new code later today (it's mid-morning here in Melbourne, Australia, and I'm just finishing a late breakfast). Yes, the Abelson & Di Sessa book is terrific - I recently acquired a second hand copy. But my love of Logo goes back nearly 30 years, when I was teaching it to education students, and in many ways Racket seems to me the most "Logo-like" of all the current Lisp descendants. And I started using Racket simply because the Logos available on Linux (mainly ucblogo) are too underpowered and memory poor for my uses. On quite simple procedures ucblogo crashes; Racket & furtle power through them with ease. Plus Racket is fast: a backtracking procedure I wrote to search for Hamiltonian cycles in graphs took several hours in Logo (on a large graph); a matter of seconds in Racket.
In spite of its slowness, I think it's one of the great misfortunes of computer languages that Logo never lost its reputation as being "for kids"; in its power and design I still hold it as being truly superb. But we must move on...
Thank you for this - I've upgraded to the new version and it all works very well indeed. Would it be possible to change the pensize during a drawing? Like this:
(turtles (pensize 6) (forward 100) (pensize 3) (forward 100) (pensize 1))
Thank you again, Alasdair
Sure. I have added two primitives pen-width and pen-color which does the above for width and color. Check out the example file and docs for their usage. Also the default orange background is changed to white now.
Thanks! Sourav
Thank you very much! I am finding your library provides a much closer "Logo" experience than any other of the various turtle libraries for Racket. My interest was sparked by trying to explain Lindenmayer Systems (L-systems). There is a very full featured Lindenmayer library already for Racket, but for purposes of teaching, I wanted something very low-level which I could use to explain the structure of an L-system, and how the rules related to the graphics. And so far furtle has proved ideal - and becoming more perfect by the minute owing to your kind changes.
Here is a classic example you might like to add:
` ;; Koch's snowflake
(: snowflake_side (-> Integer Real TurtleF)) (define (snowflake_side level size) (if (= level 0) (turtles (forward size)) (turtles (snowflake_side (sub1 level) (/ size 3)) (left 60) (snowflake_side (sub1 level) (/ size 3)) (right 120) (snowflake_side (sub1 level) (/ size 3)) (left 60) (snowflake_side (sub1 level) (/ size 3)) )))
(: snowflake (-> Integer TurtleF)) (define (snowflake level) (turtles (right 30) (penup) (back 350) (left 30) (pendown) (repeat 3 (snowflake_side level 600) (right 120))))`
Thus (draw (snowflake 6))
gives you a nice fractal Koch snowflake.
Thanks a lot for your encouraging words! It is what keeps the motivation up! I have plan to find some time soon and study fractals and other similar constructs in much detail, including Lindenmayer Systems as you noted. Hopefully that will add some more enhancements to the library. I liked the Koch example, it will be really good to add as an example!
Hello,
I've come to Racket via Logo, and furtle seems the nicest implementation of turtle graphics I've found in Racket. (I've drawn the "fractal plant" seen on https://en.wikipedia.org/wiki/L-system, and even for n=7 or 8 it was amazingly fast, once I increased the memory limit). However, there are two things I'm still not sure of: (1) saving the turtle's current position and heading, and (2) moving the turtle to a given position and heading.
In Logo (1) would be implemented with POS and HEADING, and (2) with SETPOS and SETHEADING. It may be that these are primitives that don't need special furtle functions, but anyway I don't know how to do either of them.
I'd be happy of any advice! Thank you very much. And thank you for the furtle package!