Skip to content

Commit

Permalink
Add bezier interpolation to colormap_class.
Browse files Browse the repository at this point in the history
- Add a new example to demo.f90.
  • Loading branch information
gha3mi committed Jan 28, 2024
1 parent 522212c commit 6954cf5
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
15 changes: 13 additions & 2 deletions example/demo.f90
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@
! SOFTWARE.
!-------------------------------------------------------------------------------
! Contributed by vmagnin: 2023-09-26
! Last modification: vmagnin 2023-10-19
! Last modification: gha3mi 2024-01-28
!-------------------------------------------------------------------------------

program demo
use forcolormap, only: Colormap, colormaps_list, wp
use forcolormap, only: Colormap, colormaps_list, wp, bezier
implicit none

integer :: i
type(Colormap) :: cmap, custom_cmap
integer, allocatable :: colors(:,:)
! A discrete colormap with 8 levels, from black to white:
integer, dimension(0:7, 3) :: my_colormap = reshape( [ &
0, 0, 0, &
Expand Down Expand Up @@ -68,6 +69,16 @@ program demo
call test_colormap(custom_cmap, 'a_loaded_colormap_test', encoding='binary')
call custom_cmap%print()

! You can also create your own colormap using bezier interpolation:
! Define control colors.
allocate(colors(3,3))
colors(1,:) = [255, 0, 0] ! Red
colors(2,:) = [0, 255, 0] ! Green
colors(3,:) = [0, 0, 255] ! Blue
call custom_cmap%create('custom_bezier', 0.0_wp, 2.0_wp, bezier(colors, levels=1024)) ! levels is optional, default is 256
call custom_cmap%colorbar('custom_colorbar_bezier', encoding='binary')
call test_colormap(custom_cmap, 'custom_test_bezier', encoding='binary')

contains

subroutine test_colormap(self, filename, encoding)
Expand Down
44 changes: 42 additions & 2 deletions src/colormap_class.f90
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
! SOFTWARE.
!-------------------------------------------------------------------------------
! Contributed by vmagnin: 2023-09-26
! Last modification: gha3mi 2024-01-06
! Last modification: gha3mi 2024-01-28
!-------------------------------------------------------------------------------


Expand All @@ -34,7 +34,7 @@ module forcolormap
implicit none
private

public :: wp
public :: wp, bezier

! List of built-in colormaps:
character(*), dimension(*), public, parameter :: colormaps_list = &
Expand Down Expand Up @@ -927,4 +927,44 @@ pure subroutine extract(self, extractedLevels, name, zmin, zmax, reverse)
end if
end subroutine extract

! Create colormap from continuous Bezier interpolation of control colors
pure function bezier(colors, levels) result(map)
integer, dimension(:,:), intent(in) :: colors
integer, intent(in), optional :: levels
integer, dimension(:,:), allocatable :: map
real(wp), dimension(:,:), allocatable :: map_r
integer :: order, i, j, levels_
real(wp) :: t

! Set default value for levels
if (present(levels)) then
levels_ = levels
else
levels_ = 256
end if

! Order of the Bezier curve
order = size(colors, 1) - 1

allocate(map_r(levels_,3), map(levels_,3)) ! 3 for RGB
do i = 1,levels_
t = real(i-1, wp) / real(levels_-1, wp)
map_r(i,:) = 0.0_wp
do j = 0, order
map_r(i,:) = map_r(i,:) + real(colors(j+1,:), wp)*&
real(factorial(order), wp)/(real(factorial(j), wp)*real(factorial(order-j), wp)) * t**j * (1.0_wp-t)**(order-j)
end do
map(i,:) = scale_real_int(map_r(i,:), 0, 255) ! Scale to integer RGB range
end do
end function bezier

! Factorial function used for Bezier interpolation
pure function factorial(n) result(result)
integer, intent(in) :: n
integer :: result, i
result = 1
do concurrent (i = 2:n)
result = result * i
end do
end function factorial
end module forcolormap

0 comments on commit 6954cf5

Please sign in to comment.