@@ -118,20 +118,24 @@ function shadedplot(
118
118
119
119
limits = _expandlimits(limits)
120
120
121
- r = [limits[1], limits[2]]
122
- i = [limits[3], limits[4]]
123
121
# images have inverted y and flip x and y in their storage
124
- heatmap(r, reverse(i), renderimage(f, shader, limits, pixels)';
122
+ r = [limits[1], limits[2]]
123
+ i = [limits[4], limits[3]]
124
+ heatmap(r, i, renderimage(f, shader, limits, pixels)';
125
125
interpolate=true, axis=(autolimitaspect=1,),)
126
126
end
127
127
128
+ @enum GridType begin
129
+ CheckerGrid
130
+ LineGrid
131
+ end
128
132
129
133
# Logic for grid like plotting elements, somewhat ugly, but it works.
130
- # `w` is the complex value, `checker ` is a boolean for the others see
134
+ # `w` is the complex value, `type ` is the type of grid to make
131
135
# `checkerplot`.
132
136
function _grid(
133
- w ,
134
- checker ;
137
+ type ,
138
+ w ;
135
139
real = false,
136
140
imag = false,
137
141
rect = false,
@@ -175,38 +179,45 @@ function _grid(
175
179
end
176
180
177
181
# set defaults
178
- (real isa Bool && real) && (real = 1)
179
- (imag isa Bool && imag) && (imag = 1)
182
+ (real isa Bool && real) && (real = 1)
183
+ (imag isa Bool && imag) && (imag = 1)
180
184
(angle isa Bool && angle) && (angle = 6)
181
- (abs isa Bool && abs) && (abs = 1)
185
+ (abs isa Bool && abs) && (abs = 1)
182
186
183
187
g = 1.0
184
- if real > 0 && isfinite(4*real*Base.real(w))
185
- g *= sin(real*π*Base.real(w))
188
+ if real > 0
189
+ r = real * π * Base.real(w)
190
+ isfinite(r) && (g *= sin(r))
186
191
end
187
- if imag > 0 && isfinite(4*imag*Base.imag(w))
188
- g *= sin(imag*π*Base.imag(w))
192
+ if imag > 0
193
+ i = imag * π * Base.imag(w)
194
+ isfinite(i) && (g *= sin(i))
189
195
end
190
- if angle > 0 && isfinite(angle*Base.angle(w))
191
- checker && @assert iseven(angle) "Rate of angle has to be even."
192
- g *= sin(angle/2*Base.angle(w))
196
+ if angle > 0
197
+ @assert mod(angle, 1) ≈ 0 "Rate of angle has to be an integer."
198
+ angle = round(angle)
199
+ (type == CheckerGrid) && @assert iseven(angle) "Rate of angle has to be even."
200
+
201
+ a = angle / 2 * Base.angle(w)
202
+ isfinite(a) && (g *= sin(a))
193
203
end
194
- if abs > 0 && isfinite(4*abs*log(Base.abs(w)))
195
- g *= sin(abs*π*log(Base.abs(w)))
204
+ if abs > 0
205
+ m = abs * π * log(Base.abs(w))
206
+ isfinite(m) && (g *= sin(m))
196
207
end
197
208
198
- if checker
199
- min(1, sign(g) + 1 )
200
- else
209
+ if type == CheckerGrid
210
+ float(g > 0 )
211
+ elseif type == LineGrid
201
212
Base.abs(g)^0.06
202
213
end
203
214
end
204
215
205
- _grid(w, checker , args::NamedTuple) = _grid(w, checker ; args...)
216
+ _grid(type, w , args::NamedTuple) = _grid(type, w ; args...)
206
217
207
- _grid(w, checker , arg::Bool) = arg ? _grid(w, checker ) : 1.0
218
+ _grid(type, w , arg::Bool) = arg ? _grid(type, w ) : 1.0
208
219
209
- _grid(w, checker , arg) = _grid(w, checker ; rect=arg)
220
+ _grid(type, w , arg) = _grid(type, w ; rect=arg)
210
221
211
222
# Implements the magnitude logic for `domaincolorshader`
212
223
# isnothing(transform) gives the default log, and saves us
@@ -215,7 +226,7 @@ _grid(w, checker, arg) = _grid(w, checker; rect=arg)
215
226
function _add_magnitude(
216
227
w,
217
228
c;
218
- base = exp(1) ,
229
+ base = ℯ ,
219
230
transform = nothing,
220
231
sigma = 0.02,
221
232
)
@@ -231,11 +242,9 @@ function _add_magnitude(
231
242
isfinite(m) && (c = Lab(c.l + 20mod(m, 1) - 10, c.a, c.b))
232
243
else
233
244
m = log(abs(w))
234
- if isfinite(m)
235
- t = exp(-sigma*m^2)
236
- g = 100(sign(m)/2 + .5)
237
- c = Lab((1 - t)g + t*c.l, t*c.a, t*c.b)
238
- end
245
+ t = isfinite(m) ? exp(-sigma*m^2) : 0.0
246
+ g = 100.0(m > 0)
247
+ c = Lab((1 - t)g + t*c.l, t*c.a, t*c.b)
239
248
end
240
249
end
241
250
return c
@@ -265,12 +274,15 @@ See [Phase Wheel](@ref) for more information.
265
274
"""
266
275
function labsweep(θ)
267
276
θ = mod(θ, 2π)
268
- Lab(67 - 12cos(3θ), 46cos(θ + .4) - 3, 46sin(θ + .4) + 16)
277
+ Lab(67 - 12cos(3θ),
278
+ 46cos(θ + .4) - 3,
279
+ 46sin(θ + .4) + 16)
269
280
end
270
281
271
282
"""
272
283
DomainColoring.domaincolorshader(
273
284
w :: Complex;
285
+ angle = true,
274
286
abs = false,
275
287
grid = false,
276
288
all = false,
@@ -282,27 +294,29 @@ For documentation of the remaining arguments see [`domaincolor`](@ref).
282
294
"""
283
295
function domaincolorshader(
284
296
w;
297
+ angle = true,
285
298
abs = false,
286
299
grid = false,
287
300
all = false,
288
301
)
289
302
290
303
# user wants full domain coloring
291
304
if all
292
- abs = true
293
- grid = true
305
+ (angle isa Bool) && (angle = true)
306
+ (abs isa Bool) && (abs = true)
307
+ (grid isa Bool) && (grid = true)
294
308
end
295
309
296
310
# phase color
297
- c = labsweep(angle(w))
311
+ c = angle ? labsweep(Base. angle(w)) : Lab(80.0, 0.0, 0.0 )
298
312
299
313
# add magnitude
300
314
c = _add_magnitude(w, c, abs)
301
315
302
316
# add integer grid if requested
303
317
if !(grid isa Bool) || grid
304
318
# slightly overattenuate to compensate global darkening
305
- g = 1.06_grid(w, false , grid)
319
+ g = 1.06_grid(LineGrid, w , grid)
306
320
c = mapc(x -> g*x, c)
307
321
end
308
322
314
328
f :: "Complex -> Complex",
315
329
limits = (-1, 1, -1, 1);
316
330
pixels = (720, 720),
331
+ angle = true,
317
332
abs = false,
318
333
grid = false,
319
334
all = false,
@@ -340,6 +355,8 @@ to ``\\frac{2\\pi}{3}``, cyan to ``\\pi``, blue to
340
355
real and imaginary axis, taking the same for both if only one number
341
356
is provided.
342
357
358
+ - **`angle`** toggles coloring of the phase angle.
359
+
343
360
- **`abs`** toggles the plotting of the natural logarithm of the
344
361
magnitude as lightness ramps between level curves. If set to a number,
345
362
this will be used as base of the logarithm instead, if set to `Inf`,
@@ -360,13 +377,19 @@ function domaincolor(
360
377
f,
361
378
limits = (-1, 1, -1, 1);
362
379
pixels = (720, 720),
380
+ angle = true,
363
381
abs = false,
364
382
grid = false,
365
383
all = false,
366
384
)
367
385
386
+ # issue warning if everything is inactive
387
+ if Base.all(b -> b isa Bool && !b, [angle, abs, grid, all])
388
+ @warn "angle, abs, and grid are all false, domain coloring will be a constant color."
389
+ end
390
+
368
391
shadedplot(f, w -> domaincolorshader(
369
- w; abs, grid, all
392
+ w; angle, abs, grid, all
370
393
), limits, pixels)
371
394
end
372
395
@@ -497,7 +520,7 @@ function checkerplotshader(
497
520
polar = false,
498
521
)
499
522
500
- g = _grid(w, true ; real, imag, rect, angle, abs, polar)
523
+ g = _grid(CheckerGrid, w ; real, imag, rect, angle, abs, polar)
501
524
return Gray(0.9g + 0.08)
502
525
end
503
526
0 commit comments