turtle3.body.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. (define (image-rotate x y theta1 delta-theta)
  2. (when canvas-image-rotate
  3. (canvas-image-rotate x y theta1 delta-theta)))
  4. (define (line-color color)
  5. (if canvas-line-color
  6. (canvas-line-color color)
  7. (error "line-color" "Not supported by the implementation")))
  8. (define (bg-color color)
  9. (if canvas-bg-color
  10. (canvas-bg-color color)
  11. (error "bg-color" "Not supported by the implementation")))
  12. (define (line-width width)
  13. (if canvas-line-width
  14. (canvas-line-width width)
  15. (error "line-width" "Not supported by the implementation")))
  16. (define (normalize-angle theta)
  17. (cond
  18. ((>= theta 360)
  19. (normalize-angle (- theta 360)))
  20. ((< theta 0)
  21. (normalize-angle (+ theta 360)))
  22. (else theta)))
  23. (define (xy->facing x y)
  24. (define as-degree (/ (* 180 (atan (/ (inexact y) x))) 3.1415926))
  25. (normalize-angle
  26. (if (>= x 0)
  27. as-degree
  28. (+ 180 as-degree))))
  29. (define-operation (get-pos turt))
  30. (define-operation (set-pos! turt new-pos))
  31. (define-operation (get-orient turt))
  32. (define-operation (set-orient! turt new-H new-L new-U))
  33. (define-operation (pen-down? turt))
  34. (define-operation (shown? turt))
  35. (define-operation (show! turt))
  36. (define-operation (hide! turt))
  37. (define-operation (pen-up! turt))
  38. (define-operation (pen-down! turt))
  39. (define-operation (forward! turt dist))
  40. (define-operation (yaw! turt theta))
  41. (define-operation (pitch! turt theta))
  42. (define-operation (roll! turt theta))
  43. (define-operation (nutate! turt))
  44. (define-operation (left! turt theta))
  45. (define-operation (right! turt theta))
  46. (define-operation (back! turt dist))
  47. (define (make-turtle)
  48. (define pos #(0.0 0.0 0.0))
  49. (define H #(1.0 0.0 0.0))
  50. (define L #(0.0 1.0 0.0))
  51. (define U #(0.0 0.0 1.0))
  52. (define pen-state #t)
  53. (define shown-state #f)
  54. (object
  55. ((get-pos self)
  56. pos)
  57. ((set-pos! self new-pos)
  58. (let ((start-pos pos))
  59. (draw-turtle-line (vector-ref start-pos 0)
  60. (vector-ref start-pos 1)
  61. (vector-ref new-pos 0)
  62. (vector-ref new-pos 1)
  63. (pen-down? self)
  64. (shown? self))
  65. (let ((updated-vec (vector-copy start-pos)))
  66. (vector-set! updated-vec 0 (vector-ref new-pos 0))
  67. (vector-set! updated-vec 1 (vector-ref new-pos 1))
  68. (when (>= (vector-length new-pos) 3)
  69. (vector-set! updated-vec 2 (vector-ref new-pos 2)))
  70. (set! pos updated-vec))))
  71. ((get-orient self)
  72. (list H L U))
  73. ((set-orient! self new-H new-L new-U)
  74. (when shown-state
  75. (let ((old-tilt-x (vector-ref H 0))
  76. (old-tilt-y (vector-ref H 1))
  77. (new-tilt-x (vector-ref new-H 0))
  78. (new-tilt-y (vector-ref new-H 1)))
  79. (define old-tilt (xy->facing old-tilt-x old-tilt-y))
  80. (define new-tilt (xy->facing new-tilt-x new-tilt-y))
  81. (image-rotate (vector-ref pos 0)
  82. (vector-ref pos 1)
  83. old-tilt
  84. (- new-tilt old-tilt))))
  85. (set! H new-H)
  86. (set! L new-L)
  87. (set! U new-U))
  88. ((pen-down? self)
  89. pen-state)
  90. ((shown? self)
  91. shown-state)
  92. ((show! self)
  93. (set! shown-state #t)
  94. (when canvas-show-turtle
  95. (let ((h-x (vector-ref H 0))
  96. (h-y (vector-ref H 1)))
  97. (canvas-show-turtle (vector-ref pos 0)
  98. (vector-ref pos 1)
  99. (+ (/ (* 180 (atan (/ h-y h-x))) 3.14159265)
  100. (if (negative? h-x)
  101. 180
  102. 0))))))
  103. ((hide! self)
  104. (set! shown-state #f)
  105. (when canvas-hide-turtle
  106. (canvas-hide-turtle)))
  107. ((pen-up! self)
  108. (set! pen-state #f))
  109. ((pen-down! self)
  110. (set! pen-state #t))
  111. ((forward! self dist)
  112. ;; dist is a vector of 3 real numbers.
  113. (let ((start-pos pos))
  114. (define new-pos (vector-sum start-pos
  115. (scale-vector H dist)))
  116. (set-pos! self new-pos)))
  117. ((yaw! self theta)
  118. ;; theta is a real number.
  119. (set-orient! self
  120. (rotate H L theta)
  121. (rotate L (negate-vector H) theta)
  122. U))
  123. ((pitch! self theta)
  124. (set-orient! self
  125. (rotate H U theta)
  126. L
  127. (rotate U (negate-vector H) theta)))
  128. ((roll! self theta)
  129. (set-orient! self
  130. H
  131. (rotate L U theta)
  132. (rotate U (negate-vector L) theta)))
  133. ((nutate! self)
  134. (pitch! self -47.85)
  135. (yaw! self -11.43)
  136. (roll! self 43.32))
  137. ;; These are aliases that are equivalent to (turtle simple)
  138. ;; therefore removing the need for a separate simple library
  139. ((left! self theta)
  140. (yaw! self theta))
  141. ((right! self theta)
  142. (yaw! self (- theta)))
  143. ((back! self dist)
  144. (forward! self (- dist)))))
  145. (define fd! forward!)
  146. (define bk! back!)
  147. (define lt! left!)
  148. (define rt! right!)
  149. (define pu! pen-up!)
  150. (define pd! pen-down!)
  151. (define (get-xcor t)
  152. (vector-ref (get-pos t) 0))
  153. (define (get-ycor t)
  154. (vector-ref (get-pos t) 1))
  155. (define (get-zcor t)
  156. (vector-ref (get-pos t) 2))
  157. (define (set-xcor! t new-xcor)
  158. (define start-pos (get-pos t))
  159. (set-pos! t (vector new-xcor
  160. (vector-ref start-pos 1)
  161. (vector-ref start-pos 2))))
  162. (define (set-ycor! t new-ycor)
  163. (define start-pos (get-pos t))
  164. (set-pos! t (vector (vector-ref start-pos 0)
  165. new-ycor
  166. (vector-ref start-pos 2))))
  167. (define (set-zcor! t new-zcor)
  168. (define start-pos (get-pos t))
  169. (set-pos! t (vector (vector-ref start-pos 0)
  170. (vector-ref start-pos 1)
  171. new-zcor)))
  172. (define (face! t face-pos)
  173. (define actual-face-pos
  174. (vector
  175. (vector-ref face-pos 0)
  176. (vector-ref face-pos 1)
  177. (if (= (vector-length face-pos) 3)
  178. (vector-ref face-pos 2)
  179. 0.0)))
  180. (define old-orient (get-orient t))
  181. (define new-H (unit-vector (vector-difference actual-face-pos (get-pos t))))
  182. (define U (list-ref old-orient 2))
  183. (define new-L (vector-cross-product U new-H))
  184. (define new-orient (list new-H new-L U))
  185. (apply set-orient! t new-orient))