/** operators.h * J Scott Cameron * * This file defines all the variables and functions * to be used by the Genetic Images */ #include "trees.h" #define PI 3.14159 /* X and Y Variables */ static Val pop_x,pop_y; static char x_name[] = "X"; static char y_name[] = "Y"; static Variable X = {&pop_x,x_name}; static Variable Y = {&pop_y,y_name}; // function for adding 2 values static Val add(Val a, Val b) { return (a+b); } static char add_sign[] = "+"; static Binary_Func Add = {add, add_sign}; // function for subtraction static Val sub(Val a, Val b) { return (a-b); } static char sub_sign[] = "-"; static Binary_Func Sub = {sub, sub_sign}; // multiplication static Val mult(Val a, Val b) { return (a*b); } static char mult_sign[] = "*"; static Binary_Func Mult = {mult, mult_sign}; // safe division static Val div(Val a, Val b) { return (a/b); } static char div_sign[] = "/"; static Binary_Func Div = {div, div_sign}; // mod static Val mod(Val a, Val b) { return (a%b); } static char mod_sign[] = "%"; static Binary_Func Mod = {mod, mod_sign}; // greater than static Val gt(Val a, Val b) { return(a > b); } static char gt_sign [] = ">"; static Binary_Func GT = {gt, gt_sign}; // less than static Val lt(Val a, Val b) { return(a < b); } static char lt_sign [] = "<"; static Binary_Func LT = {lt, lt_sign}; //maximum of two values static Val maxV(Val a, Val b) { double r,g,B; r= (a.r > b.r)? a.r:b.r; g= (a.g > b.g)? a.g:b.g; B= (a.b > b.b)? a.b:b.b; return Val(r,g,B); } static char max_sign [] = "max"; static Binary_Func Max = {maxV, max_sign}; //minimum of two values static Val minV(Val a, Val b) { double r,g,B; r= (a.r < b.r)? a.r:b.r; g= (a.g < b.g)? a.g:b.g; B= (a.b < b.b)? a.b:b.b; return Val(r,g,B); } static char min_sign [] = "min"; static Binary_Func Min = {minV, min_sign}; //a to the power of b static Val pow(Val a, Val b) { return Val(pow(a.r,b.r) ,pow(a.g,b.g),pow(a.b,b.b)); } static char pow_sign [] = "pow"; static Binary_Func Pow = {pow, pow_sign}; // bit-wise and, produces fractal like images static Val and(Val a, Val b) { Val c; // we need to get to the underlying data // so convert to chars char* ar = (char *)&(a.r); char* br = (char *)&(b.r); char* cr = (char *)&(c.r); char* ag = (char *)&(a.g); char* bg = (char *)&(b.g); char* cg = (char *)&(c.g); char* ab = (char *)&(a.b); char* bb = (char *)&(b.b); char* cb = (char *)&(c.b); for(int i= 0; i< sizeof(a.r);i++) { *cr = (*ar & *br); *cg = (*ag & *bg); *cb = (*ab & *bb); ar++;br++;cr++; ag++;bg++;cg++; ab++;bb++;cb++; } return c; } static char and_sign [] = "&"; static Binary_Func And = {and, and_sign}; /* bit-wise or, produces fractal like images*/ static Val or(Val a, Val b) { Val c; // we need to get to the underlying data // so convert to chars char* ar = (char *)&(a.r); char* br = (char *)&(b.r); char* cr = (char *)&(c.r); char* ag = (char *)&(a.g); char* bg = (char *)&(b.g); char* cg = (char *)&(c.g); char* ab = (char *)&(a.b); char* bb = (char *)&(b.b); char* cb = (char *)&(c.b); for(int i= 0; i< sizeof(a.r);i++) { *cr = (*ar | *br); *cg = (*ag | *bg); *cb = (*ab | *bb); ar++;br++;cr++; ag++;bg++;cg++; ab++;bb++;cb++; } return c; } static char or_sign [] = "|"; static Binary_Func Or = {or, or_sign}; // bit wise exclusive or, produces fractal like images static Val xor(Val a, Val b) { Val c; // we need to get to the underlying data // so convert to chars char* ar = (char *)&(a.r); char* br = (char *)&(b.r); char* cr = (char *)&(c.r); char* ag = (char *)&(a.g); char* bg = (char *)&(b.g); char* cg = (char *)&(c.g); char* ab = (char *)&(a.b); char* bb = (char *)&(b.b); char* cb = (char *)&(c.b); for(int i= 0; i< sizeof(a.r);i++) { *cr = (*ar ^ *br); *cg = (*ag ^ *bg); *cb = (*ab ^ *bb); ar++;br++;cr++; ag++;bg++;cg++; ab++;bb++;cb++; } return c; } static char xor_sign [] = "^"; static Binary_Func Xor = {xor, xor_sign}; // absolute value function static Val abs(Val a) { double r,g,b; if(a.r < 0) r = -a.r; else r = a.r; if(a.r < 0) g = -a.b; else b = a.b; if(a.r < 0) b = -a.g; else g = a.g; return Val(r,g,b); } static char abs_sign[] = "ABS"; static Unary_Func Abs = {abs, abs_sign}; // sine function static Val sin(Val a) { a=a*PI; return Val(sin(a.r),sin(a.g),sin(a.b)); } static char sin_sign[] = "SIN"; static Unary_Func Sin = {sin, sin_sign}; // cosine function static Val cos(Val a) { a=a*PI; return Val(cos(a.r),cos(a.g),cos(a.b)); } static char cos_sign[] = "COS"; static Unary_Func Cos = {cos, cos_sign}; // tangent function static Val tan(Val a) { a=a*PI; return Val(tan(a.r),tan(a.g),tan(a.b)); } static char tan_sign[] = "TAN"; static Unary_Func Tan = {tan, tan_sign}; // negation operator static Val neg(Val a) { return -a; } static char neg_sign[] = "NEG"; static Unary_Func Neg = {neg, neg_sign}; // square root function static Val sqrt(Val a) { return Val(sqrt(a.r),sqrt(a.g),sqrt(a.b)); } static char sqrt_sign[] = "Sqrt"; static Unary_Func Sqrt = {sqrt, sqrt_sign}; // logarithm function static Val log(Val a) { return Val(log(a.r),log(a.g),log(a.b)); } static char log_sign[] = "Log"; static Unary_Func Log= {log, log_sign}; // atan function static Val atan(Val a) { return Val(atan(a.r),atan(a.g),atan(a.b)); } static char atan_sign[] = "ATAN"; static Unary_Func Atan = {atan, atan_sign}; // inverts color static Val invert(Val a) { return Val((-(a.r-.5))+.5,(-(a.g-.5))+.5,(-(a.b-.5))+.5); } static char invert_sign[] = "Invert"; static Unary_Func Invert = {invert, invert_sign}; // translates from Red-Green-Blue color space // to Hue-Saturation-Value space static Val rgb_to_hsv(Val a) { double max = a.maximum(); double min = a.minimum(); double h; double v = max; double s= (max != 0) ? ((max-min)/max):0.0; if(s == 0.00) h=0.00; else{ double delta = max-min; if(a.r == max) h = (a.g - a.b)/delta; else if(a.g == max) h = 2.00 + (a.b - a.r) /delta; else if (a.b == max) h = 4.00 + (a.r - a.g) / delta; h /= 6.00; } return Val(h,s,v); } static char rgb_to_hsv_sign[] = "RGB_to_HSV"; static Unary_Func RGB_to_HSV = {rgb_to_hsv, rgb_to_hsv_sign}; // translates from Hus-Saturation-Value color space // to Red-Green-Blue color space static Val hsv_to_rgb(Val a) { double r,g,b; if(a.g == 0.0){ r=a.b; g=a.b; b=a.b; } else{ double f,p,q,t; int i; if(a.r ==1.00) a.r = 0.0; a.r*=6.00; i = floor(a.r); i %=6; f = a.r - i; p = a.b * (1.0-a.g); q = a.b * (1.0 - (a.g*f)); t = a.b * (1.0 - (a.g * (1.0-f))); switch(i) { case 0: r=a.b; g=t; b=p; break; case 1: r=q; g=a.b; b=p; break; case 2: r=p; g=a.b; b=t; break; case 3: r=p; g=q; b=a.b; break; case 4: r=t; g=p; b=a.b; break; case 5: r=a.b; g=p; b=q; break; } } return Val(r,g,b); } static char hsv_to_rgb_sign[] = "HSV_to_RGB"; static Unary_Func HSV_to_RGB = {hsv_to_rgb, hsv_to_rgb_sign}; /* shifts RGB values around */ static Val shift_left(Val a) { return Val(a.g,a.b,a.r); } static char shift_left_sign[] = "Shift_Left"; static Unary_Func Shift_Left = {shift_left, shift_left_sign}; /* shifts them the other way */ static Val shift_right(Val a) { return Val(a.b,a.r,a.g); } static char shift_right_sign[] = "Shift_Right"; static Unary_Func Shift_Right = {shift_right, shift_right_sign}; /* bitwise not */ static Val not(Val a) { Val b; char* ar = (char *)&(a.r); char* br = (char *)&(b.r); char* ag = (char *)&(a.g); char* bg = (char *)&(b.g); char* ab = (char *)&(a.b); char* bb = (char *)&(b.b); for(int i= 0; i< sizeof(a.r);i++) { *br = (~(*ar) ); *bg = (~(*ag) ); *bb = (~(*ab) ); ar++;br++; ag++;bg++; ab++;bb++; } return b; } static char not_sign [] = "~"; static Unary_Func Not = {not, not_sign}; // array of variables to pass to initialize population */ static Variable *v_list[2] = {&X,&Y}; /* array of binary functions to initialize population with */ static Binary_Func* b_func_list[13] = {&Add, &Sub, &Mult, &Div, &Mod, >, <, &Max,&Min, &Pow,&And,&Or,&Xor}; /* array of unary functions to initialize population with */ static Unary_Func* u_func_list[14]= {&Abs,&Sin,&Cos,&Tan,&Neg,&Sqrt,&Log,&Atan,&Invert, &RGB_to_HSV,&HSV_to_RGB,&Shift_Left,&Shift_Right,&Not}; static int num_b_funcs = 13; static int num_u_funcs = 14; static int num_vs = 2;