Skip to content

Commit 7cac420

Browse files
committed
Add angle option, and cleanup
1 parent fdef301 commit 7cac420

File tree

6 files changed

+78
-42
lines changed

6 files changed

+78
-42
lines changed

DomainColoringToy/Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
name = "DomainColoringToy"
22
uuid = "7cf40ad8-af6a-4ede-b3c6-2a9df3bce851"
33
authors = ["Evert Provoost <evert@eprovst.net>"]
4-
version = "0.2.0"
4+
version = "0.3.0"
55

66
[deps]
77
DomainColoring = "c24f3079-adb7-4533-8329-9f66732e5e85"
88
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
99

1010
[compat]
11-
DomainColoring = "0.4"
11+
DomainColoring = "0.5"
1212
GLMakie = "0.8"
1313
julia = "1.6"

DomainColoringToy/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
</p>
1010
<p>
1111
Interactive domain colorings and checker plots of complex functions in Julia using smooth colors,
12-
based on <a href="https://makie.org/">MakieGL</a>.
12+
based on <a href="https://makie.org/">GLMakie</a>.
1313
</p>

DomainColoringToy/src/DomainColoringToy.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ end
110110
f :: "Complex -> Complex",
111111
limits = (-1, 1, -1, 1);
112112
pixels = (480, 480),
113+
angle = true,
113114
abs = false,
114115
grid = false,
115116
all = false,
@@ -137,6 +138,8 @@ to ``\\frac{2\\pi}{3}``, cyan to ``\\pi``, blue to
137138
for both if only one number is provided. If either is `:auto`, the
138139
viewport resolution is used.
139140

141+
- **`angle`** toggles coloring of the phase angle.
142+
140143
- **`abs`** toggles the plotting of the natural logarithm of the
141144
magnitude as lightness ramps between level curves. If set to a number,
142145
this will be used as base of the logarithm instead, if set to `Inf`,
@@ -157,13 +160,20 @@ function domaincolor(
157160
f,
158161
limits = (-1, 1, -1, 1);
159162
pixels = (480, 480),
163+
angle = true,
160164
abs = false,
161165
grid = false,
162166
all = false,
163167
)
164168

169+
# issue warning if everything is inactive
170+
if Base.all(b -> b isa Bool && !b, [angle, abs, grid, all])
171+
@warn "angle, abs, and grid are all false, domain coloring will be a constant color."
172+
end
173+
165174
interactiveshadedplot(
166-
f, w -> DC.domaincolorshader(w; abs, grid, all), limits, pixels)
175+
f, w -> DC.domaincolorshader(w; angle, abs, grid, all),
176+
limits, pixels)
167177
end
168178

169179
"""

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DomainColoring"
22
uuid = "c24f3079-adb7-4533-8329-9f66732e5e85"
33
authors = ["Evert Provoost <evert@eprovst.net>"]
4-
version = "0.4.1"
4+
version = "0.5.0"
55

66
[deps]
77
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"

docs/src/usage/general.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,6 @@ The harshness of these white an black areas can be changed using the
203203
```julia
204204
domaincolor(z -> exp(1/z), .1, abs=(base=Inf, sigma=0.001))
205205
```
206+
207+
Finally, if one wants any of the previous plots without coloring the
208+
phase angle, they can use `angle = false`.

src/DomainColoring.jl

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,24 @@ function shadedplot(
118118

119119
limits = _expandlimits(limits)
120120

121-
r = [limits[1], limits[2]]
122-
i = [limits[3], limits[4]]
123121
# 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)';
125125
interpolate=true, axis=(autolimitaspect=1,),)
126126
end
127127

128+
@enum GridType begin
129+
CheckerGrid
130+
LineGrid
131+
end
128132

129133
# 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
131135
# `checkerplot`.
132136
function _grid(
133-
w,
134-
checker;
137+
type,
138+
w;
135139
real = false,
136140
imag = false,
137141
rect = false,
@@ -175,38 +179,45 @@ function _grid(
175179
end
176180

177181
# 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)
180184
(angle isa Bool && angle) && (angle = 6)
181-
(abs isa Bool && abs) && (abs = 1)
185+
(abs isa Bool && abs) && (abs = 1)
182186

183187
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))
186191
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))
189195
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))
193203
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))
196207
end
197208

198-
if checker
199-
min(1, sign(g) + 1)
200-
else
209+
if type == CheckerGrid
210+
float(g > 0)
211+
elseif type == LineGrid
201212
Base.abs(g)^0.06
202213
end
203214
end
204215

205-
_grid(w, checker, args::NamedTuple) = _grid(w, checker; args...)
216+
_grid(type, w, args::NamedTuple) = _grid(type, w; args...)
206217

207-
_grid(w, checker, arg::Bool) = arg ? _grid(w, checker) : 1.0
218+
_grid(type, w, arg::Bool) = arg ? _grid(type, w) : 1.0
208219

209-
_grid(w, checker, arg) = _grid(w, checker; rect=arg)
220+
_grid(type, w, arg) = _grid(type, w; rect=arg)
210221

211222
# Implements the magnitude logic for `domaincolorshader`
212223
# isnothing(transform) gives the default log, and saves us
@@ -215,7 +226,7 @@ _grid(w, checker, arg) = _grid(w, checker; rect=arg)
215226
function _add_magnitude(
216227
w,
217228
c;
218-
base = exp(1),
229+
base = ,
219230
transform = nothing,
220231
sigma = 0.02,
221232
)
@@ -231,11 +242,9 @@ function _add_magnitude(
231242
isfinite(m) && (c = Lab(c.l + 20mod(m, 1) - 10, c.a, c.b))
232243
else
233244
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)
239248
end
240249
end
241250
return c
@@ -265,12 +274,15 @@ See [Phase Wheel](@ref) for more information.
265274
"""
266275
function labsweep(θ)
267276
θ = 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)
269280
end
270281

271282
"""
272283
DomainColoring.domaincolorshader(
273284
w :: Complex;
285+
angle = true,
274286
abs = false,
275287
grid = false,
276288
all = false,
@@ -282,27 +294,29 @@ For documentation of the remaining arguments see [`domaincolor`](@ref).
282294
"""
283295
function domaincolorshader(
284296
w;
297+
angle = true,
285298
abs = false,
286299
grid = false,
287300
all = false,
288301
)
289302

290303
# user wants full domain coloring
291304
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)
294308
end
295309

296310
# phase color
297-
c = labsweep(angle(w))
311+
c = angle ? labsweep(Base.angle(w)) : Lab(80.0, 0.0, 0.0)
298312

299313
# add magnitude
300314
c = _add_magnitude(w, c, abs)
301315

302316
# add integer grid if requested
303317
if !(grid isa Bool) || grid
304318
# slightly overattenuate to compensate global darkening
305-
g = 1.06_grid(w, false, grid)
319+
g = 1.06_grid(LineGrid, w, grid)
306320
c = mapc(x -> g*x, c)
307321
end
308322

@@ -314,6 +328,7 @@ end
314328
f :: "Complex -> Complex",
315329
limits = (-1, 1, -1, 1);
316330
pixels = (720, 720),
331+
angle = true,
317332
abs = false,
318333
grid = false,
319334
all = false,
@@ -340,6 +355,8 @@ to ``\\frac{2\\pi}{3}``, cyan to ``\\pi``, blue to
340355
real and imaginary axis, taking the same for both if only one number
341356
is provided.
342357

358+
- **`angle`** toggles coloring of the phase angle.
359+
343360
- **`abs`** toggles the plotting of the natural logarithm of the
344361
magnitude as lightness ramps between level curves. If set to a number,
345362
this will be used as base of the logarithm instead, if set to `Inf`,
@@ -360,13 +377,19 @@ function domaincolor(
360377
f,
361378
limits = (-1, 1, -1, 1);
362379
pixels = (720, 720),
380+
angle = true,
363381
abs = false,
364382
grid = false,
365383
all = false,
366384
)
367385

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+
368391
shadedplot(f, w -> domaincolorshader(
369-
w; abs, grid, all
392+
w; angle, abs, grid, all
370393
), limits, pixels)
371394
end
372395

@@ -497,7 +520,7 @@ function checkerplotshader(
497520
polar = false,
498521
)
499522

500-
g = _grid(w, true; real, imag, rect, angle, abs, polar)
523+
g = _grid(CheckerGrid, w; real, imag, rect, angle, abs, polar)
501524
return Gray(0.9g + 0.08)
502525
end
503526

0 commit comments

Comments
 (0)