Function Repository Resource:

ColorWinding

Source Notebook

Find the number of times the domain coloring of a function wraps around the color wheel along a given curve

Contributed by: Garrett Dubofsky, Wolfram|Alpha Math Team

ResourceFunction["ColorWinding"][{f1,f2},{x,y},{p1,p2,}]

finds the winding number of the 2D transformation {f1,f2} with variables {x,y} along the path formed by linearly connecting the points pi.

ResourceFunction["ColorWinding"][{f1,f2},{x,y},{{p11,p12,},}]

finds the winding number over a collection of curves.

ResourceFunction["ColorWinding"][{f1,f2},{x,y},points, output]

specifies the output type using output.

ResourceFunction["ColorWinding"][{f1,f2},{x,y},"DomainColor"]

outputs the domain coloring of the transformation.

Details

A domain coloring pairs every transformed point’s angle around the origin to a specific hue. This is a method used to visualize 2D transformations. The red hue lies along the negative y-axis and the color wheel is oriented counterclockwise around the origin.
The winding number of a 2D function along a curve is the number of times the domain coloring of the function winds around the color wheel as the curve is transversed.
Wrapping in the order of red green blue represents a positive winding number, whereas blue green red is negative.
The winding number is an integer.
Both functions f1 and f2 should depend on the independent variables x and y and output a single numeric value.
The value of output can be a single item or a list containing any of "Number", "HuePlot", "PolygonPlot", "DomainColor", or All.
If output is set to All, the function returns an Association.
ResourceFunction["ColorWinding"] takes all the options for ParametricPlot with the following additions:
"ClosedCurve"Truewhether to connect the first and last points
"IterationLength"1/100how frequently the Hue value is sampled
"HueShift"0shift all colors around the Hue wheel

Examples

Basic Examples (5) 

After the identity mapping is applied, the domain coloring of the unit square centered at the origin winds around the color wheel once:

In[1]:=
ResourceFunction[
 "ColorWinding"][{x, y}, {x, y}, {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}]
Out[1]=

The domain coloring along this curve can be visualized:

In[2]:=
ResourceFunction[
 "ColorWinding"][{x, y}, {x, y}, {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}, "PolygonPlot"]
Out[2]=

The "HuePlot" output plots the domain coloring Hue value along the curve:

In[3]:=
ResourceFunction[
 "ColorWinding"][{x, y}, {x, y}, {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}, "HuePlot"]
Out[3]=

Over the entire plane, the domain coloring of the identity mapping preserves the color wheel centered at the origin:

In[4]:=
ResourceFunction["ColorWinding"][{x, y}, {x, y}, "DomainColor"]
Out[4]=

If the order of the points is reversed, the winding number is negated:

In[5]:=
ResourceFunction["ColorWinding"][{x, y}, {x, y}, Reverse[{{-1, -1}, {1, -1}, {1, 1}, {-1, 1}}]]
Out[5]=

Scope (4) 

Each 2D transformation produces its own domain coloring:

In[6]:=
ResourceFunction[
 "ColorWinding"][{Cos[4 x], Sin[4 (x + y)]}, {x, y}, "DomainColor"]
Out[6]=

Specify a collection of curves:

In[7]:=
ResourceFunction[
 "ColorWinding"][{x, y}, {x, y}, {{{0, -1}, {3, -1}, {-1, 3}}, {{-3, 1}, {1, -3}, {0, 1}}}, "PolygonPlot"]
Out[7]=

All forms of Rectangle are recognized as valid lists of points:

In[8]:=
ResourceFunction["ColorWinding"][{x, y}, {x, y}, #, "PolygonPlot"] & /@ {Rectangle[], Rectangle[{-1, -1}], Rectangle[{-1, -1}, {2, 3}]}
Out[8]=

All forms of Triangle are also supported:

In[9]:=
ResourceFunction["ColorWinding"][{x, y}, {x, y}, #, "PolygonPlot"] & /@ {Triangle[], Triangle[{{-2, 0}, {0, 1}, {1, -1}}], Triangle[{{{0, -1}, {3, -1}, {-1, 3}}, {{-3, 1}, {1, -3}, {0, 1}}}]}
Out[9]=

The heads Polygon and Line are supported:

In[10]:=
ResourceFunction["ColorWinding"][{x, y}, {x, y}, Polygon[{{0, 1}, {1, 1}, {-1, 2}, {0, 0}}], "PolygonPlot"]
Out[10]=
In[11]:=
ResourceFunction["ColorWinding"][{x, y}, {x, y}, Line[{{{-1, -1}, {1, 1}}, {{-1, 1}, {1, -1}}}], "PolygonPlot"]
Out[11]=

Multiple output types can be selected in a list and their input order is reflected in the output:

In[12]:=
ResourceFunction[
 "ColorWinding"][{Cos[y^3*x], y + x}, {x, y}, {{1, 1}, {2, 3}, {4, 1}}, {"HuePlot", "Number", "PolygonPlot"}]
Out[12]=

If All is used as the output type, the function returns an Association:

In[13]:=
ResourceFunction[
 "ColorWinding"][{Cos[y*x], y + x}, {x, y}, {{5, 5}, {1, 3}, {4, 1}}, All]
Out[13]=

Options (5) 

Determine if the list of points defines a closed curve:

In[14]:=
ResourceFunction[
 "ColorWinding"][{Sin[y], -x}, {x, y}, {{2, 0}, {1, 1}, {2, 1}}, "PolygonPlot", "ClosedCurve" -> False]
Out[14]=

The "IterationLength" option determines how frequently the Hue value is sampled along the curve, which produces more accurate results:

In[15]:=
Table[ResourceFunction[
  "ColorWinding"][{Sin[x*y], Sin[23/(1 + x)]}, {x, y}, Polygon[CirclePoints[3]], "IterationLength" -> 10^-k], {k, 0, 4}]
Out[15]=

The actual winding number is -1, as seen by inspecting the jumps in the below plot:

In[16]:=
ResourceFunction["ColorWinding"][{Sin[x*y], Sin[23/(1 + x)]}, {x, y}, CirclePoints[3], "HuePlot"]
Out[16]=

The color wheel can be shifted by a selected amount:

In[17]:=
Table[ResourceFunction["ColorWinding"][{Sin[1 - x*y], Cos[x]}, {x, y},
   "DomainColor", "HueShift" -> k], {k, 1/4, 1, 1/4}]
Out[17]=

Only the decimal value affects the hue shift:

In[18]:=
ResourceFunction["ColorWinding"][{-y*Sin[x], x*Cos[y*x]}, {x, y}, "DomainColor", "HueShift" -> #] & /@ {0.2, 1.2}
Out[18]=

The value of "IterationLength" determines how frequently the Hue value is sampled, as visualized below:

In[19]:=
Show[ResourceFunction[
  "ColorWinding"][{Cos[x + y]*x, 3 y - x^2}, {x, y}, CirclePoints[10],
   "HuePlot", "IterationLength" -> 1/10], Graphics[Table[Line[{{k, 0}, {k, 1}}], {k, 0, 1, 1/10}]]]
Out[19]=

The options for ParametricPlot are also supported:

In[20]:=
ResourceFunction[
 "ColorWinding"][{Sin[5 x - y^2], Sin[3 y - 2 x]}, {x, y}, "DomainColor", PlotRange -> 4, Frame -> False, PlotPoints -> 200]
Out[20]=

Applications (5) 

For continuous transformations, any closed curve with a nonzero winding number contains a zero of the transformation:

In[21]:=
ResourceFunction["ColorWinding"][{x^3 - Cos[y], Sin[y - x]}, {x, y}, Rectangle[{0, 0}, {1, 1}]]
Out[21]=

If a boundary with nonzero winding number is halved, one half must also have a nonzero winding number:

In[22]:=
ResourceFunction[
   "ColorWinding"][{x^3 - Cos[y], Sin[y - x]}, {x, y}, #] & /@ {Rectangle[{0, 0}, {1/2, 1}], Rectangle[{1/2, 0}, {1, 1}]}
Out[22]=

Locate the zero by repeatedly decreasing the boundary size, ignoring areas where the winding number is zero:

In[23]:=
ResourceFunction["ColorWinding"][{x^3 - Cos[y], Sin[y - x]}, {x, y}, Rectangle[{1/2, 1/2}, {1, 1}]]
Out[23]=
In[24]:=
ResourceFunction["ColorWinding"][{x^3 - Cos[y], Sin[y - x]}, {x, y}, Rectangle[{3/4, 3/4}, {1, 1}]]
Out[24]=
In[25]:=
ResourceFunction["ColorWinding"][{x^3 - Cos[y], Sin[y - x]}, {x, y}, Rectangle[{3/4, 3/4}, {7/8, 7/8}]]
Out[25]=

The resulting boundary after repeating for a total of 10 times:

In[26]:=
ResourceFunction["ColorWinding"][{x^3 - Cos[y], Sin[y - x]}, {x, y}, Rectangle[{443/512, 443/512}, {887/1024, 887/1024}], All]
Out[26]=

The midpoints of the boundaries approach a zero of the transformation:

In[27]:=
N[{x^3 - Cos[y], Sin[y - x]}] /. {x -> 1773/2048, y -> 1773/2048}
Out[27]=

Properties and Relations (2) 

Vector plots provide another visualization of 2D transformations:

In[28]:=
p1 = VectorPlot[{Sin[x^3] - 2 x^2 - 4 x*y, Cos[y^2] + y - 2 x}, {x, -2, 2}, {y, -2, 2}, ImageSize -> 250]
Out[28]=

Shown together, the similarities between vector plots and domain coloring become apparent:

In[29]:=
Show[ResourceFunction[
  "ColorWinding"][{Sin[x^3] - 2 x^2 - 4 x*y, Cos[y^2] + y - 2 x}, {x, y}, "DomainColor"], p1]
Out[29]=

Possible Issues (3) 

Discontinuities may occur in the color winding of a curve passing through a zero of the transformation:

In[30]:=
ResourceFunction["ColorWinding"][{x - 1, y - 1}, {x, y}, Rectangle[], {"PolygonPlot", "HuePlot"}]
Out[30]=

A similar effect occurs for a curve passing though any asymptotes of the transformation:

In[31]:=
ResourceFunction["ColorWinding"][{1/(x + y), 1/(x - y)}, {x, y}, Rectangle[{-2, -2}, {2, 2}], {"HuePlot", "DomainColor"}]
Out[31]=

Low values of the "IterationLength" option may produce inaccurate results:

In[32]:=
Table[ResourceFunction[
  "ColorWinding"][{Sin[5 x - y^2], Sin[3 y - 2 x]}, {x, y}, {{-2, -1}, {-2, -5}, {4, 2}}, "IterationLength" -> 10^(-k)], {k, 1, 4}]
Out[32]=

Increasing the value of PlotPoints improves the resolution of the domain coloring:

In[33]:=
ResourceFunction[
   "ColorWinding"][{Cos[x^3 - Cos[y]], Sin[y - x]}, {x, y}, "DomainColor", PlotPoints -> #] & /@ {50, 100, 200}
Out[33]=

Neat Examples (4) 

Create neat shapes by overlapping several domain coloring curves:

In[34]:=
Show[Table[
  ResourceFunction["ColorWinding"][{x, y}, {x, y}, CirclePoints[{k, k*\[Pi]/4}, 6], "PolygonPlot", "HueShift" -> k/5, Axes -> False], {k, 5, 0, -1/10}]]
Out[34]=

Visualize how changing the transformation alters the domain coloring:

In[35]:=
TableForm[
 Array[ResourceFunction[
    "ColorWinding"][{Cos[#1 x], Sin[#2 y]}, {x, y}, "DomainColor", ImageSize -> 55, Frame -> False, PlotPoints -> 40] &, {5, 5}, {1, 1}], TableSpacing -> {0, 0}]
Out[35]=

Draw the domain coloring using a collection of triangular boundaries:

In[36]:=
Show[Table[
  ResourceFunction[
   "ColorWinding"][{Cos[x + Sin[x*y]], Sin[y + Cos[x^2]]}, {x, y}, CirclePoints[k, 3], "PolygonPlot", PlotRange -> 3, Axes -> False, Background -> Black], {k, 0.2, 8, 0.2}]]
Out[36]=

Find the winding number along famous curves:

In[37]:=
ResourceFunction["ColorWinding"][{x - 450, y + 500}, {x, y}, SierpinskiCurve[3], {"PolygonPlot", "HuePlot"}]
Out[37]=
In[38]:=
ResourceFunction["ColorWinding"][{2 Sin[x - 3.5], Cos[y - 4]}, {x, y},
  HilbertCurve[3], "PolygonPlot", "ClosedCurve" -> False]
Out[38]=

Publisher

Wolfram|Alpha Math Team

Version History

  • 2.0.0 – 23 March 2023
  • 1.0.0 – 29 August 2022

Related Resources

Author Notes

To view the full source code for ColorWinding, evaluate the following:

License Information