File: point.rkt

package info (click to toggle)
racket 7.2%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 125,432 kB
  • sloc: ansic: 258,980; pascal: 59,975; sh: 33,650; asm: 13,558; lisp: 7,124; makefile: 3,329; cpp: 2,889; exp: 499; python: 274; xml: 11
file content (201 lines) | stat: -rw-r--r-- 10,097 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#lang typed/racket/base

(require typed/racket/class racket/list racket/match
         plot/utils
         "../common/type-doc.rkt"
         "../common/utils.rkt")

(require/typed
 "../common/untyped-utils.rkt"
 [fix-vector-field3d-fun  (-> Symbol
                              (U (-> Real Real Real (Sequenceof Real))
                                 (-> (Vector Real Real Real) (Sequenceof Real)))
                              (-> Real Real Real (Vectorof Real)))])

(provide (all-defined-out))

;; ===================================================================================================

(: points3d-render-proc (-> (Listof (Vectorof Real)) Point-Sym
                            Plot-Color Plot-Color
                            Nonnegative-Real Nonnegative-Real
                            Nonnegative-Real
                            (U String #f)
                            3D-Render-Proc))
(define ((points3d-render-proc vs sym color fill-color size line-width alpha label) area)
  (send area put-alpha alpha)
  (send area put-pen color line-width 'solid)
  (send area put-brush fill-color 'solid)
  (send area put-glyphs vs sym size)
  
  (cond [label  (point-legend-entry label sym color fill-color size line-width)]
        [else   empty]))

(:: points3d
    (->* [(Sequenceof (Sequenceof Real))]
         [#:x-min (U Real #f) #:x-max (U Real #f)
          #:y-min (U Real #f) #:y-max (U Real #f)
          #:z-min (U Real #f) #:z-max (U Real #f)
          #:sym Point-Sym
          #:color Plot-Color
          #:fill-color (U Plot-Color 'auto)
          #:x-jitter Nonnegative-Real
          #:y-jitter Nonnegative-Real
          #:z-jitter Nonnegative-Real
          #:size Nonnegative-Real
          #:line-width Nonnegative-Real
          #:alpha Nonnegative-Real
          #:label (U String #f)]
         renderer3d))
(define (points3d vs
                  #:x-min [x-min #f] #:x-max [x-max #f]
                  #:y-min [y-min #f] #:y-max [y-max #f]
                  #:z-min [z-min #f] #:z-max [z-max #f]
                  #:sym [sym (point-sym)]
                  #:color [color (point-color)]
                  #:fill-color [fill-color 'auto]
                  #:x-jitter [x-jitter (point-x-jitter)]
                  #:y-jitter [y-jitter (point-y-jitter)]
                  #:z-jitter [z-jitter (point-z-jitter)]
                  #:size [size (point-size)]
                  #:line-width [line-width (point-line-width)]
                  #:alpha [alpha (point-alpha)]
                  #:label [label #f])
  (define fail/kw (make-raise-keyword-error 'points3d))
  (cond
    [(and x-min (not (rational? x-min)))  (fail/kw "#f or rational" '#:x-min x-min)]
    [(and x-max (not (rational? x-max)))  (fail/kw "#f or rational" '#:x-max x-max)]
    [(and y-min (not (rational? y-min)))  (fail/kw "#f or rational" '#:y-min y-min)]
    [(and y-max (not (rational? y-max)))  (fail/kw "#f or rational" '#:y-max y-max)]
    [(and z-min (not (rational? z-min)))  (fail/kw "#f or rational" '#:z-min z-min)]
    [(and z-max (not (rational? z-max)))  (fail/kw "#f or rational" '#:z-max z-max)]
    [(not (rational? size))  (fail/kw "rational?" '#:size size)]
    [(or (> alpha 1) (not (rational? alpha)))  (fail/kw "real in [0,1]" '#:alpha alpha)]
    [else
     (let* ([vs  (sequence->listof-vector 'points3d vs 3)]
            [vs  (filter vrational? vs)])
       (cond [(empty? vs)  (renderer3d #f #f #f #f)]
             [else
              (unless (= 0 x-jitter y-jitter z-jitter)
                (points-apply-jitters vs (vector x-jitter y-jitter z-jitter)
                                      #:ivls (vector (ivl x-min x-max)
                                                     (ivl y-min y-max)
                                                     (ivl z-min z-max))))
              (match-define (list (vector #{xs : (Listof Real)}
                                          #{ys : (Listof Real)}
                                          #{zs : (Listof Real)})
                                  ...)
                vs)
              (let ([x-min  (if x-min x-min (apply min* xs))]
                    [x-max  (if x-max x-max (apply max* xs))]
                    [y-min  (if y-min y-min (apply min* ys))]
                    [y-max  (if y-max y-max (apply max* ys))]
                    [z-min  (if z-min z-min (apply min* zs))]
                    [z-max  (if z-max z-max (apply max* zs))]
                    [fill-color  (if (eq? fill-color 'auto) (->pen-color color) fill-color)])
                (renderer3d
                 (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f default-ticks-fun
                 (points3d-render-proc vs sym color fill-color
                                       size line-width alpha label)))]))]))

;; ===================================================================================================

(: vector-field3d-render-fun
   (-> (-> Real Real Real (Vectorof Real))
       Positive-Integer (U Real 'auto 'normalized)
       Plot-Color Nonnegative-Real Plot-Pen-Style
       Nonnegative-Real
       (U String #f)
       3D-Render-Proc))
(define ((vector-field3d-render-fun f samples scale color line-width line-style alpha label) area)
  (match-define (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max))
    (send area get-bounds-rect))
  
  (cond
    [(and x-min x-max y-min y-max z-min z-max)
     (define xs0 (linear-seq x-min x-max samples #:start? #t #:end? #t))
     (define ys0 (linear-seq y-min y-max samples #:start? #t #:end? #t))
     (define zs0 (linear-seq z-min z-max samples #:start? #t #:end? #t))
     
     (define-values (vs dxs dys dzs norms mags)
       (for*/lists ([vs : (Listof (Vectorof Real))]
                    [dxs : (Listof Real)]
                    [dys : (Listof Real)]
                    [dzs : (Listof Real)]
                    [norms : (Listof (Vectorof Real))]
                    [mags : (Listof Nonnegative-Real)]
                    ) ([x   (in-list xs0)]
                       [y   (in-list ys0)]
                       [z   (in-list zs0)]
                       [dv  (in-value (f x y z))] #:when (vrational? dv))
         (match-define (vector dx dy dz) dv)
         (values (vector x y z) dx dy dz (vnormalize dv) (vmag dv))))
     
     (cond [(empty? vs)  empty]
           [else (define box-x-size (/ (- x-max x-min) samples))
                 (define box-y-size (/ (- y-max y-min) samples))
                 (define box-z-size (/ (- z-max z-min) samples))
                 
                 (define new-mags
                   (match scale
                     [(? real?)  (map (λ ([mag : Real]) (* scale mag)) mags)]
                     ['normalized  (make-list (length dxs) (min box-x-size box-y-size box-z-size))]
                     ['auto  (define dx-max (real->double-flonum (apply max (map abs dxs))))
                             (define dy-max (real->double-flonum (apply max (map abs dys))))
                             (define dz-max (real->double-flonum (apply max (map abs dzs))))
                             (define scale (min (/ box-x-size dx-max)
                                                (/ box-y-size dy-max)
                                                (/ box-z-size dz-max)))
                             (map (λ ([mag : Real]) (* scale mag)) mags)]))
                 
                 (send area put-alpha alpha)
                 (send area put-pen color line-width line-style)
                 (for ([v     (in-list vs)]
                       [norm  (in-list norms)]
                       [mag   (in-list new-mags)])
                   (send area put-arrow v (v+ v (v* norm mag))))
                 
                 (cond [label  (arrow-legend-entry label color line-width line-style)]
                       [else   empty])])]
    [else  empty]))

(:: vector-field3d
    (->* [(U (-> Real Real Real (Sequenceof Real))
             (-> (Vector Real Real Real) (Sequenceof Real)))]
         [(U Real #f) (U Real #f)
          (U Real #f) (U Real #f)
          (U Real #f) (U Real #f)
          #:samples Positive-Integer
          #:scale (U Real 'auto 'normalized)
          #:color Plot-Color
          #:line-width Nonnegative-Real
          #:line-style Plot-Pen-Style
          #:alpha Nonnegative-Real
          #:label (U String #f)]
         renderer3d))
(define (vector-field3d f [x-min #f] [x-max #f] [y-min #f] [y-max #f] [z-min #f] [z-max #f]
                        #:samples [samples (vector-field3d-samples)]
                        #:scale [scale (vector-field-scale)]
                        #:color [color (vector-field-color)]
                        #:line-width [line-width (vector-field-line-width)]
                        #:line-style [line-style (vector-field-line-style)]
                        #:alpha [alpha (vector-field-alpha)]
                        #:label [label #f])
  (define fail/pos (make-raise-argument-error 'vector-field3d f x-min x-max y-min y-max z-min z-max))
  (define fail/kw (make-raise-keyword-error 'vector-field3d))
  (cond
    [(and x-min (not (rational? x-min)))  (fail/pos "#f or rational" 1)]
    [(and x-max (not (rational? x-max)))  (fail/pos "#f or rational" 2)]
    [(and y-min (not (rational? y-min)))  (fail/pos "#f or rational" 3)]
    [(and y-max (not (rational? y-max)))  (fail/pos "#f or rational" 4)]
    [(and z-min (not (rational? z-min)))  (fail/pos "#f or rational" 5)]
    [(and z-max (not (rational? z-max)))  (fail/pos "#f or rational" 6)]
    [(and (real? scale) (not (rational? scale)))
     (fail/kw "'auto, 'normalized or rational" '#:scale scale)]
    [(not (rational? line-width))  (fail/kw "rational?" '#:line-width line-width)]
    [(or (> alpha 1) (not (rational? alpha)))  (fail/kw "real in [0,1]" '#:alpha alpha)]
    [else
     (let ([f  (fix-vector-field3d-fun 'vector-field3d f)])
       (renderer3d (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f default-ticks-fun
                   (vector-field3d-render-fun
                    f samples scale color line-width line-style alpha label)))]))