;;Mardi 11 Mai

;;Language/add teachpack:
;;DrScheme/plt/teachpack/draw.ss
;;inclus au prochain chargement

;;methode directe:
(require (lib "draw.ss" "htdp"))
(require (lib "posn.ss" "lang"))


;;------------------------------------------------------------------------------



;;ouverture de la fenetre
(define +width+ 400) 
(define +heigth+ 450)
(start +width+ +heigth+)





;;------------------------------------------------------------------------------
;; Exo -1: Exemple d'operations elementaires du module draw.ss 
;;------------------------------------------------------------------------------


;;instanciation de points
(define p1 (make-posn 1 1))
(define p2 (make-posn (/ +width+ 2) 
		      (/ +heigth+ 2)))


;;fonction auxilliaire affichant a l'ecran le point specifie
(define (posn-info point)
  (printf "point: x=~a; y=~a ~n" 
	  (posn-x point) 
	  (posn-y point)))

(posn-info p2)


;;---------------------------------------------
;; Exemples de traces


(draw-solid-line p1 p2 'red)
;;couleur en option, black par defaut
;;couleurs: white, yellow, red, blue, green, black...
;;systeme de coordonnees: commence a partir du coin sup gauche, tete vers le bas.

(draw-circle p2 50) ;; centre, rayon
;;toute commande draw possede son alternative clear


(draw-solid-disk p2 50)
;;attendre un clic souris et renvoyer sa position 
(posn-info (wait-for-mouse-click))
(clear-solid-disk p2 50)

(draw-solid-rect p2 10 30 'blue)


;;attente
(sleep-for-a-while 0.02); en secs
(wait-for-mouse-click)

(stop)


;;------------------------------------------------------------------------------
;; Exo 0: Utilisation d'un repere virtuel de trace
;;------------------------------------------------------------------------------


;;Vu en cours: conversion repere virtuel -> repere ecran

(define +xmin+ -4) (define +xmax+ 4)
(define +ymin+ -1.1) (define +ymax+ 8.5)
(define +largeur+ 500) (define +hauteur+ 500)


(define xrng (- +xmax+ +xmin+)) ; sera utile tout-à-l'heure.
(define yrng (- +ymax+ +ymin+))
;;     Ensuite, les dimensions de la fenêtre, et les fonctions de
;;     conversion :
(define xfact (/ +largeur+ xrng))  ; facteur de conversion
(define yfact (/ +hauteur+ yrng))
(define (xconv x)
  (* xfact (- x +xmin+))) ; Vérifiez que c'est correct
(define (yconv y)
  (* yfact (- +ymax+ y))) ; Y fenêtre va vers le bas


;;fonctions de conversion dont vous avez besoin: cours
(define (pconv x y)
  (make-posn (xconv x) (yconv y)))


;;hors cours
(define (posn-conv point)
  (let ((x (xconv (posn-x point)))
	(y (yconv (posn-y point))))
    (make-posn x y)))
			 
(start +largeur+ +hauteur+)


;;------------------------------------------------------------------------------
;; Exo 1: Trace de fonctions dans le repere cartesien
;;------------------------------------------------------------------------------

;;fonction nettoyant l'ecran
(define (clear)
  (clear-solid-rect (make-posn 0 0) +largeur+ +hauteur+))

;;fonction affichant un simple point
(define (posn-plot point)
  (draw-circle point 1))


;;Soit un repere de trace defini par xmin/max, ymin/max,
;;largeur/hauteur, comme indique dans l'exercice 0 
;;
;;Soient les fonctions (posn-conv point) et (posn-plot point)
;;
;;
;;*Ecrire la procedure (plot-cartesian-function nb-steps function-1) qui affiche
;;sur l'ecran courant un trace de la fonction mathematique d'arite 1
;;(ie, a 1 parametre) 'function-1'.
;;
;;On tracera a l'ecran 'nb-steps' points.
;;
;;Ecrire une version avec un let nomme, puis une avec do


(define (plot-cartesian-function nb-steps function-1)
  (let ((delta (/ (- +xmax+ +xmin+) nb-steps))) 
    (let iter ((x +xmin+))
      (if (>= x +xmax+) 
	  'done
	  (let* ((f_x (make-posn x (function-1 x)))
		 (f_x_ecran (posn-conv f_x)))
	    (begin (posn-plot f_x_ecran)
		   (iter (+ x delta))))))))


(define (plot-cartesian-function2 nb-steps function-1)
  (let ((delta (/ (- +xmax+ +xmin+) nb-steps)))
    (do ((x +xmin+ (+ x delta)))
	((> x +xmax+) 'done)
      (let* ((f_x (make-posn x (function-1 x)))
	     (f_x_ecran (posn-conv f_x)))
	(posn-plot f_x_ecran)))))

;;------------------------------------------------------------------------------
;; Exo 4: Fractales / Courbe de Von Koch
;;------------------------------------------------------------------------------




;;Soit l'addition / la soustraction vectorielles:
(define (posn+ pa pb)
  (make-posn (+ (posn-x pa) (posn-x pb))
	     (+ (posn-y pa) (posn-y pb))))
	     

(define (posn- pa pb)
  (make-posn (- (posn-x pa) (posn-x pb))
	     (- (posn-y pa) (posn-y pb))))
	     

;;Soit la fonction calculant la position du point p interpolant
;;deux points p1 et p2 avec un facteur f tq:
;;f = 0 => p = p1 ; f = 0.5 => p = (p1 + p2)/2...
(define (posn-linear-interpolation p1 p2 factor)
  (let ((x1 (posn-x p1))
	(y1 (posn-y p1))
	(x2 (posn-x p2))
	(y2 (posn-y p2)))
    (make-posn (+ x1 (* (- x2 x1) factor))
	       (+ y1 (* (- y2 y1) factor)))))


;; Soit la fonction (point-rotate p alpha) retournant le point p'
;; image de p par rotation de l'angle alpha a partir de l'origine:
;; 
;; x' = cos(a) x - sin(a) y 
;; y' = sin(a) x + cos(a) y
(define (posn-rotate p alpha)  
  (let ((cs (cos alpha)) 
	(sn (sin alpha))
        (x (posn-x p)) 
	(y (posn-y p)))
    (make-posn (- (* cs x) (* sn y ))
	       (+ (* sn x) (* cs y)))))


;;Soit la fonction effectuant la rotation du point p autour du point
;;pO - au lieu de l'origine.
(define (posn-rotate-pO p pO alpha)
  (posn+ pO 
	 (posn-rotate (posn- p pO) alpha)))



;;* Ecrire une fonction (koch prof p0 p1) tracant la courbe de
;;  Koch entre les pts p0 et p1 de profondeur 'prof'
;;
;;Notes pour l'optisation, eventuellement:
;; -Pour eviter tout calcul redondant, on ecrira une version de
;; point-rotate-pO qui effectuera toujours une rotation de 60 degres
;;
;; -il s'agit de ne pas recalculer ces valeurs constantes:
(define 1_3 (/ 1 3))
(define 2_3 (/ 2 3))

(define (koch prof p0 p1 color)
  (if (= prof 0) 
      (draw-solid-line (posn-conv p0) (posn-conv p1) color)
      (let* ((p2 (posn-linear-interpolation p0 p1 1_3))
	     (p3 (posn-linear-interpolation p0 p1 2_3))
	     (p4 (posn-rotate-pO p3 p2 (/ pi 3)))
	     (newprof (- prof 1)))
	(begin (koch newprof p0 p2 color)
	       (koch newprof p2 p4 color)
	       (koch newprof p4 p3 color)
	       (koch newprof p3 p1 color)))))

(wait-for-mouse-click)
(clear)
(koch 5 (make-posn -2 0) (make-posn 2 0) 'red) 
      
