Jump to content

Reptillian

Members
  • Posts

    1,238
  • Joined

  • Last visited

  • Days Won

    18

Posts posted by Reptillian

  1. Translation of OP:

     

    Paint.NET closes as soon as it open.

    ----

    Uno, aqui escribe en ingles, no en español. Y dos, ese es un problema con la programa. Probablemente algo que se puede areglar. ¿Puede tu mandar un reporte?

     

    Translation:

     

    One, here we write in english, not in spanish. Two, that is a problem with the program. Likely, it can be fixed. Send your report.

  2. This is essentially a upgraded version of the existing Paint.NET Emboss/Relief.  Emboss/Relief+ has options such as changing radius, changing internal convolution kernel, and finally, having the option for each channel has their own convolution result rather than utilizing the average of convolution.

     

    The original code was based on this  - https://www.mathworks.com/matlabcentral/fileexchange/9645-steerable-gaussian-filters

     

    Download Plugin -> EmbossReliefPlus.zip

     

    Output of Result:

     

    unknown.png

     

    Source code

     

    CodeLab:

    Spoiler
    // Name: Emboss/Relief+
    // Submenu: Stylize
    // Author: Reptillian
    // Title: Emboss/Relief+
    // Version: 1
    // Desc: Extended version of Emboss/Relief
    // Keywords: Emboss, Relief
    // URL: https://forums.getpaint.net/profile/85868-reptillian/
    // Help:
    
    #region UICode
    IntSliderControl radius = 5; // [5,25] Radius (px)
    AngleControl var_angle = 90; // [-180,180] Angle
    DoubleSliderControl sigma = 0.5; // [0.25,4] Sigma
    DoubleSliderControl scale_value = 2; // [0.5,10] Value Scale
    ListBoxControl output = 0; // Output|Relief|Emboss
    CheckboxControl rgb_mode = true; // RGB Mode
    #endregion
    
    double[] convolve_a;
    double[] convolve_b;
    
    int cut(int v,int image_max_index){
        return Math.Max(0,Math.Min(v,image_max_index));
    }
    
    int d2i(double v){
        return (int)(Math.Round(v));
    }
    
    int average(int r, int g, int b){
        return (r+g+b)/3;
    }
    
    double tau_sqrt = Math.Sqrt ( 2 * Math.PI);
    
    // This single-threaded function is called after the UI changes and before the Render function is called
    // The purpose is to prepare anything you'll need in the Render function
    void PreRender(Surface dst, Surface src)
    {
        convolve_a = new double[radius];
        convolve_b = new double[radius];
    
        double center_index=((double)(radius) - 1 )/2;
        double sigma_exp = 2 * sigma * sigma;
        double sqrsig = sigma * tau_sqrt;
        double M = 3 * sigma;
        double ni,rescale_factor;
    
        rescale_factor = 0;
    
        for (int p = 0 ; p < radius ; p++){
            ni = ((double)(p)-center_index)/center_index*M;
            convolve_a[p] = Math.Exp(-(ni * ni)/sigma_exp)/sqrsig;
            convolve_b[p] = (ni / (sigma * sigma)) * convolve_a[p];
            rescale_factor +=convolve_a[p];
        }
    
        rescale_factor /= scale_value ;
    
        for (int p = 0 ; p < radius ; p++){
            convolve_a[p]/=rescale_factor;
            convolve_b[p]/=rescale_factor;
        }
    }
    
    // Here is the main multi-threaded render function
    // The dst canvas is broken up into rectangles and
    // your job is to write to each pixel of that rectangle
    void Render(Surface dst, Surface src, Rectangle rect)
    {
        double theta = var_angle / 180 * Math.PI;
        double cos_theta = Math.Cos(theta);
        double sin_theta = Math.Sin(theta);
        int max_x = src.Width - 1;
        int max_y = src.Height - 1;
        int center = (int)(Math.Ceiling((double)(radius)/2));
        double inner_convolve_a_r,inner_convolve_a_g,inner_convolve_a_b,inner_convolve_b_r,inner_convolve_b_g,inner_convolve_b_b;
        double outer_convolve_a_r,outer_convolve_a_g,outer_convolve_a_b,outer_convolve_b_r,outer_convolve_b_g,outer_convolve_b_b;
        double result_r,result_g,result_b;
        int new_r,new_g,new_b,avg;
    
        int start_x,start_y;
    
        ColorBgra Reference_Color_A,Reference_Color_B;
    
        // Step through each row of the current rectangle
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;
            // Step through each pixel on the current row of the rectangle
            for (int x = rect.Left; x < rect.Right; x++)
            {
                start_x=x-center;
                start_y=y-center;
    
                inner_convolve_a_r = inner_convolve_a_g = inner_convolve_a_b = inner_convolve_b_r = inner_convolve_b_g = inner_convolve_b_b = 0;
               
                outer_convolve_a_r = outer_convolve_a_g = outer_convolve_a_b = outer_convolve_b_r = outer_convolve_b_g = outer_convolve_b_b = 0;
    
                for (int p = 0 ; p < radius ; p++)
                {
                    for (int q = 0 ; q < radius ; q++)
                    {
                        Reference_Color_A = src[cut(start_x+p,max_x),cut(start_y+q,max_y)];
                        inner_convolve_a_r += (double)(Reference_Color_A.R) * convolve_a[q];
                        inner_convolve_a_g += (double)(Reference_Color_A.G) * convolve_a[q];
                        inner_convolve_a_b += (double)(Reference_Color_A.B) * convolve_a[q];
                        Reference_Color_B = src[cut(start_x+q,max_x),cut(start_y+p,max_y)];
                        inner_convolve_b_r += (double)(Reference_Color_B.R) * convolve_a[q];
                        inner_convolve_b_g += (double)(Reference_Color_B.G) * convolve_a[q];
                        inner_convolve_b_b += (double)(Reference_Color_B.B) * convolve_a[q];
    
                    }
    
                    outer_convolve_a_r += inner_convolve_a_r * convolve_b[p];
                    outer_convolve_a_g += inner_convolve_a_g * convolve_b[p];
                    outer_convolve_a_b += inner_convolve_a_b * convolve_b[p];
                    outer_convolve_b_r += inner_convolve_b_r * convolve_b[p];
                    outer_convolve_b_g += inner_convolve_b_g * convolve_b[p];
                    outer_convolve_b_b += inner_convolve_b_b * convolve_b[p];
    
                    inner_convolve_a_r = inner_convolve_a_g = inner_convolve_a_b = inner_convolve_b_r = inner_convolve_b_g = inner_convolve_b_b = 0;
                }
    
                result_r = outer_convolve_b_r * cos_theta + outer_convolve_a_r * sin_theta ;
                result_g = outer_convolve_b_g * cos_theta + outer_convolve_a_g * sin_theta ;
                result_b = outer_convolve_b_b * cos_theta + outer_convolve_a_b * sin_theta ;
                new_r = d2i(result_r);
                new_g = d2i(result_g);
                new_b = d2i(result_b);
                if (rgb_mode)
                {
                    if (output == 0)
                    {
                        dst[x,y] = ColorBgra.FromBgraClamped(src[x,y].B+new_b,src[x,y].G+new_g,src[x,y].R+new_r,src[x,y].A);
                    }
                    else
                    {
                        dst[x,y] = ColorBgra.FromBgraClamped(new_b+127,new_g+127,new_r+127,src[x,y].A);
                    }
                }
                else
                {
                    avg = average(new_r,new_g,new_b);
    
                    if (output == 0)
                    {
                        dst[x,y] = ColorBgra.FromBgraClamped(src[x,y].B+avg,src[x,y].G+avg,src[x,y].R+avg,src[x,y].A);
                    }
                    else
                    {
                        dst[x,y] = ColorBgra.FromBgraClamped(avg+127,avg+127,avg+127,src[x,y].A);
                    }
                }
            }
        }
    }
    

     

     

    G'MIC:

    Spoiler
    +_rep_steerable_gaussian_convolve:
    
    sg,theta,sigma,M={max(5,int(abs($1)))},{deg2rad($2)},$3,{3*$3}
    
    $sg,1,1,2,"begin(
      const center_index=(w-1)/2;
      const sigma_exp=2*$sigma^2;
      const sqrsig=$sigma*sqrt(2*pi);
     );
     nx=(x-center_index)/center_index*$M;
     g=exp(-(nx^2)/sigma_exp)/sqrsig;
     gp=(nx/$sigma^2)*g;
     [g,gp];"
    
    sh. 0 ts={is#-1/$4} rm. /. $ts
    
    +rotate. 90
    
    s[-2,-1] c
    
    +convolve[0] [-4]
    convolve. [-2]
    +convolve[0] [-3]
    convolve. [-5]
    *. {cos($theta)}
    *.. {sin($theta)}
    add.. .
    
    k[0,-2]

     

     

    Note: Don't bother editing radius limit into more than 50. I would advise you to go into the G'MIC Emboss/Relief if you need it since it's faster with higher value there.

    • Like 2
    • Upvote 1
  3. Why is this so slow? The other time I did something like this, it was much faster. It's on PreRender that's the problem. Take out the code in Render, and it's still slow.

     

    Spoiler
    // Name: Emboss / Relief +
    // Submenu: Stylize
    // Author: Reptorian
    // Title: Emboss / Relief +
    // Version:
    // Desc:
    // Keywords:
    // URL:
    // Help:
    #region UICode
    IntSliderControl radius = 5; // [5,100] Radius
    AngleControl var_angle = 45; // [-180,180] Angle
    DoubleSliderControl sigma = 0.5; // [0.5,4] Sigma
    DoubleSliderControl scale_value = 2; // [0.5,10] Value Scale
    ListBoxControl output = 0; // Output|Emboss|Relief
    #endregion
    
    double[] convolve_a;
    double[] convolve_b;
    
    int cut(int v,int image_max_index){
        return Math.Max(0,Math.Min(v,image_max_index));
    }
    
    int d2i(double v){
        return (int)(Math.Round(v));
    }
    
    // This single-threaded function is called after the UI changes and before the Render function is called
    // The purpose is to prepare anything you'll need in the Render function
    void PreRender(Surface dst, Surface src)
    {
        convolve_a = new double[radius];
        convolve_b = new double[radius];
    
        double d_radius = (double)(radius-1);
        double center_index = d_radius / 2;
        double sigma_exp = 2 * sigma * sigma;
        double sqrsig= sigma * Math.Sqrt(2*Math.PI);
        double M = 3* sigma;
    
        double vp,g,gp;
        double sum=0;
    
        for (int p = 0 ; p < radius ; radius++){
            vp = (p - center_index)/center_index*M;
            g = Math.Exp(-(vp*vp)/sigma_exp)/sqrsig;
            gp = (vp / (sigma*sigma))*g;
            sum+=g;
            convolve_a[p]=g;
            convolve_b[p]=gp;
        }
        double scaling = sum / scale_value;
        for (int p = 0 ; p < radius ; radius++){
            convolve_a[p]/=scaling;
            convolve_b[p]/=scaling;
        }
    
    }
    
    // Here is the main multi-threaded render function
    // The dst canvas is broken up into rectangles and
    // your job is to write to each pixel of that rectangle
    void Render(Surface dst, Surface src, Rectangle rect)
    {
        double theta = var_angle / 180 * Math.PI;
        double cos_theta = Math.Cos(theta);
        double sin_theta = Math.Sin(theta);
        int max_x = src.Width - 1;
        int max_y = src.Height - 1;
        int center = (int)(Math.Ceiling((double)(radius)/2));
        double inner_convolve_a_r,inner_convolve_a_g,inner_convolve_a_b,inner_convolve_b_r,inner_convolve_b_g,inner_convolve_b_b;
        double outer_convolve_a_r,outer_convolve_a_g,outer_convolve_a_b,outer_convolve_b_r,outer_convolve_b_g,outer_convolve_b_b;
        double result_r,result_g,result_b;
        int new_r,new_g,new_b;
    
        int start_x,start_y;
    
        ColorBgra Reference_Color_A,Reference_Color_B;
    
        // Step through each row of the current rectangle
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;
            // Step through each pixel on the current row of the rectangle
            for (int x = rect.Left; x < rect.Right; x++)
            {
                start_x=x-center;
                start_y=y-center;
    
                inner_convolve_a_r = inner_convolve_a_g = inner_convolve_a_b = inner_convolve_b_r = inner_convolve_b_g = inner_convolve_b_b = 0;
               
                outer_convolve_a_r = outer_convolve_a_g = outer_convolve_a_b = outer_convolve_b_r = outer_convolve_b_g = outer_convolve_b_b = 0;
    
                for (int p = 0 ; p < radius ; p++)
                {
                    for (int q = 0 ; q < radius ; q++)
                    {
                        Reference_Color_A = src[cut(start_x+q,max_x),cut(start_y+p,max_y)];
                        inner_convolve_a_r+=(double)(Reference_Color_A.R)*convolve_a[q];
                        inner_convolve_a_g+=(double)(Reference_Color_A.G)*convolve_a[q];
                        inner_convolve_a_b+=(double)(Reference_Color_A.B)*convolve_a[q];
    
                        Reference_Color_B = src[cut(start_x+p,max_x),cut(start_y+q,max_y)];
                        inner_convolve_b_r+=(double)(Reference_Color_B.R)*convolve_b[q];
                        inner_convolve_b_g+=(double)(Reference_Color_B.G)*convolve_b[q];
                        inner_convolve_b_b+=(double)(Reference_Color_B.B)*convolve_b[q];
    
                    }
    
                    outer_convolve_a_r += inner_convolve_a_r * convolve_b[p];
                    outer_convolve_a_g += inner_convolve_a_r * convolve_b[p];
                    outer_convolve_a_b += inner_convolve_a_r * convolve_b[p];
                    outer_convolve_b_r += inner_convolve_a_r * convolve_a[p];
                    outer_convolve_b_g += inner_convolve_a_r * convolve_a[p];
                    outer_convolve_b_b += inner_convolve_a_r * convolve_a[p];
                    inner_convolve_a_r = inner_convolve_a_g = inner_convolve_a_b = inner_convolve_b_r = inner_convolve_b_g = inner_convolve_b_b = 0;
                }
    
                result_r = cos_theta * outer_convolve_a_r + sin_theta * outer_convolve_b_r ;
                result_g = cos_theta * outer_convolve_a_g + sin_theta * outer_convolve_b_g ;
                result_b = cos_theta * outer_convolve_a_b + sin_theta * outer_convolve_b_b ;
    
                if (output == 1)
                {
                    new_r = src[x,y].R + d2i(result_r);
                    new_g = src[x,y].G + d2i(result_g);
                    new_b = src[x,y].B + d2i(result_b);
                    dst[x,y] = ColorBgra.FromBgraClamped(new_b,new_g,new_r,src[x,y].A);
    
                }
                else
                {
                    new_r = 128 + d2i(result_r);
                    new_g = 128 + d2i(result_g);
                    new_b = 128 + d2i(result_b);
                    dst[x,y] = ColorBgra.FromBgraClamped(new_b,new_g,new_r,src[x,y].A);
                }
            }
        }
    }

     

     

  4. 35 minutes ago, Red ochre said:

    would the fractal algorithm work with some small random factor added in?

    Unfortunately, it would not be easy to add it in. If it were possible to do post-processing Dents without resorting to gmic-pdn route or plain c# in visual studio (I only know how to do the former), then I could add it. This is why I release my source code other than belief in open-knowledge.

     

    Thank you anyways.

  5. Bifurcation diagram for two-parameters of torus-map or three-coupled oscillators.

     

    Preview:

     

    unknown.png

     

    Download Plugin -> ThreeCoupledOscillators.zip

     

    After install, it's under Effect->Texture.

     

    ------------------------

    License : CeCiLL v2.0 - https://cecill.info/licences/Licence_CeCILL_V2-en.html

     

    Codelab Source Code

    Spoiler
    // Name: Three-Coupled Oscillators
    // Submenu: Texture
    // Author: Reptorian
    // Title: Three-Coupled Oscillators
    // Version: 1
    // Desc: Bifurcation diagram for two-parameters of torus-map or three-coupled oscillators
    // Keywords: Texture, Oscillators
    // URL: https://forums.getpaint.net/profile/85868-reptillian/
    // Help:
    
    /*
    
    Source: 
    
    [C. Baesens, J. Guckenheimer, S. Kim, R.S. MacKay
    Three coupled oscillators: mode-locking, global bifurcations and toroidal chaos 
    Physica D: Nonlinear Phenomena, Volume 49, Issue 3, 1991, Pages 387-475, 
    ISSN 0167-2789]
    
    */
    
    #region UICode
    IntSliderControl max_iter = 50; // [1,200] Maximum Iteration
    DoubleSliderControl k_a_perc = 50; // [-100,100] K-A Tau (%)
    DoubleSliderControl k_b_perc = -50; // [-100,100] K-B Tau (%)
    AngleControl variable_angle = 45; // [-180,180] Angle
    DoubleSliderControl axis_scale = 2; // [1,15] Axis-Scale
    PanSliderControl point_xy = Pair.Create(0.000, 0.000); // Point
    CheckboxControl antialiased_mode = true; // Use Anti-aliasing?
    ListBoxControl color_order = 0; // {color_mode} Color Setting|0-1-2|0-2-1|1-0-2|1-2-0|2-0-1|2-1-0
    CheckboxControl color_mode = true; // Color Mode
    DoubleSliderControl mult = 1; // [0,10] Multiplier
    DoubleSliderControl tau_add = 0; // [-100,100] Add by Tau (%)
    #endregion
    
    double tau = 2 * Math.PI;
    double tc = .7 / (2 * Math.PI);
    
    double rot_x(double a, double b, double sin_ang,double cos_ang){
        return a*cos_ang-b*sin_ang;
    }
    
    double rot_y(double a, double b, double sin_ang,double cos_ang){
        return a*sin_ang+b*cos_ang;
    }
    
    double oscil_a(double a,double b, double k_a){
        return a+k_a-tc*Math.Sin(tau*b);
    }
    
    double oscil_b(double a,double b, double k_b){
        return a+k_b-tc*Math.Sin(tau*b);
    }
    
    double norm2(double a,double b){
        return Math.Sqrt(a*a+b*b);
    }
    
    int[] col_order = new int[3];
    
    void define_color_order(int r,int g,int b){
        col_order[0]=r;
        col_order[1]=g;
        col_order[2]=b;
    }
    
    void PreRender(Surface dst, Surface src)
    {
        switch(color_order){
            case 0: define_color_order(0,1,2);
            break;
            case 1: define_color_order(0,2,1);
            break;
            case 2: define_color_order(1,0,2);
            break;
            case 3: define_color_order(1,2,0);
            break;
            case 4: define_color_order(2,0,1);
            break;
            case 5: define_color_order(2,1,0);
            break;
        }
    }
    
    void Render(Surface dst, Surface src, Rectangle rect)
    {
        int ww = src.Width-1;
        int hh = src.Height-1;
        double d_ww=(double)(ww);
        double d_hh=(double)(hh);
        double sd = Math.Max(d_ww,d_hh)/Math.Min(d_ww,d_hh);
        double sx = ww>hh?sd:1;
        double sy = ww>hh?1:sd;
        double cx = d_ww/2;
        double cy = d_hh/2;
        double cxsx=cx/sx/axis_scale;
        double cysy=cy/sy/axis_scale;
        double ang = variable_angle/180*Math.PI;
        double sin_ang=Math.Sin(ang);
        double cos_ang=Math.Cos(ang);
        double k_a=k_a_perc/100*tau;
        double k_b=k_b_perc/100*tau;
        double ix,iy,txp,xp,yp,ev,disp;
        double shift_tau = tau_add/100*tau;
        int lim=antialiased_mode?2:1;
        byte r,g,b,avg;
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;       
            
            for (int x = rect.Left; x < rect.Right; x++)
            {
                ev=0;
                double[] col = new double[3] {0,0,0};
                for (int m = 0 ; m < lim ; m++){
                    disp=m*.5;
                    iy=(y+disp-cy)/cysy;
                    ix=(x+disp-cx)/cxsx;
                    ix-=point_xy.First;
                    iy-=point_xy.Second;
                    xp=rot_x(ix,iy,sin_ang,cos_ang);
                    yp=rot_y(ix,iy,sin_ang,cos_ang);
                    for (int n = 0 ; n < max_iter ; n ++){
                        txp=xp;
                        xp=oscil_a(xp,yp,k_a);
                        yp=oscil_b(yp,txp,k_b);
                    }
                    ev=norm2(xp,yp)*mult+shift_tau;
                    col[col_order[0]]+=(Math.Sin(ev)+1)/2;
                    col[col_order[1]]+=(Math.Cos(ev)+1)/2;
                    col[col_order[2]]+=(Math.Cos(ev+Math.PI/2)+1)/2;
                }
                col[col_order[0]]/=lim;
                col[col_order[1]]/=lim;
                col[col_order[2]]/=lim;
                r = (byte)((int)(Math.Round(col[0]*255)));
                g = (byte)((int)(Math.Round(col[1]*255)));
                b = (byte)((int)(Math.Round(col[2]*255)));
                if (color_mode){dst[x,y]=ColorBgra.FromBgr(b,g,r);}
                else{
                    avg = (byte)((int)(3*((r+g+b)/3-85)));
                    dst[x,y]=ColorBgra.FromBgr(avg,avg,avg);
                }       
            }
        }
    }

     

    G'MIC Source Code

    Spoiler
    #@cli rep_tco_anim: eq. to 'rep_three_coupled_oscillators_animation' : (+)
    rep_tco_anim: rep_three_coupled_oscillators_animation $*
    #@cli rep_three_coupled_oscillators_animation: _max_iter>0,-2pi<=_k_a_1<=2pi,-2pi<=_k_b_1<=2pi,-2pi<=_k_a_2<=2pi,-2pi<=_k_b_2<=2pi,_sublevel>=0,-360<=_ang_a<=360,-360<=_ang_b<=360,_ox_a,_oy_a,_ox_b,_oy_b,_axis_scale_a>0,_axis_scale_b>0
    #@cli : Animation-based version of Bifurcation diagram for two-parameters of torus-map or three-coupled oscillators. [1]
    #@cli :
    #@cli : --- Citation ---
    #@cli : 1) C. Baesens, J. Guckenheimer, S. Kim, R.S. MacKay
    #@cli : Three coupled oscillators: mode-locking, global bifurcations and toroidal chaos
    #@cli : Physica D: Nonlinear Phenomena, Volume 49, Issue 3, 1991, Pages 387-475, ISSN 0167-2789
    #@cli : ------
    #@cli :
    #@cli : _max_iter is the number of iterations within the bifurcation diagram.
    #@cli : _k_a_1 is the a-variable that influence the output for first frame.
    #@cli : _k_b_1 is the b-variable that influence the output for first frame.
    #@cli : _k_a_2 is the a-variable that influence the output for last frame.
    #@cli : _k_b_2 is the b-variable that influence the output for last frame.
    #@cli : _sublevel defines the degree of subpixel processing. 0 means no subpixel sampling. Negative  number in here means it will not be resized (Useful for mapping before downsizing to original image size.).
    #@cli : _ang_a defines the angle of function for first frame.
    #@cli : _ang_b defines the angle of function for last frame.
    #@cli : _ox_a defines the x-offset of function for first frame.
    #@cli : _oy_a defines the y-offset of function for first fraime.
    #@cli : _ox_b defines the x-offset of function for last frame.
    #@cli : _oy_b defines the y-offset of function for last frame.
    #@cli : _axis_scale_a defines the scale of each axis for first frame.
    #@cli : _axis_scale_b defines the scale of each axis for last frame.
    #@cli :
    #@cli : Author: Reptorian.
    #@cli : Default values: '_max_iter=50','_k_a_1=u(-2*pi,2*pi)','_k_b_1=u(-2*pi,2*pi)','_k_a_2=u(-2*pi,2*pi)','_k_b_2=u(-2*pi,2*pi)','_sublevel=1','_ang_a=0','_ang_b=0','_ox_a=0','_oy_a=0','_ox_b=0','_oy_b=1','_axis_scale_a=1','_axis_scale_b=1'
    rep_three_coupled_oscillators_animation:
    skip ${1=50},${2=},${3=},${4=},${5=},${6=1},${7=0},${8=180},{$9=0},${10=0},${11=0},${12=0},${13=1},${14=1}
    check ${-max_d}>1
    _rep_three_coupled_oscillators ${1-14}
    #@cli rep_tco: eq. to 'rep_three_coupled_oscillators' : (+)
    rep_tco: rep_three_coupled_oscillators $*
    #@cli rep_three_coupled_oscillators: _max_iter>0,-2pi<=_k_a<=2pi,-2pi<=_k_b<=2pi,_sublevel>=0,-360<=_ang<=360,_ox,_oy,_axis_scale>0
    #@cli : Bifurcation diagram for two-parameters of torus-map or three-coupled oscillators. [1]
    #@cli :
    #@cli : --- Citation ---
    #@cli : 1) C. Baesens, J. Guckenheimer, S. Kim, R.S. MacKay
    #@cli : Three coupled oscillators: mode-locking, global bifurcations and toroidal chaos
    #@cli : Physica D: Nonlinear Phenomena, Volume 49, Issue 3, 1991, Pages 387-475, ISSN 0167-2789
    #@cli : ------
    #@cli :
    #@cli : _max_iter is the number of iterations within the bifurcation diagram.
    #@cli : _k_a is a variable that influence the output.
    #@cli : _k_b is a variable that influence the output.
    #@cli : _sublevel defines the degree of subpixel processing. 0 means no subpixel sampling. Negative  number in here means it will not be resized (Useful for mapping before downsizing to original image size.).
    #@cli : _ang defines the angle of function.
    #@cli : _ox defines the x-offset of function.
    #@cli : _oy defines the y-offset of function.
    #@cli : _axis_scale defines the scale of each axis.
    #@cli :
    #@cli : Author: Reptorian.
    #@cli : Default values: '_max_iter=50','_k_a=u(-2*pi,2*pi)','_k_b=u(-2*pi,2*pi)','_sublevel=1','_ang=0','_ox=0','_oy=0','_axis_scale=1'
    rep_three_coupled_oscillators:
    skip ${1=50},${2=},${3=},${4=1},${5=0},${6=0},${7=0},${8=1}
    check ${-max_d}==1
    _rep_three_coupled_oscillators ${1-8}
    _rep_three_coupled_oscillators:
    skip ${1=50},${2=},${3=},${4=},${5=}
    check "abs($1)!=0&&$8!=0"
     
    animation_mode=0
    if ${-max_d}>1 animation_mode=1 if $!>1 error "One image only for animation mode!" fi fi
    
    tau={pi*2}
    
    if $animation_mode
     if narg($2) __k_a_1=$2
     else __k_a_1={u(-$tau,$tau)}
     fi
     
     if narg($3) __k_a_2=$3
     else __k_b_1={u(-$tau,$tau)}
     fi
     
     if narg($4) __k_b_1=$4
     else __k_a_2={u(-$tau,$tau)}
     fi
     
     if narg($5) __k_b_2=$5
     else __k_b_2={u(-$tau,$tau)}
     fi
     
     rescale_back={$6>0}
     
     __sub={abs($6)+1}
     m "generate_three_coupled: +_rep_three_coupled_oscillators_animation $1,$__k_a_1,$__k_b_1,$__k_a_2,$__k_b_2,$__sub,${7-14}"
     
    else
     if narg($2) __k_a=$2
     else __k_a={u(-$tau,$tau)}
     fi
    
     if narg($3) __k_b=$3
     else __k_b={u(-$tau,$tau)}
     fi
    
     rescale_back={$4>0}
     __sub={abs($4)+1}
     
     m "generate_three_coupled: +_rep_three_coupled_oscillators_static_out $1,$__k_a,$__k_b,$__sub,${5-8}"
    fi
    
    repeat $! l[$>]
    
     generate_three_coupled
      
     if $rescale_back r. {w#0},{h#0},100%,100%,6 fi
    
     rm..
     
    endl done
    
    um generate_three_coupled
    +_rep_three_coupled_oscillators_animation:
    check "$13!=0&&$14!=0"
    
     {w*$6},{h*$6},{d},1,"*begin(
       const max_iter=abs($1);
       const ww=w-1;
       const hh=h-1;
       const dd=d-1;
       const sd=max(ww,hh)/min(ww,hh);
       const sx=w>h?sd:1;
       const sy=w>h?1:sd;
       const cx=ww/2;
       const cy=hh/2;
       const ox_a=($9+1)*cx;
       const oy_a=($10+1)*cx;
       const ox_b=(($11*-1)+1)*cy;
       const oy_b=(($12*-1)+1)*cy;
       const axis_scale_a=$13;
       const axis_scale_b=$14;
       const cxsx=cx/sx;
       const cysy=cy/sy;
       const cxsx_a=cxsx/axis_scale_a;
       const cxsx_b=cxsx/axis_scale_b;
       const cysy_a=cysy/axis_scale_a;
       const cysy_b=cysy/axis_scale_b;
       const ang_a=-$7;
       const ang_b=-$8;
       set_cos_ang=vectord();
       set_sin_ang=set_cos_ang;
       fill(set_cos_ang,p,cos(deg2rad(lerp(ang_a,ang_b,p/dd))));
       fill(set_sin_ang,p,sin(deg2rad(lerp(ang_a,ang_b,p/dd))));
       const tau=2*pi;
       const k_a_1=$2;
       const k_b_1=$3;
       const k_a_2=$4;
       const k_b_2=$5;
       const tc=.7/tau;
       rot_x(a,b,c)=a*set_cos_ang[c]-b*set_sin_ang[c];
       rot_y(a,b,c)=a*set_sin_ang[c]+b*set_cos_ang[c];
       oscil_a(a,b,c)=a+c-tc*sin(tau*b);
       oscil_b(a,b,c)=a+c-tc*sin(tau*b);
      );
      zp=z/dd;
      ix=(x-lerp(ox_a,ox_b,zp))/lerp(cxsx_a,cxsx_b,zp);
      iy=(y-lerp(oy_a,oy_b,zp))/lerp(cysy_a,cysy_b,zp);
      xp=rot_x(ix,iy,z);
      yp=rot_y(ix,iy,z);
      k_a=lerp(k_a_1,k_b_1,zp);
      k_b=lerp(k_a_2,k_b_2,zp);
      repeat(max_iter,
       txp=xp;
       xp=oscil_a(xp,yp,k_a);
       yp=oscil_b(yp,txp,k_b);
      );
      norm(xp,yp);"
    +_rep_three_coupled_oscillators_static_out:
    check "$8!=0"
    
     {w*$4},{h*$4},1,1,*"begin(
       const max_iter=abs($1);
       const ww=w-1;
       const hh=h-1;
       const sd=max(ww,hh)/min(ww,hh);
       const sx=w>h?sd:1;
       const sy=w>h?1:sd;
       const cx=ww/2;
       const cy=hh/2;
       const ox=($6+1)*cx;
       const oy=(($7*-1)+1)*cy;
       const axis_scale=abs($8);
       const cxsx=cx/sx/axis_scale;
       const cysy=cy/sy/axis_scale;
       const ang=-($5/180)*pi;
       const cos_ang=cos(ang);
       const sin_ang=sin(ang);
       const tau=2*pi;
       const k_a=$2;
       const k_b=$3;
       const tc=.7/tau;
       rot_x(a,b)=a*cos_ang-b*sin_ang;
       rot_y(a,b)=a*sin_ang+b*cos_ang;
       oscil_a(a,b)=a+k_a-tc*sin(tau*b);
       oscil_b(a,b)=a+k_b-tc*sin(tau*b);
      );
      ix=(x-ox)/cxsx;
      iy=(y-oy)/cysy;
      xp=rot_x(ix,iy);
      yp=rot_y(ix,iy);
      repeat(max_iter,
       txp=xp;
       xp=oscil_a(xp,yp);
       yp=oscil_b(yp,txp);
      );
      norm(xp,yp);"

     

     

    • Like 2
    • Upvote 2
  6. 2 hours ago, NinthDesertDude said:

    if b_ev just goes from 0 to 255 you could use it as the alpha to lerp between two colors using the ColorBgra.Blend(colorA, colorB, alphaB) overload

     

    I resorted to trying to find a color formula instead:

     

    2zBVzx2.png

     

    Quite limited, but it's better than before.

     

    // Name:
    // Submenu:
    // Author:
    // Title:
    // Version:
    // Desc:
    // Keywords:
    // URL:
    // Help:
    #region UICode
    IntSliderControl max_iter = 50; // [1,200] Maximum Iteration
    DoubleSliderControl k_a_perc = 50; // [-100,100] K-A Tau (%)
    DoubleSliderControl k_b_perc = -50; // [-100,100] K-B Tau (%)
    AngleControl variable_angle = 45; // [-180,180] Angle
    DoubleSliderControl axis_scale = 2; // [1,15] Axis-Scale
    PanSliderControl point_xy = Pair.Create(0.000, 0.000); // Point
    CheckboxControl antialiased_mode = true; // Use Anti-aliasing?
    #endregion
    
    double tau = 2 * Math.PI;
    double tc = .7 / (2 * Math.PI);
    
    double rot_x(double a, double b, double sin_ang,double cos_ang){
        return a*cos_ang-b*sin_ang;
    }
    
    double rot_y(double a, double b, double sin_ang,double cos_ang){
        return a*sin_ang+b*cos_ang;
    }
    
    double oscil_a(double a,double b, double k_a){
        return a+k_a-tc*Math.Sin(tau*b);
    }
    
    double oscil_b(double a,double b, double k_b){
        return a+k_b-tc*Math.Sin(tau*b);
    }
    
    double norm2(double a,double b){
        return Math.Sqrt(a*a+b*b);
    }
    
    void Render(Surface dst, Surface src, Rectangle rect)
    {
        int ww = src.Width-1;
        int hh = src.Height-1;
        double d_ww=(double)(ww);
        double d_hh=(double)(hh);
        double sd = Math.Max(d_ww,d_hh)/Math.Min(d_ww,d_hh);
        double sx = ww>hh?sd:1;
        double sy = ww>hh?1:sd;
        double cx = d_ww/2;
        double cy = d_hh/2;
        double cxsx=cx/sx/axis_scale;
        double cysy=cy/sy/axis_scale;
        double ang = variable_angle/180*Math.PI;
        double sin_ang=Math.Sin(ang);
        double cos_ang=Math.Cos(ang);
        double k_a=k_a_perc/100*tau;
        double k_b=k_b_perc/100*tau;
        double ix,iy,txp,xp,yp,ev,disp;
        int lim=antialiased_mode?2:1;
        byte r,g,b;
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;       
            
            for (int x = rect.Left; x < rect.Right; x++)
            {
                ev=0;
                double[] col = new double[3] {0,0,0};
                for (int m = 0 ; m < lim ; m++){
                    disp=m*.5;
                    iy=(y+disp-cy)/cysy;
                    ix=(x+disp-cx)/cxsx;
                    ix-=point_xy.First;
                    iy-=point_xy.Second;
                    xp=rot_x(ix,iy,sin_ang,cos_ang);
                    yp=rot_y(ix,iy,sin_ang,cos_ang);
                    for (int n = 0 ; n < max_iter ; n ++){
                        txp=xp;
                        xp=oscil_a(xp,yp,k_a);
                        yp=oscil_b(yp,txp,k_b);
                    }
                    ev=norm2(xp,yp);
                    col[0]+=(Math.Sin(ev)+1)/2;
                    col[1]+=(Math.Cos(ev+ev/2)+1)/2;
                    col[2]+=(Math.Sin(ev*2)+1)/2;
                }
                col[0]/=lim;
                col[1]/=lim;
                col[2]/=lim;
                r = (byte)((int)(Math.Round(col[0]*255)));
                g = (byte)((int)(Math.Round(col[1]*255)));
                b = (byte)((int)(Math.Round(col[2]*255)));
                dst[x,y]=ColorBgra.FromBgr(b,g,r);
            }
        }
    }

     

  7. This is yet another translation of my filter. I'm working exclusively with Render. Might be done, or not.

     

    Output:

     

    2qgj1VJ.png

     

    Here are the TODOs list:

    1) Enable Anti-aliasing

    2) Find ways to color the image

     

    // Name:
    // Submenu:
    // Author:
    // Title:
    // Version:
    // Desc:
    // Keywords:
    // URL:
    // Help:
    #region UICode
    IntSliderControl max_iter = 50; // [1,200] Maximum Iteration
    DoubleSliderControl k_a_perc = 50; // [-100,100] K-A Tau (%)
    DoubleSliderControl k_b_perc = -50; // [-100,100] K-B Tau (%)
    AngleControl variable_angle = 45; // [-180,180] Angle
    DoubleSliderControl axis_scale = 2; // [1,15] Axis-Scale
    PanSliderControl point_xy = Pair.Create(0.000, 0.000); // Point
    CheckboxControl antialiased_mode = true; // Use Anti-aliasing?
    #endregion
    
    double tau = 2 * Math.PI;
    double tc = .7 / (2 * Math.PI);
    
    double rot_x(double a, double b, double sin_ang,double cos_ang){
        return a*cos_ang-b*sin_ang;
    }
    
    double rot_y(double a, double b, double sin_ang,double cos_ang){
        return a*sin_ang+b*cos_ang;
    }
    
    double oscil_a(double a,double b, double k_a){
        return a+k_a-tc*Math.Sin(tau*b);
    }
    
    double oscil_b(double a,double b, double k_b){
        return a+k_b-tc*Math.Sin(tau*b);
    }
    
    double norm2(double a,double b){
        return Math.Sqrt(a*a+b*b);
    }
    
    void Render(Surface dst, Surface src, Rectangle rect)
    {
        int ww = src.Width-1;
        int hh = src.Height-1;
        double d_ww=(double)(ww);
        double d_hh=(double)(hh);
        double sd = Math.Max(d_ww,d_hh)/Math.Min(d_ww,d_hh);
        double sx = ww>hh?sd:1;
        double sy = ww>hh?1:sd;
        double cx = d_ww/2;
        double cy = d_hh/2;
        double ox = (point_xy.First+1)*cx;
        double oy = (point_xy.Second+1)*cy;
        double cxsx=cx/sx/axis_scale;
        double cysy=cy/sy/axis_scale;
        double ang = variable_angle/180*Math.PI;
        double sin_ang=Math.Sin(ang);
        double cos_ang=Math.Cos(ang);
        double k_a=k_a_perc/100*tau;
        double k_b=k_b_perc/100*tau;
        double ix,iy,txp,xp,yp,ev;
        int i_ev;
        byte b_ev;
    
        for (int y = rect.Top; y < rect.Bottom; y++)
        {
            if (IsCancelRequested) return;
            iy=(y-oy)/cysy;
            for (int x = rect.Left; x < rect.Right; x++)
            {
                ix=(x-ox)/cxsx;
                xp=rot_x(ix,iy,sin_ang,cos_ang);
                yp=rot_y(ix,iy,sin_ang,cos_ang);
                for (int n = 0 ; n < max_iter ; n ++){
                    txp=xp;
                    xp=oscil_a(xp,yp,k_a);
                    yp=oscil_b(yp,txp,k_b);
                }
                ev = norm2(xp,yp);
                i_ev=(int)(Math.Round(ev*200));
                b_ev=(byte)(i_ev);
                dst[x,y] = ColorBgra.FromBgr(b_ev,b_ev,b_ev);
            }
        }
    }

     

     

  8. @AndrewDavid

     

    All I could do is rebuild, and then reupload the TiledFormGmicPdn.zip. That is what I did, and this is the last time I'll do this. Download once more. The code doesn't show a problem, and @lynxster4 and I can confirm that they work without problem. If it doesn't work on your side, there's not much I can do about it other than resorting to C#, and going with very difficult to maintain code. There is a possibility of a image being a problem, do PM me the offending image of the problem layer to see if I can replicate the problem.

     

    This is the metadata information of the .zip file I uploaded and recently built from Visual Studio + send to .zip - ‎Modified: Thursday, ‎December ‎2, ‎2021, ‏‎3:22:15 P

     

×
×
  • Create New...