Advertisement
Guest User

Untitled

a guest
Sep 18th, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 7.77 KB | None | 0 0
  1. #lang racket/gui
  2.  
  3. (require racket/gui/base)
  4.  
  5. ;; sizes
  6. (define canvas-width 800)
  7. (define canvas-height 600)
  8. (define offset-x 30) ; moves grid right
  9. (define offset-y 30) ; moves grid up
  10. (define actual-width (- canvas-width 16)) ; window padding
  11. (define actual-height (- canvas-height 40)) ; window padding
  12. (define grid-width (- actual-width offset-x))
  13. (define grid-height (- actual-height offset-y))
  14. (define point-width 4)
  15.  
  16. ;; window
  17. (define frame (new frame% [label "Graph"] [width canvas-width] [height canvas-height]))
  18. (define canvas (new canvas% [parent frame]))
  19. (define context (send canvas get-dc))
  20.  
  21. ;; pens
  22. (define thin-pen (new pen% [color "lightgray"] [width 0.5] [style 'dot])) ; gridlines
  23. (define thick-pen (new pen% [color "black"] [width 1.5] [style 'solid])) ; axis
  24. (define red-pen (new pen% [color "red"] [width 1] [style 'solid])) ; lines
  25.  
  26. ;; brush
  27. (define point-brush (new brush% [color "black"])) ; points
  28.  
  29. (send context set-brush point-brush)
  30.  
  31. ;; fonts
  32. (define title-font (make-object font% 12 'roman 'italic)) ; axis titles
  33. (define label-font (make-object font% 6 'roman 'normal 'light)) ; axis numbers/labels
  34.  
  35.  
  36. ;; label axis numbers
  37. (define (label-number axis label x/y increment lines-per-increment)
  38.   (let ([n (if (integer? (inexact->exact (/ (* label increment) lines-per-increment)))
  39.                (inexact->exact (/ (* label increment) lines-per-increment))
  40.                (string->number (real->decimal-string (/ (* label increment) lines-per-increment) 3)))])
  41.     (let-values ([(label-width label-height base-whitespace extra-vertical)
  42.                   (send context get-text-extent (number->string n))])
  43.       (cond
  44.         [(eq? axis 'x)
  45.          (send context draw-text (number->string n) (- x/y (/ label-width 2)) (add1 grid-height))]
  46.         [(eq? axis 'y)
  47.          (send context draw-text (number->string n) (- offset-x label-width 1) (- x/y (/ label-height 2)))]))))
  48.  
  49.  
  50. ;; grid drawing
  51. (define (draw-grid x-title ; x-axis title
  52.                    x-interval ; range of x-axis values (cons lower upper)
  53.                    x-increment ; how much labels on x-axis increase
  54.                    lines-per-x-increment ; added lines for each value in range
  55.                    y-title
  56.                    y-interval
  57.                    y-increment
  58.                    lines-per-y-increment)
  59.   ;; AXIS TITLES
  60.   (send context set-font title-font)
  61.  
  62.   ;; x-axis title
  63.   (let-values ([(title-width ; width in px of `x-title`
  64.                  title-height ; height in px of `x-title`
  65.                  base-whitespace
  66.                  extra-vertical)
  67.                 (send context get-text-extent x-title)])
  68.     (send context draw-text x-title (/ (+ offset-x canvas-width title-width) 2) (- actual-height (/ (+ offset-y (/ title-height 2)) 2))))
  69.  
  70.   ;; y-axis title
  71.   (let-values ([(title-width title-height base-whitespace extra-vertical)
  72.                 (send context get-text-extent y-title)])
  73.     (send context draw-text y-title 0 (/ (- grid-height title-width) 2) #f 0 (/ pi 2)))
  74.  
  75.   ;; AXIS
  76.   (send context set-pen thick-pen)
  77.  
  78.   ;; draw axis
  79.   (send context draw-line offset-x grid-height canvas-width grid-height) ; x-axis
  80.   (send context draw-line offset-x 0 offset-x grid-height) ; y-axis
  81.  
  82.   ;; arrow heads
  83.   (send context draw-lines (list (make-object point% (- offset-x 2) 2)
  84.                                  (make-object point% offset-x 0)
  85.                                  (make-object point% (+ offset-x 2) 2)))
  86.   (send context draw-lines (list (make-object point% (- actual-width 2) (- grid-height 2))
  87.                                  (make-object point% actual-width grid-height)
  88.                                  (make-object point% (- actual-width 2) (+ grid-height 2))))
  89.  
  90.   ;; GRIDLINES AND LABELS
  91.   (send context set-pen thin-pen)
  92.   (send context set-font label-font)
  93.  
  94.   (let* ([interval-width (- (cdr x-interval) (car x-interval))] ; change in values along x-axis
  95.          [interval-height (- (cdr y-interval) (car y-interval))]
  96.          [num-x-lines (/ (* interval-width lines-per-x-increment) x-increment)] ; number of vertical lines in grid (not including y-axis)
  97.          [num-y-lines (/ (* interval-height lines-per-y-increment) y-increment)]
  98.          [cell-width (/ (- grid-width 5) num-x-lines)] ; distance bewteen vertical lines
  99.          [cell-height (/ (- grid-height 5) num-y-lines)])
  100.  
  101.     (label-number 'x 0 offset-x x-increment lines-per-x-increment) ; 0
  102.    
  103.     ;; y-axis gridlines
  104.     (for ([i (in-range 1 (add1 (* num-y-lines y-increment)))])
  105.       (let ([y (- grid-height (/ (* i cell-height) y-increment))])
  106.         (send context draw-line offset-x y actual-width y)
  107.  
  108.         ;; y-axis labels
  109.         (cond [(= (remainder i lines-per-y-increment) 0)
  110.             (label-number 'y i y y-increment lines-per-y-increment)])))
  111.  
  112.     ;; x-axis gridlines
  113.     (for ([i (in-range 1 (add1 num-x-lines))])
  114.       (let ([x (+ offset-x (/ (* i cell-width) 1))])
  115.         (send context draw-line x 0 x grid-height)
  116.  
  117.         ;; x-axis labels
  118.         (cond [(= (remainder i lines-per-x-increment) 0)
  119.                (label-number 'x i x x-increment lines-per-x-increment)])))))
  120.  
  121.  
  122. ;; convert x-values on grid to within the frame/window
  123. (define (grid-x->frame-x x precision-offset interval-width num-points precision)
  124.   (+ (/ (* grid-width (+ x (/ precision-offset precision))) num-points) offset-x))
  125.  
  126.  
  127. ;; compute y-values and convert them to within the frame/window
  128. (define (grid-x->frame-y x f precision-offset interval-width interval-height num-points precision)
  129.   (- grid-height (* (f (/ (* (+ x (/ precision-offset precision)) interval-width) num-points)) (/ grid-height interval-height))))
  130.  
  131.  
  132. (define (draw-connecting-curve f x interval-width interval-height num-points precision)
  133.   (for ([i (* num-points precision)])
  134.     (send context draw-line (grid-x->frame-x x (sub1 i) interval-width num-points precision)
  135.                             (grid-x->frame-y x f (sub1 i) interval-width interval-height num-points precision)
  136.                             (grid-x->frame-x x i interval-width num-points precision)
  137.                             (grid-x->frame-y x f i interval-width interval-height num-points precision))))
  138.  
  139.  
  140. (define (draw-curve f interval-width interval-height num-points precision)
  141.   (send context set-pen red-pen)
  142.  
  143.   (for ([i (* num-points precision)])    
  144.       (draw-connecting-curve f i interval-width interval-height num-points precision)))  
  145.  
  146.  
  147. (define (plot-points f interval-width interval-height num-points precision)
  148.   (send context set-pen thick-pen)
  149.  
  150.   (for ([i num-points])    
  151.     (send context draw-ellipse (+ (- (/ (* grid-width i) num-points) (/ point-width 2)) offset-x)
  152.                                (- grid-height (* (f (/ (* i interval-width) num-points)) (/ grid-height interval-height)) (/ point-width 2))
  153.                                ;; (- grid-height (* interval-height (f (* i num-points))) (/ point-width 2))
  154.                                point-width
  155.                                point-width)))
  156.  
  157.  
  158. (define (plot f x-interval y-interval num-points precision)
  159.   (let* ([interval-width (- (cdr x-interval) (car x-interval))]
  160.          [interval-height (- (cdr y-interval) (car y-interval))])
  161.     (draw-curve f interval-width interval-height num-points precision)
  162.     (plot-points f interval-width interval-height num-points precision)))
  163.  
  164.  
  165. (send frame show #t)
  166.  
  167. (sleep/yield 1)
  168.  
  169.  
  170. ;; calls
  171. (draw-grid "n" (cons 0 10) 1 4 "{a(n)}" (cons 0 20) 1 1)
  172. ;; (draw-grid-mod 20 20 (lambda (x) (/ 10 x)) (lambda (y) y))
  173.  
  174.  
  175. (define e (exp 1))
  176.  
  177. ;; Stirling approximation for efficiency
  178. (define (factorial n)
  179.   (* (sqrt (* 2 pi n))
  180.      (expt (/ n e) n)))
  181.  
  182.  
  183. ;; (plot (lambda (x) (abs (* x (sin (factorial x))))) (cons 0 2) (cons 0 2) 10 10)
  184. (plot (lambda (x) (+ (abs (sin x)) (* 2 x))) (cons 0 10) (cons 0 20) 20 10)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement