Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Erlang Mapping (Map)


May 13, 2021 Erlang


Table of contents


Erlang Mapping (Map)

Mapping is used to represent the association between keys and values. T his association is enclosed by the words """"" H ere's how to create a mapping of the string "key" to the value 42:

1>#{ "key"=>42}.
  #{"key" => 42}

Let's look directly at some interesting features from the example.

The following example shows how to use mapping to associate colors with alpha channels to calculate alpha blending, a technique that makes 3D objects transparent. E nter the following code into the color.erl file:

-module(color).

-export([new/4, blend/2]).

-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).

new(R,G,B,A) when ?is_channel(R), ?is_channel(G),
                  ?is_channel(B), ?is_channel(A) ->
    #{red => R, green => G, blue => B, alpha => A}.

blend(Src,Dst) ->
    blend(Src,Dst,alpha(Src,Dst)).

blend(Src,Dst,Alpha) when Alpha > 0.0 ->
    Dst#{
        red   := red(Src,Dst) / Alpha,
        green := green(Src,Dst) / Alpha,
        blue  := blue(Src,Dst) / Alpha,
        alpha := Alpha
    };
blend(_,Dst,_) ->
    Dst#{
        red   := 0.0,
        green := 0.0,
        blue  := 0.0,
        alpha := 0.0
    }.

alpha(#{alpha := SA}, #{alpha := DA}) ->
    SA + DA*(1.0 - SA).

red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->
    SV*SA + DV*DA*(1.0 - SA).
green(#{green := SV, alpha := SA}, #{green := DV, alpha := DA}) ->
    SV*SA + DV*DA*(1.0 - SA).
blue(#{blue := SV, alpha := SA}, #{blue := DV, alpha := DA}) ->
    SV*SA + DV*DA*(1.0 - SA).

Compile and test:

1> c(color).
{ok,color}
2> C1 = color:new(0.3,0.4,0.5,1.0).
 #{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3}
3> C2 = color:new(1.0,0.8,0.1,0.3).
 #{alpha => 0.3,blue => 0.1,green => 0.8,red => 1.0}
4> color:blend(C1,C2).
 #{alpha => 1.0,blue => 0.5,green => 0.4,red => 0.3}
5> color:blend(C2,C1).
 #{alpha => 1.0,blue => 0.38,green => 0.52,red => 0.51}

The explanation for the above example is as follows:

-define(is_channel(V), (is_float(V) andalso V >= 0.0 andalso V =< 1.0)).

First, the example above defines a macro is_channel, which is primarily useful for easy checking. I n most cases, macros are used for the convenience of using or simplifying syntax. M ore about macros can be referred to in Preprocessing.

new(R,G,B,A) when ?is_channel(R), ?is_channel(G),
                  ?is_channel(B), ?is_channel(A) ->
    #{red => R, green => G, blue => B, alpha => A}.

The function new/4 creates a new map that associates red, green, blue, and alpha with the initial values. W here the is_channel guarantees that only floats between 0.0 and 1.0 are legitimate values (including endpoint values of 0.0 and 1.0). N ote that you can only use the operator when you create a new map.

Call the function blend/2 as an argument using any color generated by the new/4 function, and you get the alpha blend of that color. O bviously, this result is determined by two maps.

The first thing the blend/2 function does is calculate the alpha channel:

alpha(#{alpha := SA}, #{alpha := DA}) ->
    SA + DA*(1.0 - SA).

The value associated with the key alpha is obtained as the value of the argument using the : - operator. T he other keys in the map are ignored directly. Because only the key alpha and its value are required, only the key value pair in the map is checked.

For functions red/2, blue/2 and green/2 are the same:

red(#{red := SV, alpha := SA}, #{red := DV, alpha := DA}) ->
    SV*SA + DV*DA*(1.0 - SA).

The only difference is that two keys in each mapping parameter are checked and the other keys are ignored.

Finally, let's go back to the color returned by blend/3:

blend(Src,Dst,Alpha) when Alpha > 0.0 ->
    Dst#{
        red   := red(Src,Dst) / Alpha,
        green := green(Src,Dst) / Alpha,
        blue  := blue(Src,Dst) / Alpha,
        alpha := Alpha
    };

The Dst map is updated to a new channel value. Updating a map key value pair that already exists can use the : . . operator.