Jump to content

Trying to make smooth transition with this code. Something like Color.Brga(lerp(color_a,color_b,finalgradient))


Recommended Posts

Posted (edited)

This is more of a continuation of the other thread as that problem has been solved.

 

This is the complete line of code that is giving me a problem

 

dst[x,y]=ColorBgra.FromBgra((byte)(lerp((double)(space_color_a.B),(double)(space_color_b.B),final_gradient)),(byte)(lerp((double)(space_color_a.G),(double)(space_color_b.G),final_gradient)),(byte)(lerp((double)(space_color_a.R),(double)(space_color_b.R),final_gradient)),(byte)(spaces ? 255 : 0));

 

What I"m trying to achieve is a colored gradient effect depending on final_gradient. Also, HsvColor.ToRgb() would the correct route for converting HSV (The code has random Hue as option)? There's also the observation that reseed does nothing, but that's for another day.

Spoiler



// Name:
// Submenu:
// Author:
// Title:
// Version:
// Desc:
// Keywords:
// URL:
// Help:
#region UICode
ReseedButtonControl seed = 0; // Reseed
IntSliderControl bar_size = 50; // [1,256] Bar Size
IntSliderControl space_size = 0; // [0,256] Space Size
AngleControl degree = 45; // [-180,180] Angle
DoubleSliderControl skew_degree = 0; // [-89,89] Skew Angle
PanSliderControl origin = Pair.Create(0.0,0.0); // Origin
IntSliderControl sublevel = 0; // [0,3] Subsampling
DoubleSliderControl shift = 0; // [0,100] Shift
DoubleSliderControl mult_1 = 0.1; // [0.1,256] Multiplier A
DoubleSliderControl mult_2 = 100; // [0.1,256] Multiplier B
ListBoxControl repetition_mode = 0; // Repetition|Random|Cut|Periodic|Continuous
ListBoxControl repetition_random_repetition_modes = 0; // Random Bar Repetition|All|Cut and Periodic|Cut and Continuous|Periodic and Continuous
ListBoxControl color_space = 0; // Color|Gray|Duotone|Random-RGB|Random-HSV
ListBoxControl space_mode = 0; // Space Mode|Alpha|Cut|Gradient
ListBoxControl symmetry = 0; // Symmetry Mode|N/A|A|B
CheckboxControl inversion_mode = false; // Use Inversion
ColorWheelControl space_color_a = ColorBgra.FromBgr(0, 140, 255); // [DarkOrange] Space Color A
ColorWheelControl space_color_b = ColorBgra.FromBgr(0, 215, 255); // [Gold] Space Color B
#endregion
double[] v_base = null;
double[] v_shift = null;
double[] v_mult = null;
int[] v_modulo_out = null;
bool[] v_invert = null;
int[] v_hue = null;
int[] v_rgb_r = null;
int[] v_rgb_g = null;
int[] v_rgb_b = null;
double ang;
int number_of_bars;
int shift_bars;

double cut(double a,double b,double c){
    double min_val = Math.Min(b,c);
    double max_val = Math.Max(b,c);
    return (a < min_val) ? min_val : (a > max_val) ? max_val : a;
}

double fmod(double a, double b){
    return a - Math.Floor(a / b) ;
}

int imod(int a, int b){
    int r = a % b;
    return r < 0 ? r + b : r;
}

double fmod_cont(double a, double b){
    double ind = imod((int)(Math.Floor(a/b)),2) ;
    return ind == 1 ? b - fmod(a,b) : fmod(a,b) ;
}

double fcut(double a, double b){
    return (cut(a,-b,b)+b)/2 ;
}


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 lerp(double a, double b, double t){
    return a + (1 - t) * b * t ;
}

void PreRender(Surface dst, Surface src)
{
    Random myRandom = new Random(int.MaxValue);
    int ww = src.Width - 1 ;
    int hh = src.Height - 1 ;
    double cx = (double)(ww) / 2 ;
    double cy = (double)(hh) / 2 ;
    double cut_ang = Math.Atan2(cy,cx) ;
    double cut_ang_2 = Math.PI - cut_ang ;
    ang = ( degree / 180 ) / Math.PI ;
    double trimmed_ang = ang % Math.PI ;
    bool use_shift = shift > 0 ;
    int total_width = bar_size + space_size;
    double d_total_width = (double)(total_width);
    double d_ww = (double)(ww);
    double d_hh = (double)(hh);

    if ((trimmed_ang>=cut_ang)&&(trimmed_ang<cut_ang)){
        number_of_bars =(int)(Math.Ceiling((Math.Abs(1/Math.Sin(ang))*d_ww)/d_total_width));
    }
    else
    {
        number_of_bars =(int)(Math.Ceiling((Math.Abs(1/Math.Cos(ang))*d_hh)/d_total_width));
    }

    shift_bars = number_of_bars / 2;

    v_base = new double[number_of_bars];
    v_modulo_out = new int[number_of_bars];
    v_invert = new bool[number_of_bars];
    v_shift = new double[number_of_bars];   

    for(int n = 0 ; n < number_of_bars ; n++){
        v_base[n] = 0;
        v_invert[n] = false ;
    }


    Array.Copy(v_base, v_shift, v_base.Length);

    double shift_dist;
    int precision = 100000;

    if (use_shift){
        for(int n = 0 ; n < number_of_bars ; n++){
            shift_dist = (double)(myRandom.Next(precision)) / (double)(precision) ;
            shift_dist*=shift;
            if (myRandom.Next(255) > 128){
                v_shift[n] = shift_dist;
            }
            else{
                v_shift[n] = -shift_dist;
            }
        }
    }

    if (repetition_mode > 0) {
        int rep_pos=repetition_mode - 1 ;
        for(int n = 0 ; n < number_of_bars ; n++){
            v_modulo_out[n]=rep_pos;
        }
    }
    else{
        switch(repetition_random_repetition_modes){
            case 1:
                for(int n = 0 ; n < number_of_bars ; n++){
                    v_modulo_out[n] = myRandom.Next(2);
                }
                break;
            case 2:
                for(int n = 0 ; n < number_of_bars ; n++){
                    v_modulo_out[n] = myRandom.Next(2)*2;
                }
                break;
            case 3:
                for(int n = 0 ; n < number_of_bars ; n++){
                    v_modulo_out[n] = myRandom.Next(2)+1;
                }                
                break;
            default:
                for(int n = 0 ; n < number_of_bars ; n++){
                    v_modulo_out[n] = myRandom.Next(3);
                }  
                
                break;
        }
    }

    if (inversion_mode){
        for(int n = 0 ; n < number_of_bars ; n++){
            if (myRandom.Next(255) > 128){
                v_invert[n] = true;
            }
        }
    }

    v_hue = new int[number_of_bars];
    v_rgb_r = new int[number_of_bars];
    v_rgb_g = new int[number_of_bars];
    v_rgb_b = new int[number_of_bars];
    v_mult = new double[number_of_bars];

    for(int n = 0 ; n < number_of_bars ; n++){
        v_hue[n] = myRandom.Next(359);
        v_rgb_r[n] = myRandom.Next(255);
        v_rgb_g[n] = myRandom.Next(255);
        v_rgb_b[n] = myRandom.Next(255);
        v_mult[n] = lerp(mult_1,mult_2,(double)(myRandom.Next(precision))/(double)(precision));
    }

}

void Render(Surface dst, Surface src, Rectangle rect)
{
    // Delete any of these lines you don't need
    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 = d_ww>d_hh?sd:1;
    double sy = d_ww>d_hh?1:sd;
    double cx = (double)(ww) / 2 ;
    double cy = (double)(hh) / 2 ;
    double ox = cx - ((double)(cx)*-origin.First);
    double oy = cy - ((double)(cy)*-origin.Second);
    double ww_div_sx = (double)(ww)/sx;
    double hh_div_sy = (double)(hh)/sy;
    double pyth_img = Math.Sqrt(d_ww*d_ww+d_hh*d_hh);
    double ren_ang = ( degree / 180 ) * Math.PI ;
    double skew_ang = ( skew_degree / 180)*Math.PI;
    double cos_ang = Math.Cos(ren_ang);
    double sin_ang = Math.Sin(ren_ang);
    double mdist = Math.Tan(skew_ang)*pyth_img;
    int total_width = bar_size + space_size;
    bool width_test = total_width>1;
    bool bar_and_space_test = (bar_size==1)&&(space_size<2);
    bool space_test = space_size > 0;
    int half_total_width = width_test ? total_width / 2 : 0 ;
    double initial_x,initial_y,spacing,gradient,point_x,new_gradient,final_gradient;
    int bar,bar_id,use_modulo_out,result;
    bool spaces;
    double temp_result;
    double temp_result_2;

    ColorBgra Bar_And_Space_Fill;

    if (bar_and_space_test){
        spacing = (space_size>0)?.5:0;
    }
    else{
        spacing = 1 - ((double)(space_size)/((double)(total_width) - 1));
    }

    for (int y = rect.Top; y < rect.Bottom; y++)
    {
        if (IsCancelRequested) return;
        for (int x = rect.Left; x < rect.Right; x++)
        {
             initial_x = ((double)(x) - ox) / d_ww * sx;
             initial_y = ((double)(y) - oy ) / d_hh * sy;
             gradient = -rot_y(initial_x,initial_y,sin_ang,cos_ang)*hh_div_sy/pyth_img;
             point_x = rot_x(initial_x,initial_y,sin_ang,cos_ang)*ww_div_sx+gradient*mdist+half_total_width;
             bar_id = (int)(Math.Floor(point_x/total_width));

             switch(symmetry){
                 case 2:   bar = imod(-Math.Abs(bar_id)+shift_bars,number_of_bars);break;
                 case 1:   bar = imod(Math.Abs(bar_id)+shift_bars,number_of_bars);break;
                 default:  bar = imod(bar_id+shift_bars,number_of_bars);break;
             }

             if(bar_and_space_test) {
                 if (space_test){
                     spaces = imod((int)(point_x),2) == 1 ;
                 }
                 else{
                     spaces = true;
                 }

             }
             else {
                 spaces = 2*Math.Abs(fmod(point_x/total_width,1)-.5)<=spacing;
             
             }

             new_gradient = gradient * v_mult[bar] + v_shift[bar];
             use_modulo_out = v_modulo_out[bar];

             switch(use_modulo_out){
                 case 2: final_gradient = v_invert[bar] ? 1 - fmod_cont(new_gradient,1) : fmod_cont(new_gradient,1); break;
                 case 1: final_gradient = v_invert[bar] ? 1 - fmod(new_gradient,1) : fmod(new_gradient,1); break;
                 default: final_gradient= v_invert[bar] ? 1 - fcut(new_gradient,1) : fcut(new_gradient,1); break;
             }

             switch(color_space){
                 case 3: switch(space_mode){
                    case 2:
                        break;
                    case 1:
                        break;
                    default:
                        break;

                    }
                    break;
                 case 2: switch(space_mode){
                    case 2:
                        break;
                    case 1:
                        break;
                    default:
                        break;

                    }
                    break;
                 case 1: switch(space_mode){
                    case 2:
                        temp_result = Math.Round(255 * final_gradient);
                        temp_result_2 = cut(gradient*2+.5,0,1) * 255;
                        temp_result = spaces ? temp_result : temp_result_2;
                        dst[x,y]=ColorBgra.FromBgr((byte)(temp_result),(byte)(temp_result),(byte)(temp_result));
                        break;
                    case 1:
                        temp_result = spaces ? Math.Round(255 * final_gradient) : (gradient >= 0 ? 255 : 0);
                        dst[x,y]=ColorBgra.FromBgr((byte)(temp_result),(byte)(temp_result),(byte)(temp_result));
                        break;
                    default: 
                        dst[x,y]=ColorBgra.FromBgra((byte)(lerp((double)(space_color_a.B),(double)(space_color_b.B),final_gradient)),(byte)(lerp((double)(space_color_a.G),(double)(space_color_b.G),final_gradient)),(byte)(lerp((double)(space_color_a.R),(double)(space_color_b.R),final_gradient)),(byte)(spaces ? 255 : 0));
                        break;
                    }
                    break;
                    default: switch(space_mode){
                    case 2:
                        temp_result = Math.Round(255 * final_gradient);
                        temp_result_2 = cut(gradient*2+.5,0,1) * 255;
                        temp_result = spaces ? temp_result : temp_result_2;
                        dst[x,y]=ColorBgra.FromBgr((byte)(temp_result),(byte)(temp_result),(byte)(temp_result));
                        break;
                    case 1:
                        temp_result = spaces ? Math.Round(255 * final_gradient) : (gradient >= 0 ? 255 : 0);
                        dst[x,y]=ColorBgra.FromBgr((byte)(temp_result),(byte)(temp_result),(byte)(temp_result));
                        break;
                    default: 
                        temp_result = Math.Round(255 * final_gradient);
                        dst[x,y]=ColorBgra.FromBgra((byte)(temp_result),(byte)(temp_result),(byte)(temp_result),(byte)(spaces ? 255 : 0));
                        break;
                    }
                    break;
             }


        }
    }
}

 

 

Edited by Reptillian

G'MIC Filter Developer

Link to comment
Share on other sites

  • Reptillian changed the title to Trying to make smooth transition with this code. Something like Color.Brga(lerp(color_a,color_b,finalgradient))
Posted (edited)
10 hours ago, toe_head2001 said:

 

What kind of issue is it causing?

 

Strange color with the original code. Change color_space into 1, and you'll see what I mean.

 

I'm not getting the desired result with this.

 

dst[x,y]=ColorBgra.FromBgr(
	(byte)((int)(lerp((double)(sc_a_B),(double)(sc_b_B),final_gradient))),
	(byte)((int)(lerp((double)(sc_a_G),(double)(sc_b_G),final_gradient))),
	(byte)((int)(lerp((double)(sc_a_R),(double)(sc_b_R),final_gradient)))
);

5eTtprm.png

There is suppose to be a transition. There is not a transition. This code does work better than the first one, however, see what I mean? :

 

EDIT : I solve it. lerp formula was wrong. So sorry about that. This is the fix.

double lerp(double a, double b, double t){
    return a * (1 - t) + b * t ;
}
Edited by Reptillian

G'MIC Filter Developer

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...