» Blog
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Blog

new post

Blog-posts are sorted by the tags you see below. You can filter the listing by checking/unchecking individual tags. Doubleclick or Shift-click a tag to see only its entries. For more informations see: About the Blog.

  reset tags

addon-release core-release date devvvv gallery news screenshot stuff
delicious flickr vimeo
Order by post date popularity

A classic: Pitch On Pole

Evvvveryone,

how about a random little feature? Hope you don't mind that it is about 15 years late...

Introducing: Rekorder (Windows)

Simply place the node in a patch (even save it in your _root.v4p), then press CTRL+4 to start recording on any(!) window and press it again to stop and save the recorded sequence to an animated GIF.

Available in latest alphas now!

This is not meant to replace other options for capturing output but more to easily create quick sketches. By default the recordings are saved to your desktop with an auto-generated filename. If you enable Auto Open they'll also automatically be displayed using the application you've registered to open .gif files once saving is complete. Note that saving a file may take a while, but since it happens in the background it won't block your workflow. Also beware that if you run a 32bit vvvversion you may run out of memory within a few seconds (in which case the recording will stop automatically).

Animated GIF

For now recording is limited to animated GIFs which is nice but also has quite some limitations: They can only deal with a limited number of different framerates (default for your recordings is 25fps) and can only have 256 different colors! In exchange you get nice ditherings..

Thank Code the whole thing is opensource which means anyone can add an ffmpeg-backend that could offer different compression options and write a video-file to disk continually...we do accept pullrequests..

1 minute action

Instead of starting/stopping a recording with the CTRL+4 shortcut you can also trigger a recording using the nodes Record input. If you want to create perfectly looping gifs simply set the Frames To Capture input to the number of frames you want to record. Now a single bang (or press of CTRL+4) starts the recording and the Progress output has a value going from 0..1 which you can make your loop to depend on..

Sharing your recordings

Unfortunately, due to the size of recordings, we cannot offer an automatic upload to vvvv.org for sharing your animations. What's new though is that you can now embed animated gifs in blogs, wiki-pages and the forum.

Also it seems to me thathttp://giphy.com is a nice service to manage your (now quickly growing) library of gifs. Best feature: they allow anonymous uploads! One problem I found is that even if you tag an upload with 'vvvv' it won't show up in the respective search. When asked about the reason for this giphy answered thats for some privacy reason but they want to change that in the future. So still don't forget to tag your uploads already!

And then share your account in the comments (for now). I found at least one celebrity user already:

 https://giphy.com/channel/evvvvil 

and mine are here:

 https://giphy.com/channel/joreg 

Looking forward to your creations (and animated bug-reports..)!

joreg, Tuesday, Jul 19th 2016 Digg | Tweet | Delicious 16 comments  

This is to announce proper Spout support for vvvv (finally).

What the Spout?

Spout is a realtime video sharing framework for windows. Basically what Syphon is for OSX. It allows different applications that handle video (or textures) to share them. That includes TouchDesigner, Resolume, AfterEffects,... to name only a few. For a full list see the Spout website.

How to Spout?

While you've already been able to use Spout so far, it was a bit of a hassle to set it up. Now vvvv ships with two simple nodes which should be all you ever need:

  • Spout (EX9.Texture Sender)
  • Spout (EX9.Texture Receiver)

Both modules are also available as DX11 versions.

Internally the sender module uses the new SpoutSender (System) node to register a sender name with Spout. If you're interested in a list of all available senders on your system, use SpoutSenderNames (System).

Can I has Network?

Indeed! Check the brilliant TCPSpout and share your textures via network and even to applications on OSX by using TCPSyphon on the other end. Watch this video to see TCPSpout/Syphon in action:

Available in latest alphas now. Many thanks to the creators of Spout and TCPSpout! Please test and report your findings.

joreg, Friday, May 20th 2016 Digg | Tweet | Delicious 20 comments  

Good news for those of you who often work with nodes in the RAW category. The general performance overhead has been reduced by quite a bit in the latest alpha version of vvvv. The respective commit can be found here.

This was achieved by an internal change to work with the IStream interface directly, instead of wrapping it in adapter classes, exposing it either as System.IO.Stream to .NET or TStream to Delphi. So a downstream plugin node will now have direct access to the upstream stream output, instead of going through an internal adapter class.

In case you write your own plugins and you want to keep the overhead as small as possible create your own custom Stream class, which implements the before mentioned IStream interface - for example have a look at the ComStream.*.cs files here and nodes making use of it here.

Thanks to woei and jens.a.e for reporting the performance issues and keeping on nagging me about it ;)

Elias, Tuesday, May 10th 2016 Digg | Tweet | Delicious 9 comments  

The Workshop

We had a 3 day VL workshop at resonate (belgrade) and this was just plain fun! In fact when thinking about that event some weeks ago i was still quite frightened by the idea of talking VL for 3 days straight. VL is still in an alpha phase and therefore sometimes harder to explain than you would want to. Of course it's less didactic if you need to also teach to work around glitches...

But then, just in time before the workshop, we remembered what learning a new system is about. It is about understanding how to apply it for "real world problems", so we made up a "problem" which we worked on as a team.

Our problem we named VLOsmos, after the game that we wanted to clone: Osmos.
http://www.osmos-game.com/
The goal of the game is to get to be the biggest bubble. You get bigger by eating smaller bubbles. But beware of getting eaten by a bigger one. To prevent this you sometimes need to flee, by accelerating into a direction. But alas by accelerating you loose mass, very much the same way a rocket does. You emit small bubbles... So you get smaller by changing direction, but you have the initiative which helps you get bigger earlier than others...

VLorkshop

So our idea was that we actually want to work, and not do frontal teaching so much of the time. So we split up into three teams.
Every team had a helping hand (there were Elias, Dominik and me) and each team got one VL document to work on. We split up the work like this:

  • Controller
  • Game Logic
  • Display
Controller

The controller team was responsible to hand over controller data to the game logic team. They also got the world state of the last frame from the game logic department. Here is what they did: They allowed to slip into the next free bubble and control it via mouse. I also saw this working with two mice (or track pad and mouse). But they also allowed to create several A.I. instances that slip into one of the next free bubbles and controlled them based upon the bubble world around the respective controlled bubble: try to accelerate into the direction of smaller bubbles (if those are not too small) and also run away from bigger ones...

Game Logic

The game logic team did the core logic of the game:

  • Emit new small bubbles, loose weight and in turn accelerate (all based upon control data for the respective bubbles, therefore independent of who is generating this control data)
  • Eat, grow, shrink in a fair manner
  • Update the world in a frame based manner that also is fps aware. Output a description of the world for display and controller team.
Display

The display team was there to make it look nice. They got a description of the world with all bubbles and all currently happening collisions. For each collision a new collision effect got created, to have a bit of VL typical lifetime management in there. But in the end the display team also had to get the data back into vvvv to do the rendering here. Luckily this was obvious from the beginning and we found a way so that everybody got her/his amount of VL treatment.

All in all

We did not only work on a real project, but also had a try on how to synchronize the work of typically ten people, all working on the programming department of that project.
So we solved that by separating the job into those 3 main blocks and designed the interfaces between them = the types of data that flows between. In VL terms we created the data types "World" and "ControlData", which we put into a core VL document that every other VL document could reference.
After sketching the rough game structure and the interfaces in between each team had its own VL and vvvv document. We synchronized via a public git repository: https://github.com/gregsn/ResonateVLWorkshop

All in all we basically had a proof of concept regarding lifetime management and object oriented dataflow programming with VL embedded in a vvvv project.

The lecture

was about visual programming, its roots, sister projects, push and pull based dataflow, synchrnonous and asynchronous dataflow, object orientation, control flow via regions within a strict language and the playful culture and work environment where vvvv got created.
We also had a look onto the game that we created. The presentation was patched in vvvv for easily embedding video playback and game.

https://www.youtube.com/watch?v=NLyIYmPfCps
http://meso.net/download/filename/49/ok_spektral_meso_email.pdf

gregsn, Saturday, Apr 23rd 2016 Digg | Tweet | Delicious 1 comments  

previously on VL: VL Autumn Update


WHY DOES THAT TAKE SO LONG? Glad you're still with us to ask that question. Well, good things take a while... not good enough? naa, i know you deserve better. so please read on below after the "what the vl" blurb to learn more.

What the VL?

VL is a general purpose visual programming language that combines dataflow with features known from object-oriented programming. It comes with a compiler that builds to the .net intermediate language and as such produces executables and libraries compatible to .net/mono.

Language features include but are not limited to:

  • datatypes and operations
  • loops
  • delegates
  • generics
  • observables
  • interfaces

As a proof of concept VL is now embedded into vvvv before it will later be available in a standalone development environment. Also we're planning for VL to be embeddable in other software products allowing it to become a dynamic plugin provider for various applications. More on that later..

Where its at

Here is how we like to think about VLs current state: a few month after our initial public release at node15 we found that there are a few things that we can radically improve. Mostly under the hood. And we decided to give it a go now rather than running into problems later. So at the moment we're finishing a branch that has all those changes in it with the goal that when merging it back to our main branch we're at a stage where we've been around 5 month ago and what will look quite similar to what is available with the vvvv-alpha download at the moment. Not too uplifting, eh? Well, there will also be a few notable changes:

No more Utility patches

The biggest change comes in the fact that VL now no longer distinguishes between datatype and utility patches. Utility operations can now simply be patched anywhere, inside or outside a datatype-patch. And they can now call operations that are defined on the same canvas. You're therefore no longer forced to split up utilities into "MyUtils2, MyUtils3..." to only call one operation from the other.

Document Canvas

This one is quite something though it is in a very simple state only at the moment. As you already know, a .vl document can hold any number of patches. Only so far you didn't get a good overview of all those. The document canvas now provides such an overview in that it shows you a (freely arrangable) listing of all patches in a document. Later this canvas may be used to visualize dependencies between types or references to interfaces or documents. Nothing promised, but just to give you an idea that with the document canvas we're establishing a new view that will help you organize your projects.

Excerpt of the VL.CoreLib.vl document canvas

New file format

The .vl fileformat has changed. Still .xml only with a different layout. Nothing to worry for you though since we have a converter in place that loads old .vl files and saves them in the new format.

Library

The good news: our work on the VL library continues steadily and is not set back by the mentioned restructuring of the core. work is going on in parallel here.
The bad news: none

Our work on all things library is going on on two front lines:

  1. building the VL.CoreLib
  2. learning about importing miscellaneous .net libraries

ad 1)
here our latest work was regarding integer-and-primitive-types-in-vl

ad 2)
we're now in the process of preparing a chapter for The Gray Book where we're trying to answer all your questions before you can even ask them.

Basically our idea is that as soon as the chapter is finished (which may still take a while) we'll release it to you. Independent of the rest of the state of VL as we're starting to get confident enough with the language that we believe there should not be any hard breaking changes coming up anymore (for a while at least).

In practice we've had a go at importing SkiaSharp, the blazingly fast 2d drawing library (that powers chrome and firefox) then SharpFont which is a wrapper around freetype and gives us access to any type of fonts curves and VerbalExpressions which is a convenient alternative to ordinary regular expressions.

All three libraries imported nicely and had their own quirks which we documented. We can now also say that almost all libraries will need some kind of a wrapper (patched in VL and/or written in C#) to be conveniently usable in visualprogramming because after all they were not made for that. Still those wrappers are easy to realize and most of the work goes into wrapper-design, which is actually all the fun.

Just recently we announced the editing framework and also in the works and the next to land in the public alpha builds is a complete implementation of the arduino/firmata protocoll in VL. Because we can!

Next Steps

On our road to beta35 which will be the first vvvversion that includes VL as a first-class patching language we'll first release a new series of alpha-versions including our new work described above and probably some of the libraries mentioned. Then beta35, then the world. So you may want to get started now. If you don't have time to come to the 3 days introduction workshop on VL in april, here is how you can help yourself:

Diving into VL

joreg, Tuesday, Mar 29th 2016 Digg | Tweet | Delicious 7 comments  

Introduction

The latest VL comes with a revised 'Primitive' category in the nodebrowser. This category holds the most basic data types which the system has build in. As amazing as it sounds all other types are made out of them.

There are:

  • Integer and floating point numeric types for calculations
  • Boolean for logic
  • Char and String for text
  • A few system types like Exception and Object

In this article we will focus on the numeric types and which operations VL ships for them.

Overview

Primitive numeric types come in two flavors: integer and floating point. The number after the type name is the size of the type in bits. The number of bits also defines the value range that the type can hold.

The VL default types are Integer32 and Float32.

Operators and Types

Numeric Unary Numeric Binary Bit Unary Bit Binary Bit Shift Bool Unary Bool Binary
+
-
+
-
*
/
%
<
>
<=
>=
==
!=
~ &
^
|
<<
>>
! ==
!=
&&
||
&
|
^

You should know most of them from math class but there are a few computer specific ones:

Division for integers is called DIV and it outputs an integer again. The "/" operator on integer types returns a floating point number.

The "%" operator is called MOD in VL and returns the remainder of a division.

For integers there is a combination of DIV and MOD called DIVMOD which outputs both the result of the division and the remainder. A practical usage is 2D column/row index calculation.

"~" is the ones complement, it inverts all bits of a value.

">>", "<<" are the bit shift operators, they move all bits of a type to the left or right. New bits are padded with zeroes.

The following table gives an overview of all types and their operators:

VL Name Bits Unary Binary C# Name
Integer8 8 num/bit num/bit/shift sbyte
Byte 8 num/bit num/bit/shift byte
Char 16 num/bit num/bit/shift char
Integer16 16 num/bit num/bit/shift short
Integer16 (Unsigned) 16 num/bit num/bit/shift ushort
Integer32 32 num/bit num/bit/shift int
Integer32 (Unsigned) 32 num/bit num/bit/shift uint
Integer64 64 num/bit num/bit/shift long
Integer64 (Unsigned) 64 +, ~ num/bit/shift ulong
Float32 32 num num float
Float64 64 num num double
Boolean 1 bool bool bool

Value Range

Integer types

Type Range Size
Integer8 -128 to 127 Signed 8-bit integer
Byte 0 to 255 Unsigned 8-bit integer
Char U+0000 to U+ffff Unicode 16-bit character
Integer16 -32,768 to 32,767 Signed 16-bit integer
Integer16 (Unsigned) 0 to 65,535 Unsigned 16-bit integer
Integer32 -2,147,483,648 to 2,147,483,647 Signed 32-bit integer
Integer32 (Unsigned) 0 to 4,294,967,295 Unsigned 32-bit integer
Integer64 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Signed 64-bit integer
Integer64 (Unsigned) 0 to 18,446,744,073,709,551,615 Unsigned 64-bit integer

Floating point types

Type Approximate range Precision Size
Float32 ±1.5 * E45 to ±3.4 * E38 7 digits 32-bit float
Float64 ±5.0 * E−324 to ±1.7 * E308 15-16 digits 64-bit float
Floating point numbers have an insane value range, but its important to understand that there is only a certain number of digits of precision.
This also means that the maximum consecutive integer that can be represented is 2^24 = 16,777,216 for Float32 and 2^54 = 9,007,199,254,740,992 for Float64, keep that in mind when connecting integers to float inputs.

Conversions

Between Numeric Types

Smaller integer types can directly be connected to bigger integer types that can hold the range of the smaller type and to floating point types.
For all other conversions a node is required since information might get lost.
However, sometimes you want to trick the VL type inference system or you explicitly want a specific type and therefore the complete list of conversion nodes are available.

Checked

Checked conversions throw an error if the value to convert exceeds the range of the target type. This can be helpful if you want to make sure to assign correct values to bytes.

The naming scheme of the nodes is ToTargetType and they are located in the category of the source type. For example a conversion from Integer32 to Byte is called ToByte (Integer32). Unsigned types are abbreviated with an 'U', so a conversion from Float32 to Integer32 (Unsigned) is called ToUInt32 (Float32).

Unchecked

Unchecked conversions do not throw errors and just copy appropriate bits from the source type to the target type. This results in value wrapping. For example converting an Integer32 with value 256 to a Byte will result in a value of 0, an integer with value 257 in a value of 1 and so on...

Because they directly copy the bits, the naming scheme of the nodes is BitsToTargetType in the category of the source type. For example a conversion from Integer32 to Integer64 (Unsigned) is called BitsToUint64 (Integer32) or a Byte to Char BitsToChar (Byte).

Type -> String

The conversion form machine representation to human readable string is of course essential for programming. There is a general node ToString (Object) which tries to convert everything plugged in to it to a string. This node works for all numeric types and Char because the system knows what to do.

However if you want your value in a specific string representation you have three more advanced nodes for all numeric types:

ToString (Format)

This is the most powerful node. It allows to input a format string which acts as template for the output string of the value. See these two documentation pages for the vast amount of possibilities (thanks microsoft!).
Standard Format Strings
Custom Format Strings

ToString (Binary)

Quite helpful when working with low level device protocols and other bitwise operations. Nerds ahoi!

ToString (Hex)

Hexadecimal is a compact representation of the bits where one digit can represent 16 values from '0' to 'F' which is 4 bits. You know this probably from html colors. Medium nerdy.

String -> Type

Parsing strings to a numeric type is also often required. When getting user input from or reading data from a text file for example. Since the parsing can go wrong quite easily the nodes are called TryParse and have a boolean output 'Success' which indicates whether the input string could be parsed into a numeric value that makes sense.

TryParse (Hex)

Version to parse hexadecimal strings into a numeric type.

TryParse (Binary)

My personal favorite, parsing binary strings. (Didn't you ever want to just type ones and zeroes into your computer?).

Conclusion

This might be some heavy detailed stuff for the average user, but it gives us a solid core library that is ready for all tasks and can solve even the problems on the lowest level.

And rest assured, most of the time you will just deal with the standard types Integer32 and Float32 and don't have to worry about the others. But in the 1% case when you need to shuffle the bits its all there for you.

yours,
devvvvs

tonfilm, Wednesday, Mar 23rd 2016 Digg | Tweet | Delicious 1 comments  

For years now vvvv is shipping with little helper modules like the AxisAndGrid (EX9), Camera (Transform Softimage), PointEditor (3D)... and some more that are hopefully saving you a lot of time while patching. In fact the Camera was the very first module i ever built when we introduced the concept of subpatches. It didn't work well, so gregsn took it over, fixed it and made it a Softimage one as this was the software he was used to at that time...

Anyway, we maintained those modules over time but kinda failed to review/consolidate them. Not least because they were always a bit tricky to handle. While they look quite simple from the outside they are rather complex internally. And as you may have noticed, at certain complexities vvvv patches become a bit tedious to maintain...

Entering VL. With VL we now allegedly have the right tool at hand to tackle such complexities. To put it to a test we thought it would be a good time to rework those Camera and Editor modules. So we went ahead keeping the following things in mind:

Design Goals

  • Modularity: a clear line between Model and View allows
    • easy reuse of individual parts in custom editors
    • a simple way to adapt the look of an editor by simply providing an alternative View node
    • to easily provide DX9 and DX11 versions of all editors
  • Persistence: editing state can be saved to and loaded from disk
  • Boygrouping: editors can be used in boygrouping scenarios by simply putting a halfboygrouped module (provided) between Editor and View
  • Undo/Redo: editing steps can be undone/redone

Performance

By building them with VL (which, remember, is a compiled language) we were hoping for improved performance because the existing modules were actually quite CPU hungry. And indeed we got better results immediately even though there's not been put too much effort in optimization on the VL side yet.

Drawbacks?

Of course! Mainly one though. A little one. More an annoyance. Not a big deal really. You may not even notice it..well..after a while.. in fact some people may even love it..niiiooaaa.. here is the thing: The first time you're using one of those new modules, VL is loaded, which takes a while. That really only happens once per session though, so lets for now pretend it is not that bad...

Here is what you get

  • PointEditor
  • BezierEditor
  • BezierPatchEditor (was: GridEditor)

Each of the above come in two flavors: 2D, 3D

Besides the above design-goals here is what changed with the modules for the user:

  • no more need to connect Mouse/Keyboard
  • no more need to tag points before moving them
  • no more need to press different mousebuttons for operating on different axis. interact with on-screen pivot element instead
  • better handling of point-dragging with extreme camera views
  • on-screen-display informing about the current transformation
  • MeshEditor (EX9) now also modifies normals
  • AxisAndGrid now has pins to show/hide axis and grid

Bonus:

Next Steps

The editors still need a bit of finetuning in terms of interaction and also their internal architecture is not yet exactly optimized for readability. Then the DX11 versions of the views need to be patched but that should be rather trivial since it is really only about drawing. So now you please give it a spin and feed back your findings before we're going into a second round..

Available now in latest alpha builds.

joreg, Tuesday, Feb 23rd 2016 Digg | Tweet | Delicious 6 comments  

previously on VL: VL Summer Update


It may seem a bit quiet around VL on your end but i can tell you our heads get deeper and deeper into what is going to be our next-generation visual programming offering. Before you get the latest infos please read the standard blurb. Too techy?

What the VL?

VL is a visual programming language combining dataflow and object oriented programming. It is compatible with the .net and mono frameworks in that it can consume .net/mono libraries directly and its compiler builds to the CIL.

Notable features include:

  • patch your own types, dynamically instantiate them and manage them in collections (Spread, Dictionary,..)
  • use Generics, LinQ, Delegates, Interfaces
  • asynchronously react to input using the Observer design pattern

VL is embedded into vvvv as a first class patching language and later will be released with its own standalone editor.

Hmmja..probably too techy still..

What happened recently

Library

First here is a little update on whats new in the library. dominikKoller implemented the following devices:

Note that the downloads in those threads are now obsolete since they are now included with alpha downloads.

Then we cleaned up the BezierSegment and BezierPatch stuff a bit that woei had started and moved it from girlpower to library. And we added some random stuff:

  • ArcLength
  • ADSR (time and framebased)
  • Limiter, Trigger, Metronome
  • ArtNet encoder and decoder
  • QRCode encoder
  • Mapping nodes

Of those we wrapped the following for your convenience into plugins for vvvv:

  • EyeTracker (Devices TheEyeTribe)
  • Leap (Devices) quite similar to the extensive leap-pack by microdee
  • ArcLength (2D/3D)
  • Artnet (Network Sender/Receiver) with spreadable subset and universe pins

Check their helppatches for details.

Also there are now FromRaw and ToRaw nodes in VL that allow you to communicate in raw(ie. bytes) between vvvv and VL. Quite some more stuff is in the works in VL that we'll also want to wrap back to vvvv..exciting times..

Nugets

All this preparation of the library took us way longer than expected because about halfway through we decided to give priority to a thing we had initially scheduled for later: VL now has a package management system. It was obvious that we need such a thing since the early days of vvvv but we always knew that it will be a hell lot of work to implement and maintain on our own (think: versioning, dependencies,...). Luckily finally some people came up with a thing called NuGet that Microsoft adopted as the official package managing system for .net. And hey, VL is built on .net...kombiniere..

So essentially now the whole VL library comes as a series of nugets. We have the VL.CoreLib nuget which brings you the most basic stuff and then a couple of nugets like VL.Devices.Leap, VL.Devices.Spacemouse,...you get the idea. In the future anyone contributing to the VL library can create and share nugets. They are versioned and can depend on other nugets and they can be referenced by individual .vl documents. Means: VL has no more monolithic addonpack and no more guessing as to which contributions are missing and where they need to be placed.

In the best future scenario you open a VL patch that has red nodes and VL will check to find the missing pieces (in the correct version) online and simply ask you to confirm to download them with one click. See, if we get this right it potentially solves a lot of problems you were used to in vvvv over the past years.

Can also have this in vvvv? So far we've laid the basis that potentially also vvvv can profit from but that still needs a bit of investigation, so nothing promised yet.

For now we've concentrated on VL and you can see the first results: we're shipping all our nugets with VL, so no dynamic download/update mechanism yet. But still you can already decide to reference individual nugets or not. Read on:

UI

The main navigation got a bit of an overhaul and is now more focusing on the active document. You can now more easily get an overview of all patches in the document and also have a new section to select which nugets you want your documents to reference via a single rightclick.

Please refer to the following two new sections in The Gray Book for details:

Next steps

To repeat our current plan: Get beta35 out at some point early™ next year which will include VL as a serious new language that you can use if you're stuck with vvvv but don't want to use c#. Easyasthat.

And of course at some point we'll let you know how you can build your own nugets. We're just not 100% sure about all the details yet, so please bare with us while we do some more testing on that..

Meanwhile please get yourself excited a bit more. I don't know how you do it normally but here is a few steps i can suggest:

Diving into VL

(Don't be alarmed by the fact that the alpha-downloads are huge at the moment. That'll be improved at some point..)

joreg, Friday, Dec 18th 2015 Digg | Tweet | Delicious 1 comments  

As a vvvv user you are most probably familiar with the node Map (Value). 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 Mapping 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) ).

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

Range

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

Map

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:

 UnitRange

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!

tonfilm, Friday, Dec 11th 2015 Digg | Tweet | Delicious 16 comments  

Introduction

While researching for the new VL math library the topic of polar, spherical and geographic coordinates came up. After reading several articles it was clear that there is a common confusion about the angle convention, orientation and naming.

This blog post starts from the official definition in math textbooks and derives the correct implementations in a left-handed coordinate system with y-axis up like the one in DirectX.

Polar and spherical coordinate systems do the same job as the good old cartesian coordinate system you always hated at school. It describes every point on a plane or in space in relation to an origin O by a vector. But instead of 3 perpendicular directions xyz it uses the distance from the origin and angles to identify a position.

Conventions

In the following descriptions the angle units are degree and the cartesian coordinate systems and drawings are the ones you would find in math textbooks.

2D

In 2d the definition is straightforward. A position is defined by the distance to the origin and one angle. We just need the:

  • origin O
  • a reference direction where the angle is 0

For practical reasons mathematicians place the origin at the same position as it is in the cartesian system and the reference direction is the positive x-axis:

Then the conversion from a cartesian vector (x, y) of a position P to polar coordinates (radius, angle) is:

radius = sqrt(x^2 + y^2)
angle = atan2(y, x)

and the way around:

x = radius * cos(angle)
y = radius * sin(angle)

Here a positive angular velocity moves the position counter-clockwise on a circle:

Note that many 2d computer graphics coordinate systems have the y-axis pointing downwards so that everything is flipped upside down. In that case, using the same calculations as above, a positive angular velocity moves the position clockwise.

To get the same behavior in a 2d cartesian system with y-axis down the calculations would be:

radius = sqrt(x^2 + y^2)
angle = atan2(-y, x)

and:

x = radius * cos(angle)
y = -radius * sin(angle)

3D

To define a point in space by spherical coordinates the distance to the origin O as well as two angles are required. The confusion starts here since many conventions for the notation and the order of the angles exist. This page lists most of them:http://mathworld.wolfram.com/SphericalCoordinates.html

But let's step back and have a look at what we need to define spherical coordinates. We will see that regardless of the notation the actual formula for the calculation is the same:

  • the origin O
  • for one angle we need a directed axis which defines the poles (like north and south pole of the earth), this angle is often called polar angle, zenith angle, colatitude, inclination or elevation
  • for the other angle we need a reference direction in the equatorial plane, this angle is called azimuthal angle

The origin is also the same as the one of the cartesian system. Traditionally mathematicians choose the z-axis as the polar axis and the xy-plane as the equatorial plane with reference direction as the positive x-axis:

The conversion formulas are then:

radius = sqrt(x^2 + y^2 + z^2)
polar = arccos(z/radius)
azimuthal = atan2(y, x)

and:

x = radius * sin(polar) * cos(azimuthal)
y = radius * sin(polar) * sin(azimuthal)
z = radius * cos(polar)

As you can see in the drawing, if polar angle is 0 the vector points toward the positive z-axis and the azimuthal angle has no effect because it only rolls the vector around the z-axis.

Positive polar velocity moves the point away from the pole at positive z towards positive x.
Positive azimuthal velocity moves the point from positive x towards positive y.

The drawing uses a right-handed system with z-axis up which is common in math textbooks. As in the 2d case it looks different depending on orientation of the xyz-axis of the cartesian coordinate system in which the position will be displayed.

Geographic Coordinates

The definition of the spherical coordinates has two drawbacks. First the polar angle has to have a value other than 0° (or 180°) to allow the azimuthal value to have an effect. Second the geographic system of latitude and longitude does not match with the two angles.

In order to match the spherical angles to latitude and longitude the polar angle needs to have a value of 90°. Then the position vector points towards the positive x-axis in the equatorial plane which matches a latitude of 0° and a longitude of 0°.

The angular directions of latitude and longitude are the same. So the conversion is quite simple:

latitude = polar - 90°
longitude = azimuthal

and:

polar = latitude + 90°
azimuthal = longitude

With trigonometric substitutions a direct conversion between geographic and cartesian coordinates can be derived:

radius = sqrt(x^2 + y^2 + z^2)
latitude = arcsin(z/radius)
longitude = atan2(y, x)

and:

x = radius * cos(latitude) * cos(longitude)
y = radius * cos(latitude) * sin(longitude)
z = radius * sin(latitude)

Implementation for VL

VL assumes that the user works in a left-handed cartesian coordinate system with the y-axis up which is commonly used with DirectX. This means that all the above images and directions would be somehow rotated and flipped when used in such a coordinate system. But that's of course not what we want. The north pole of a sphere should still be up and the angular directions of the angles should also be the same as above.

The conversion of a vector between the systems is not very complicated:

xR = -zL
yR = xL
zR = yL

and:

xL = yR
yL = zR
zL = -xR

The simplest solution would be to convert the vector before or after the calculation, but we can also apply the conversion to the formulas. Then we get for the spherical coordinates:

radius = sqrt(x^2 + y^2 + z^2)
polar = arccos(y/radius)
azimuthal = atan2(x, -z)

and:

x = radius * sin(polar) * sin(azimuthal)
y = radius * cos(polar)
z = -radius * sin(polar) * cos(azimuthal)

For geographic coordinates:

radius = sqrt(x^2 + y^2 + z^2)
latitude = arcsin(y/radius)
longitude = atan2(x, -z)

and:

x = radius * cos(latitude) * sin(longitude)
y = radius * sin(latitude)
z = -radius * cos(latitude) * cos(longitude)

Angle Units

Since we all love the convention of scaling value ranges to the interval 0-1, the VL nodes also use cycles as units as we are used to from vvvv.

Node Names

As we assume that the standard system you work in is cartesian we use the 'To' and 'From' prefix which we think is more clear than the vvvv names 'Polar' and 'Cartesian' we had before. So we now have:

ToPolar, FromPolar
ToSpherical, FromSpherical
ToGeographic, FromGeographic

Since the Angle (3D) node already calculates the spherical angles and the radius, the VL implementation for the spherical coordinates looks like this:

You can find it along with the other conversion nodes in Basics.vl in the patch Utils3D.

Relation to VVVV nodes

The old vvvv nodes Polar and Cartesian in 3d are similar to the geographic coordinates with the exception that the angular direction of the longitude is inverted.
The 2d nodes do match exactly.

Cylindrical Coordinates

A natural extension of the 2d polar coordinates are cylindrical coordinates, since they just add a height value out of the xy-plane. For completeness here they are:

The formula is exactly the same as 2d polar corrdinates with the extension of the height:

radius = sqrt(x^2 + y^2)
angle = atan2(y, x)
height = z

and the way around:

x = radius * cos(angle)
y = radius * sin(angle)
z = height

Converting that to left-handed system with y-axis up gives:

radius = sqrt(x^2 + z^2)
angle = atan2(x, -z)
height = y

and the way around:

x = radius * sin(angle)
y = height
z = -radius * cos(angle)

Node Names

As for the other conversion nodes we use:

ToCylindrical, FromCylindrical

Download

As usual in the alpha builds.

tonfilm, Tuesday, Oct 6th 2015 Digg | Tweet | Delicious 1 comments  

anonymous user login

Shoutbox

~6d ago

joreg: @beyon too bad. but from now on we have a fixed schedule: every 4th tuesday in the month! hope this helps to plan evvvveryones visits

~6d ago

beyon: joreg: ah, bad timing, I would be happy to attend but I doesn't look like it will work out

~7d ago

joreg: @beyon any chance you can add 2 days to stay? would be great to have you at the (not yet announced) #vvvv meetup on the 23rd!

~7d ago

~7d ago

beyon: I'll be in Berlin July 13-22 - anything interesting going on in that time frame?

~8d ago

~9d ago

joreg: moments later: admin fixed it. back to normal.

~9d ago

joreg: indeed. site broken. hope to get this sorted soon. sorry for the inconvenience.