C# code (console app, copy paste, add reference for System.Drawing)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
namespace Moire
{
class Program
{
static void Main(string[] args)
{
int width = 640;
int height = 480;
var scale = 50.0;
scale /= height; // adjust for resolution
var xh = width / 2;
var yh = height / 2;
var bitmap = new Bitmap(width, height);
for (int y = 0; y < height; y++)
{
var yy = (y - yh) * scale;
for (int x = 0; x < width; x++)
{
var xx = (x - xh) * scale;
var value = xx * xx + yy * yy; // f(x,y) = x^2 + y ^ 2
value = value % 1.0; // mod, though Hue should actually wrap anyway
var color = Hue((float)value);
bitmap.SetPixel(x, y, color);
}
}
bitmap.Save("image.png", ImageFormat.Png);
bitmap.Dispose();
}
#region Color functions
public static byte ToByte(float value)
{
return (byte)System.Math.Max(0, System.Math.Min(255, System.Math.Round(255f * value)));
}
public static Color FromFloat(float r, float g, float b)
{
return Color.FromArgb(ToByte(r), ToByte(g), ToByte(b));
}
public static Color Hue(float hue)
{
float oneSixth = 1f / 6f;
float h = hue - (int)hue;
int index = (int)(h / oneSixth);
h = (h / oneSixth) - index;
var q = 1f - h;
switch (index)
{
case 0: return FromFloat(1, h, 0);
case 1: return FromFloat(q, 1, 0);
case 2: return FromFloat(0, 1, h);
case 3: return FromFloat(0, q, 1);
case 4: return FromFloat(h, 0, 1);
default: return FromFloat(1, 0, q);
}
}
#endregion
}
}
Playing with the scale:scale = 10

scale = 20

scale = 50
