public SpotFunctionPanel() : base(4, 2, false) { // TODO: use degrees instead of radians angleHScale = new HScale(0, 2, 0.01); distanceSpinButton = new SpinButton(1, 1000, 1); presets = new List<SpotFunction>(SpotFunction.Samples.list()); presetsNames = (from preset in presets select preset.Name).ToList(); presetComboBox = new ComboBox(presetsNames.ToArray()); presetComboBox.Changed += delegate { int active = presetComboBox.Active; if (active >= 0) { module = (SpotFunction)presets[active].deepCopy(); } }; ColumnSpacing = RowSpacing = BorderWidth = 5; Attach(new Label("Preset:") { Xalign = 0.0f }, 0, 1, 0, 1, AttachOptions.Fill, AttachOptions.Shrink, 0, 0); Attach(presetComboBox, 1, 2, 0, 1, AttachOptions.Fill | AttachOptions.Expand, AttachOptions.Shrink, 0, 0); Attach(new Label("Screen angle (rad):") { Xalign = 0.0f }, 0, 1, 1, 2, AttachOptions.Fill, AttachOptions.Shrink, 0, 0); Attach(angleHScale, 1, 2, 1, 2, AttachOptions.Fill | AttachOptions.Expand, AttachOptions.Shrink, 0, 0); Attach(new Label("Screen line distance (px):") { Xalign = 0.0f }, 0, 1, 2, 3, AttachOptions.Fill, AttachOptions.Shrink, 0, 0); Attach(distanceSpinButton, 1, 2, 2, 3, AttachOptions.Fill | AttachOptions.Expand, AttachOptions.Shrink, 0, 0); ShowAll(); }
static Samples() { _list = new List<SpotFunction>(); nullSpot = new SpotFunction((double angle, double distance) => { return (int x, int y) => 128; }) { Name = "Null spot function" } ; euclidDot = new SpotFunction((double angle, double distance) => { double pixelDivisor = 2.0 / distance; return (int x, int y) => { double rotatedX, rotatedY; Util.rotate( x * pixelDivisor, y * pixelDivisor, angle, out rotatedX, out rotatedY); return (int)( 255 * (0.5 - (0.25 * ( // to make an elipse multiply sin/cos // arguments with different multipliers Math.Sin(Math.PI * (rotatedX + 0.5)) + Math.Cos(Math.PI * rotatedY))))); }; }) { Name = "Euclid dot", Description = "circular dot changing to square at 50% grey" }; _list.Add(euclidDot); perturbedEuclidDot = new SpotFunction( (double angle, double distance) => { Random random = new Random(); double noiseAmplitude = 0.01; double pixelDivisor = 2.0 / distance; return (int x, int y) => { double rotatedX, rotatedY; SpotFunction.Util.rotate( x * pixelDivisor, y * pixelDivisor, angle, out rotatedX, out rotatedY); return (int)( 255 * ( ((random.NextDouble() - 0.5) * 2 * noiseAmplitude) + (0.5 - (0.25 * ( // to make an elipse multiply sin/cos // arguments with different multipliers Math.Sin(Math.PI * (rotatedX + 0.5)) + Math.Cos(Math.PI * rotatedY)))))); }; }) { Name = "Euclid dot, perturbed", Description = "Euclid dot with some noise" }; _list.Add(perturbedEuclidDot); squareDot = new SpotFunction((double angle, double distance) => { return (int x, int y) => { double rotatedX, rotatedY; SpotFunction.Util.rotate(x, y, angle, out rotatedX, out rotatedY); return (int)(255 * (1 - (0.5 * ( Math.Abs(((Math.Abs(rotatedX) / (distance * 0.5)) % 2) - 1) + Math.Abs(((Math.Abs(rotatedY) / (distance * 0.5)) % 2) - 1) )))); }; }) { Name = "Square dot" }; _list.Add(squareDot); line = new SpotFunction((double angle, double distance) => { angle %= Math.PI * 0.5; double invDistance = 1 / distance; double sinInvDistance = Math.Sin(angle) * invDistance; double cosInvDistance = Math.Cos(angle) * invDistance; return (int x, int y) => { double value = (sinInvDistance * x) + (cosInvDistance * y); return (int)(255 * (Math.Abs( Math.Sign(value) * value % Math.Sign(value)))); }; }) { Name = "Line" }; _list.Add(line); triangle = new SpotFunction((double angle, double distance) => { double invDistance = 1 / distance; return (int x, int y) => { // TODO: it does not rotate return (int)(255 * 0.5 * ( ((invDistance * x) % 1) + ((invDistance * y) % 1) )); }; }) { Name = "Triangle" }; _list.Add(triangle); circleDot = new SpotFunction((double angle, double distance) => { double invDistance = 1 / distance; return (int x, int y) => { // TODO: fix this double xSq = x - distance * 0.5; xSq = (xSq * xSq) % distance; double ySq = y - distance * 0.5; ySq = (ySq * ySq) % distance; return (int)(255 * //((1 - Math.Sqrt( //(invDistance * (x*x) % 1) + //(invDistance * (y*y) % 1) //) * 0.5))); ((1 - invDistance * Math.Sqrt(2*(xSq + ySq))))); }; }) { Name = "Circle dot" }; // TODO: uncomment this when circle dot will work //_list.Add(circleDot); }
/// <summary> /// Create a new spot function threshold filter with given spot /// function. /// </summary> /// <param name="spotFunc"></param> public SpotFunctionThresholdFilter(SpotFunction spotFunc) { SpotFunc = spotFunc; }
/// <summary> /// Create a new image generator with a default spot functions /// and no effects. /// </summary> public ImageGenerator() { SpotFunction = new SpotFunction(); Effects = new List<IImageFilter>(); }
/// <summary> /// Create a new spot function threshold filter with a default /// spot function. /// </summary> public SpotFunctionThresholdFilter() { SpotFunc = new SpotFunction(); }