Created
June 8, 2015 20:19
-
-
Save RenaissanceBug/d9fc6ec65566a043377d to your computer and use it in GitHub Desktop.
Circular graphs of functions in modular arithmetic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang typed/racket/base | |
#| | |
Drawing function graphs on a circle, in modular arithmetic. | |
jmj, 8 June 2015. | |
See also: | |
http://stephanainley.com/shapes2/# | |
http://blog.recursiveprocess.com/2015/04/28/linear-modulus-art/ | |
|# | |
(require math/array racket/match (only-in racket/math pi)) | |
(require/typed 2htdp/image | |
[#:opaque Image image?] | |
[empty-scene (Natural Natural -> Image)] | |
[scene+line | |
(Image Number Number Number Number Symbol -> Image)] | |
[place-image | |
(Image Number Number Image -> Image)] | |
[text (String Number Symbol -> Image)]) | |
(require/typed 2htdp/universe | |
[animate (-> (-> Natural Image) Natural)]) | |
(define r 200) ;; Radius of the output circle | |
(define margin 40) ;; Between circle and edge of image | |
(define n-margin 20) ;; Between circle and number | |
;; Derived screen width and height: | |
(define W (* 2 (+ r margin))) | |
(define H W) | |
;; Center of the circle: | |
(define CTR (array #[(/ H 2) (/ W 2)])) | |
;; Background image and foreground colors: | |
(define BG (empty-scene W H)) | |
(define line-color 'black) | |
(define number-color 'red) | |
(define number-size 9) | |
;; Modulus for our arithmetic: | |
(: current-modulus (Parameterof Positive-Integer)) | |
(define current-modulus (make-parameter 360)) | |
;; Shorthand for setting the modulus: | |
(define-syntax-rule (with-mod m expr) | |
(parameterize ([current-modulus m]) expr)) | |
(: lines (->* ((-> Integer Integer)) (Boolean) Image)) | |
;; Draws a function graph on the circle for the mapping from | |
;; i to (f i) under the current modulus. Show the numbers if numbers?. | |
(define (lines f [numbers? #f]) | |
(for/fold ([img : Image BG]) ([i : Natural (in-range 0 (current-modulus))]) | |
(define img2 | |
(mk-line img (n/mod->array i) (n/mod->array (f i)) line-color)) | |
(if numbers? | |
(draw-number i (n/mod->array i (number-radius i)) img2) | |
img2))) | |
(: number-radius (-> Natural Nonnegative-Exact-Rational)) | |
;; determine a good radius for displaying the number i, adjusting for | |
;; the modulus and staggering even/odd numbers. | |
(define (number-radius i) | |
(if (>= (current-modulus) 90) | |
(abs ((if (even? i) + -) (+ r n-margin) (/ n-margin 2))) | |
(+ r n-margin))) | |
(: draw-number (-> Number (Array Number) Image Image)) | |
;; draws n at the given position onto the given image | |
(define (draw-number n p img) | |
(place-image (text (number->string n) number-size number-color) | |
(array-ref p #[0]) (array-ref p #[1]) img)) | |
(: mk-line (-> Image (Array Number) (Array Number) Symbol Image)) | |
;; draws a line from p1 to p2 in color c onto the given image | |
(define (mk-line img p1 p2 c) | |
(match-define (list x1 y1) (array->list p1)) | |
(match-define (list x2 y2) (array->list p2)) | |
(scene+line img x1 y1 x2 y2 c)) | |
(: n/mod->array (->* (Integer) (Nonnegative-Exact-Rational) (Array Number))) | |
;; converts n (modulo the current modulus) to an array representing a | |
;; point on a circle, using the given radius (default r). | |
(define (n/mod->array n [radius r]) | |
(define θ (* 2 pi (/ (modulo n (current-modulus)) (current-modulus)))) | |
(array+ CTR (array #[(* radius (cos θ)) (* radius (sin θ))]))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; Examples: | |
(lines (λ (i) i)) ; produces 360 points arranged in a circle | |
(lines (λ (i) (* 2 i))) ; cardiod (one cusp) | |
(lines (λ (i) (* 6 i))) ; five cusps | |
(with-mod 90 ; this makes it less dense | |
(lines (λ (i) (* 6 i)))) | |
(animate | |
(λ (shift) | |
(with-mod 90 (lines (λ (i) (+ shift (* 4 i))))))) | |
#| | |
Q: Linear functions seem to produce the most appealing images. | |
What other functions work well? | |
|# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment