Links

Categories

Tags


« | Main | »

Supershapes Effect

By Jewe | May 19, 2014

Draws a shape based upon equations by Johan Gielis. Code by Paul Bourke. (IrfanView Filter Sandbox 1.0)

Download this script

import Math;
import RasterizerSSE;

using Math;

class PointF
{
    float x;
    float y;
    method PointF()
    {
        x = 0;
        y = 0;
    }
}

/*
 * Supershapes
 *
 * written by Paul Bourke
 * http://paulbourke.net/geometry/supershape/
 *
 * Based upon equations by Johan Gielis
 */

function Eval(float m, float n1, float n2, float n3, float phi, PointF result)
{
   float mp = m * phi / 4.0;
   float t1 = Pow(Abs(Cos(mp)), n2);
   float t2 = Pow(Abs(Sin(mp)), n3);
   float r = Pow(t1 + t2, 1.0 / n1);
   if (Abs(r) == 0)
   {
      result.x = 0;
      result.y = 0;
   }
   else
   {
      r = 1.0 / r;
      result.x = r * Cos(phi);
      result.y = r * Sin(phi);
   }
}

//------------------------------------------------------------------------------
class Supershape : Effect
{
    Slider M, N1, N2, N3, Scale, Prec;
    Slider Hue1, Sat1, Lum1;
    Slider Hue2, Sat2, Lum2;
    Slider BSize, BSoft;
    Label Shape, Brush, Color1, Color2;

    method Supershape()
    {
        Shape = new Label("Shape");
        M = new Slider("M", "", 2, 0, 27.4, 6);
        N1 = new Slider("N1", "", 2, 0.1, 27.5, 1);
        N2 = new Slider("N2", "", 2, 0, 27.4, 1);
        N3 = new Slider("N3", "", 2, 0, 27.4, 6);
        Scale = new Slider("Scale", "", 2, 0, 2, 0.8);
        Prec = new Slider("Precision", "", 0, 100, 100000, 10000);
        Brush = new Label("Brush");
        BSize = new Slider("Size", "", 0, 1, 20, 5);
        BSoft = new Slider("Softness", "", 0, 1, 10, 5);
        Color1 = new Label("Shape Color");
        Hue1 = new Slider("Hue", "", 0, 0, 359, 240);
        Sat1 = new Slider("Saturation", "", 0, 0, 255, 127);
        Lum1 = new Slider("Luminance", "", 0, 0, 255, 127);
        Color2 = new Label("Background Color");
        Hue2 = new Slider("Hue", "", 0, 0, 359, 0);
        Sat2 = new Slider("Saturation", "", 0, 0, 255, 0);
        Lum2 = new Slider("Luminance", "", 0, 0, 255, 255);
    }

    method EffectInfo GetEffectInfo()
    {
        return new EffectInfo(
            "Supershape",
            "by Jewe",
            "Draws a shape based upon equations by Johan Gielis. "
            "Code by Paul Bourke - www.paulbourke.net"
        );
    }

    method Parameter[] GetParameters()
    {
        return {
            Shape, M, N1, N2, N3, Scale, Prec,
            Brush, BSize, BSoft,
            Color1, Hue1, Sat1, Lum1,
            Color2, Hue2, Sat2, Lum2
        };
    }

    method DoEffect(Image img)
    {
        Color b = Color::FromHSL(Hue2.Value, Sat2.Value / 255.0, Lum2.Value / 255.0);
        Color c = Color::FromHSL(Hue1.Value, Sat1.Value / 255.0, Lum1.Value / 255.0);
        int brushSize = BSize.Value + 1;

        RasterizerSSE ras = new RasterizerSSE(img, img.Selection);
        ras.Fill(b);

        RasterizerSSE bru = new RasterizerSSE(brushSize, brushSize);
        bru.CreateRadialBrush(BSoft.Value / 2.0);
        bru.PixelsToAlpha(bru);
        bru.Fill(c);

        int Res = Prec.Value;
        float m = M.Value;
        float n1 = N1.Value;
        float n2 = N2.Value;
        float n3 = N3.Value;
        float pi2 = 2 * Math::PI;
        float w = (img.Selection.Width - brushSize) / 2.0;
        float h = (img.Selection.Height - brushSize) / 2.0;
        float z = Min(w, h) * Scale.Value;
        PointF pt;
        Rect dst = Rect::FromSize(brushSize, brushSize);
        for (int res = 0; res < Res; res++)
        {
            float phi = res * pi2 / Res;
            Eval(m, n1, n2, n3, phi, pt);
            dst.MoveTo(new Point(pt.x * z + w, pt.y * z + h));
            ras.DrawAlpha(bru, dst, new Point());
        }
        ras.Finalize();
    }
}

Topics: code examples, filter sandbox | Comments Off on Supershapes Effect

Comments are closed.