Mapping and Ranges in VL

December 11, 2015 posted by: tonfilm

As a vvvv user you are most probably familiar with the node Map (Value)node. You would use it whenever you have to map a value from one range to another.

For example you want to use a hardware sensor input in the range 0..1000 to control the vertical position of a visual element on the screen in -1..1 range. And since you want to make sure that the visual element never leaves the screen you set the Mappingpin to ‘Clamp’:

Mapping in vvvv

So far, so easy.

Mapping in VL

Let’s see if we can improve on that in VL.

First we make three important observations:

  1. The Map node does two things, it maps the value ranges and also knows how to handle input values which are outside the input range.
  2. The mapping mode almost never changes during run-time for a particular use case
  3. The specification for both, the input and output range is by Minimum and Maximum (or Center and Width if you use MapRange (Value)node ).

So we separated all functionality in VL to gain flexibility in the following way:


We introduced the concept of a Range. Its a simple generic data type that works for every type and has just two fields and two operations:

Range VL Type

If the datatype has the operators +, - and * (Scale) defined, which is the case for numbers and vectors in VL, there are Center/Width nodes that you can use with it:

Range Type Nodes

Range Handling

The mapping mode was a second functionality of the vvvv node and is now a separate story. We have a bunch of nodes which handle an input value that is outside a specific range in a certain way:

Map Modes


The map node itself got pretty simple and just does what its name says, mapping the input from one range to another:

Map Node

Convenience Nodes

Although the above nodes give the maximum flexibility, you would need to patch a few of them together for every use case. So of course we have convenient nodes that should cover most applications.

Since its often needed, the range from Zero to One:


We made for all nodes a version that takes Minimum and Maximum, one that takes Range and some which work with UnitRange:

Map Map (Range)

Clamp Clamp (Range) Clamp (UnitRange) Wrap Wrap (Range) Frac -> same as Wrap (UnitRange) Mirror Mirror (Range) Mirror (UnitRange)

There is also Mapping and Range Handling together:

MapClamp MapClamp (Range) MapWrap MapWrap (Range) MapMirror MapMirror (Range) MapDelegate MapDelegate (Range)

All nodes are generic and work for numbers, vectors and custom types alike.

Happy Mapping!


Comments are no longer accepted for this post.

11.12.2015 - 18:59

if the way to go is to have nodes for various combinations of functions of an old-node, maybe its more friendly to be specific to all of them ?

  • Map (MinMax)
  • Map (Range)
  • Map (UnitRange)
11.12.2015 - 21:24
how is Range or especially UnitRange handled internally? i find myself converting to input range to unitrange to output range all the time, just to apply non-linear interpolation. maybe a good point to hook in tweening cleverly…
14.12.2015 - 21:31


yes, a big part of the library is patched. it is very convenient because you can use adaptive nodes to make patches which work with many different data types which is what you want in a library.

concerning the UI question, the hidden (or much less space consuming) values in pins will be back in a later UI iteration. list as well of course… but not dates are fixed yet.

17.12.2015 - 13:54
values in pins…hurra ! thanks
17.12.2015 - 15:30

… or a much less space consuming solution ;)

having hidden values in pins is a bad concept in most scenarios. up to now there is no final decision on how it will look, but its clear that if a pin has a value other than it’s default, there has to be visual representation for it.

17.12.2015 - 23:06

it is a bad concept to not indicate a change,yes and to solve the problem with extra nodes too

hello color

20.12.2015 - 12:17
hey tonfilm i think it depends on the perfomance of the GUI, we know that IOBox’s takes most of the processor performance on huge patches, so why do same in VL, maybe try two types pin and field with representation of value. Pin just a connector between patches (however would be nice to see all that it holds inside with inspektor) and field is kinda slider with graphics representation of value.
20.12.2015 - 16:05


the value box in VL is something very different then the one in vvvv. the code is also different and does not do as much as the vvvv IOBox, so you cannot compare it in that way. but we are aware of the performance problem and we will work on that of course.

11.12.2015 - 22:48
interesting point @woei. most nodes convert to unit range internally and than to output range. there could be one Map node with an additional delegate input that gets the input value mapped to unit range as input and should output the value in unit range as well…
11.12.2015 - 22:58

not sure about adding the MinMax version @ggml because the style is always to have no version title for the most basic node version. also in the nodebrowser you will see the signature of the node if you hover with the mouse over it:

Signature in node

11.12.2015 - 23:23


added MapDelegate and MapDelegate (Range) that lets you specify what to do in the unit range as a region or a node with delegate input. does this cover your use cases?

12.12.2015 - 10:05

looking at the map image, i still find it hard to see an improvement compared to vvvv

while in vvvv i just need a map node, in vl it seems i need 7 nodes to achieve the same setup. this makes the patches crowded but also requires a lot more user interaction. i dont want to imagine how my patches would look like with that kind of noise..

12.12.2015 - 14:48


…which naturally includes the case on your second picture.

14.12.2015 - 12:37


delegate version look good! what would happen, if you go beyond unitrange in within the region? outofrange exception? guessing the math behind all this i also guess a 0 range will lead to a division by zero exception… any way for the user to handle these cases?

14.12.2015 - 19:05

@tonfilm, probably need to get used to the fact the whole language is patched anyway.

concerning ioboxes, values hidden in pins might confuse a beginner but it allows to distinguish between important values and not so important.. making the patch more readable.

question: is there a way to have spreaded ioboxes like a list ?

14.12.2015 - 21:18

@woei the mapping code looks like this:

nothing special will happen if you return values outside the unit range. the input range will throw a division by zero exception if From and To is the same. i thought about an if region around this part… but then decided against it because of performance. if it creates problems we can update the internals… as a user you can check From==To before the Map and cover the case in the delegate.



vvvv - Dießl & Gregor GbR
Oranienstrasse 10
10997 Berlin/Germany
VAT: DE275566955


Follow us

Sign up for our Newsletter

Your subscription could not be saved. Please try again.
Your subscription has been successful.