Skip to content
Snippets Groups Projects
Commit 914d7c13 authored by Dieter Weber's avatar Dieter Weber
Browse files

Fix clipping of rgb_from_vector()

* Clip saturation and luminance separately to make sure the result is clipped
  at the maximum possible saturation or luminance
* Ensure that the argument of np.arccos(...) is within the allowed range
  to avoid NaN
parent e85a58da
No related branches found
No related tags found
2 merge requests!2Fix clipping of rgb_from_vector(),!1Fix clipping of rgb_from_vector()
Pipeline #51673 failed
...@@ -65,8 +65,6 @@ class Colormap3D(colors.Colormap, metaclass=abc.ABCMeta): ...@@ -65,8 +65,6 @@ class Colormap3D(colors.Colormap, metaclass=abc.ABCMeta):
""" """
self._log.debug('Calling rgb_from_vector') self._log.debug('Calling rgb_from_vector')
x, y, z = vector x, y, z = vector
R = np.sqrt(x ** 2 + y ** 2 + z ** 2)
R_max = vmax if vmax is not None else R.max() + 1E-30
# FIRST color dimension: HUE (1D ring/angular direction) # FIRST color dimension: HUE (1D ring/angular direction)
phi = np.asarray(np.arctan2(y, x)) phi = np.asarray(np.arctan2(y, x))
phi[phi < 0] += 2 * np.pi phi[phi < 0] += 2 * np.pi
...@@ -74,11 +72,14 @@ class Colormap3D(colors.Colormap, metaclass=abc.ABCMeta): ...@@ -74,11 +72,14 @@ class Colormap3D(colors.Colormap, metaclass=abc.ABCMeta):
rgba = np.asarray(self(hue)) rgba = np.asarray(self(hue))
r, g, b = rgba[..., 0], rgba[..., 1], rgba[..., 2] r, g, b = rgba[..., 0], rgba[..., 1], rgba[..., 2]
# SECOND color dimension: SATURATION (2D, in-plane) # SECOND color dimension: SATURATION (2D, in-plane)
rho = np.sqrt(x ** 2 + y ** 2) rho = np.sqrt(np.abs(x)**2 + np.abs(y)**2)
sat = rho / R_max rho_max = vmax if vmax is not None else rho.max() + 1E-30
sat = np.minimum(rho, rho_max) / rho_max
r, g, b = interpolate_color(sat, (0.5, 0.5, 0.5), np.stack((r, g, b), axis=-1)) r, g, b = interpolate_color(sat, (0.5, 0.5, 0.5), np.stack((r, g, b), axis=-1))
# THIRD color dimension: LUMINANCE (3D, color sphere) # THIRD color dimension: LUMINANCE (3D, color sphere)
theta = np.arccos(z / R_max) z_max = vmax if vmax is not None else np.abs(z).max() + 1E-30
z_clipped = np.minimum(np.abs(z), z_max) / z_max
theta = np.arccos(z_clipped)
lum = 1 - theta / np.pi # goes from 0 (black) over 0.5 (grey) to 1 (white)! lum = 1 - theta / np.pi # goes from 0 (black) over 0.5 (grey) to 1 (white)!
lum_target = np.where(lum < 0.5, 0, 1) # Separate upper(white)/lower(black) hemispheres! lum_target = np.where(lum < 0.5, 0, 1) # Separate upper(white)/lower(black) hemispheres!
lum_target = np.stack([lum_target] * 3, axis=-1) # [0, 0, 0] -> black / [1, 1, 1] -> white! lum_target = np.stack([lum_target] * 3, axis=-1) # [0, 0, 0] -> black / [1, 1, 1] -> white!
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment