static void map_click_callback (GtkWidget *w, GdkEventButton *event) { if (event->button == 1) { vector[selectedvector].x = event->x / (double)OMWIDTH; vector[selectedvector].y = event->y / (double)OMHEIGHT; } else if (event->button == 2) { if (num_vectors + 1 == MAXORIENTVECT) return; add_new_vector (event->x / (double)OMWIDTH, event->y / (double)OMHEIGHT); update_slides (); } else if (event->button == 3) { gdouble d; d = atan2 (OMWIDTH * vector[selectedvector].x - event->x, OMHEIGHT * vector[selectedvector].y - event->y); vector[selectedvector].dir = gimp_rad_to_deg (d); vector[selectedvector].dx = sin (d); vector[selectedvector].dy = cos (d); update_slides (); } update_vector_prev (); update_orient_map_preview_prev (); }
static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformTool *tr_tool) { return g_strdup_printf (C_("undo-type", "Rotate by %-3.3g° around (%g, %g)"), gimp_rad_to_deg (tr_tool->trans_info[ANGLE]), tr_tool->trans_info[PIVOT_X], tr_tool->trans_info[PIVOT_Y]); }
static void gimp_rotate_tool_dialog_update (GimpTransformTool *tr_tool) { GimpRotateTool *rotate = GIMP_ROTATE_TOOL (tr_tool); gtk_adjustment_set_value (rotate->angle_adj, gimp_rad_to_deg (tr_tool->trans_info[ANGLE])); g_signal_handlers_block_by_func (rotate->sizeentry, rotate_center_changed, tr_tool); gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 0, tr_tool->trans_info[PIVOT_X]); gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (rotate->sizeentry), 1, tr_tool->trans_info[PIVOT_Y]); g_signal_handlers_unblock_by_func (rotate->sizeentry, rotate_center_changed, tr_tool); }
double get_direction (double x, double y, int from) { gint i; gint n; gint voronoi; gdouble sum, dx, dy, dst; vector_t *vec; gdouble angoff, strexp; gint first = 0, last; if (from == 0) { n = num_vectors; vec = vector; angoff = gtk_adjustment_get_value (GTK_ADJUSTMENT (angle_offset_adjust)); strexp = gtk_adjustment_get_value (GTK_ADJUSTMENT (orient_map_str_exp_adjust)); voronoi = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (orient_voronoi)); } else { n = pcvals.num_orient_vectors; vec = pcvals.orient_vectors; angoff = pcvals.orient_angle_offset; strexp = pcvals.orient_strength_exponent; voronoi = pcvals.orient_voronoi; } if (voronoi) { gdouble bestdist = -1.0; for (i = 0; i < n; i++) { dst = dist (x,y,vec[i].x,vec[i].y); if ((bestdist < 0.0) || (dst < bestdist)) { bestdist = dst; first = i; } } last = first+1; } else { first = 0; last = n; } dx = dy = 0.0; sum = 0.0; for (i = first; i < last; i++) { gdouble s = vec[i].str; gdouble tx = 0.0, ty = 0.0; if (vec[i].type == 0) { tx = vec[i].dx; ty = vec[i].dy; } else if (vec[i].type == 1) { gdouble a = atan2 (vec[i].dy, vec[i].dx); a -= atan2 (y-vec[i].y, x-vec[i].x); tx = sin (a + G_PI_2); ty = cos (a + G_PI_2); } else if (vec[i].type == 2) { gdouble a = atan2 (vec[i].dy, vec[i].dx); a += atan2 (y-vec[i].y, x-vec[i].x); tx = sin (a + G_PI_2); ty = cos (a + G_PI_2); } else if (vec[i].type == 3) { gdouble a = atan2 (vec[i].dy, vec[i].dx); a -= atan2 (y-vec[i].y, x-vec[i].x)*2; tx = sin (a + G_PI_2); ty = cos (a + G_PI_2); } dst = dist (x,y,vec[i].x,vec[i].y); dst = pow (dst, strexp); if (dst < 0.0001) dst = 0.0001; s = s / dst; dx += tx * s; dy += ty * s; sum += s; } dx = dx / sum; dy = dy / sum; return 90 - (gimp_rad_to_deg (atan2 (dy, dx)) + angoff); }
/** * gimp_display_shell_get_line_status: * @status: initial status text. * @separator: separator text between the line information and @status. * @shell: #GimpDisplayShell this status text will be displayed for. * @x1: abscissa of first point. * @y1: ordinate of first point. * @x2: abscissa of second point. * @y2: ordinate of second point. * * Utility function to prepend the status message with a distance and * angle value. Obviously this is only to be used for tools when it * makes sense, and in particular when there is a concept of line. For * instance when shift-clicking a painting tool or in the blend tool, * etc. * This utility prevents code duplication but also ensures a common * display for every tool where such a status is needed. It will take * into account the shell unit settings and will use the ideal digit * precision according to current image resolution. * * Return value: a newly allocated string containing the enhanced status. **/ gchar * gimp_display_shell_get_line_status (GimpDisplayShell *shell, const gchar *status, const gchar *separator, gdouble x1, gdouble y1, gdouble x2, gdouble y2) { GimpImage *image; gchar *enhanced_status; gdouble xres; gdouble yres; gdouble dx, dy, pixel_dist; gdouble angle; image = gimp_display_get_image (shell->display); if (! image) { /* This makes no sense to add line information when no image is * attached to the display. */ return g_strdup (status); } if (shell->unit == GIMP_UNIT_PIXEL) xres = yres = 1.0; else gimp_image_get_resolution (image, &xres, &yres); dx = x2 - x1; dy = y2 - y1; pixel_dist = sqrt (SQR (dx) + SQR (dy)); if (dx) { angle = gimp_rad_to_deg (atan ((dy/yres) / (dx/xres))); if (dx > 0) { if (dy > 0) angle = 360.0 - angle; else if (dy < 0) angle = -angle; } else { angle = 180.0 - angle; } } else if (dy) { angle = dy > 0 ? 270.0 : 90.0; } else { angle = 0.0; } if (shell->unit == GIMP_UNIT_PIXEL) { enhanced_status = g_strdup_printf ("%.1f %s, %.2f\302\260%s%s", pixel_dist, _("pixels"), angle, separator, status); } else { gdouble inch_dist; gdouble unit_dist; gint digits = 0; /* The distance in unit. */ inch_dist = sqrt (SQR (dx / xres) + SQR (dy / yres)); unit_dist = gimp_unit_get_factor (shell->unit) * inch_dist; /* The ideal digit precision for unit in current resolution. */ if (inch_dist) digits = gimp_unit_get_scaled_digits (shell->unit, pixel_dist / inch_dist); enhanced_status = g_strdup_printf ("%.*f %s, %.2f\302\260%s%s", digits, unit_dist, gimp_unit_get_symbol (shell->unit), angle, separator, status); } return enhanced_status; }
/* --------------------------------- * gap_colordiff_LabDeltaE2000 * --------------------------------- * uses algortihm found at http://colormine.org/delta-e-calculator/cie2000 * based on L*a*b Colorspace. * returns deltaE scaled down to a range of 0.0 to 1.0 */ gdouble gap_colordiff_LabDeltaE2000(guchar *aPixelPtr , guchar *bPixelPtr , gboolean debugPrint ) { //Set weighting factors to 1 gdouble k_L = 1.0; gdouble k_C = 1.0; gdouble k_H = 1.0; GapColorLAB lab1; GapColorLAB lab2; //Change Color Space to L*a*b: p_convert_rgb8_to_Lab(aPixelPtr, &lab1); p_convert_rgb8_to_Lab(bPixelPtr, &lab2); //Calculate Cprime1, Cprime2, Cabbar gdouble c_star_1_ab = sqrt(lab1.A * lab1.A + lab1.B * lab1.B); gdouble c_star_2_ab = sqrt(lab2.A * lab2.A + lab2.B * lab2.B); gdouble c_star_average_ab = (c_star_1_ab + c_star_2_ab) / 2; gdouble c_star_average_ab_pot7 = c_star_average_ab * c_star_average_ab * c_star_average_ab; c_star_average_ab_pot7 *= c_star_average_ab_pot7 * c_star_average_ab; gdouble G = 0.5 * (1 - sqrt(c_star_average_ab_pot7 / (c_star_average_ab_pot7 + 6103515625))); //25^7 gdouble a1_prime = (1 + G) * lab1.A; gdouble a2_prime = (1 + G) * lab2.A; gdouble C_prime_1 = sqrt(a1_prime * a1_prime + lab1.B * lab1.B); gdouble C_prime_2 = sqrt(a2_prime * a2_prime + lab2.B * lab2.B); //Angles in Degree. gdouble h_prime_1 = (int)rint(gimp_rad_to_deg(atan2(lab1.B, a1_prime)) + 360) % 360; gdouble h_prime_2 = (int)rint(gimp_rad_to_deg(atan2(lab2.B, a2_prime)) + 360) % 360; gdouble delta_L_prime = lab2.L - lab1.L; gdouble delta_C_prime = C_prime_2 - C_prime_1; gdouble h_bar = abs(h_prime_1 - h_prime_2); gdouble delta_h_prime; if (C_prime_1 * C_prime_2 == 0) delta_h_prime = 0; else { if (h_bar <= 180.0) { delta_h_prime = h_prime_2 - h_prime_1; } else if (h_bar > 180.0 && h_prime_2 <= h_prime_1) { delta_h_prime = h_prime_2 - h_prime_1 + 360.0; } else { delta_h_prime = h_prime_2 - h_prime_1 - 360.0; } } gdouble delta_H_prime = 2 * sqrt(C_prime_1 * C_prime_2) * sin(gimp_deg_to_rad(delta_h_prime / 2)); // Calculate CIEDE2000 gdouble L_prime_average = (lab1.L + lab2.L) / 2.0; gdouble C_prime_average = (C_prime_1 + C_prime_2) / 2.0; //Calculate h_prime_average gdouble h_prime_average; if (C_prime_1 * C_prime_2 == 0) h_prime_average = 0; else { if (h_bar <= 180.0) { h_prime_average = (h_prime_1 + h_prime_2) / 2; } else if (h_bar > 180.0 && (h_prime_1 + h_prime_2) < 360.0) { h_prime_average = (h_prime_1 + h_prime_2 + 360.0) / 2; } else { h_prime_average = (h_prime_1 + h_prime_2 - 360.0) / 2; } } gdouble L_prime_average_minus_50_square = (L_prime_average - 50); L_prime_average_minus_50_square *= L_prime_average_minus_50_square; gdouble S_L = 1 + ((.015d * L_prime_average_minus_50_square) / sqrt(20 + L_prime_average_minus_50_square)); gdouble S_C = 1 + .045d * C_prime_average; gdouble T = 1 - .17 * cos(gimp_deg_to_rad(h_prime_average - 30)) + .24 * cos(gimp_deg_to_rad(h_prime_average * 2)) + .32 * cos(gimp_deg_to_rad(h_prime_average * 3 + 6)) - .2 * cos(gimp_deg_to_rad(h_prime_average * 4 - 63)); gdouble S_H = 1 + .015 * T * C_prime_average; gdouble h_prime_average_minus_275_div_25_square = (h_prime_average - 275) / (25); h_prime_average_minus_275_div_25_square *= h_prime_average_minus_275_div_25_square; gdouble delta_theta = 30 * exp(-h_prime_average_minus_275_div_25_square); gdouble C_prime_average_pot_7 = C_prime_average * C_prime_average * C_prime_average; C_prime_average_pot_7 *= C_prime_average_pot_7 * C_prime_average; gdouble R_C = 2 * sqrt(C_prime_average_pot_7 / (C_prime_average_pot_7 + 6103515625)); gdouble R_T = -sin(gimp_deg_to_rad(2 * delta_theta)) * R_C; gdouble delta_L_prime_div_k_L_S_L = delta_L_prime / (S_L * k_L); gdouble delta_C_prime_div_k_C_S_C = delta_C_prime / (S_C * k_C); gdouble delta_H_prime_div_k_H_S_H = delta_H_prime / (S_H * k_H); gdouble CIEDE2000 = sqrt( delta_L_prime_div_k_L_S_L * delta_L_prime_div_k_L_S_L + delta_C_prime_div_k_C_S_C * delta_C_prime_div_k_C_S_C + delta_H_prime_div_k_H_S_H * delta_H_prime_div_k_H_S_H + R_T * delta_C_prime_div_k_C_S_C * delta_H_prime_div_k_H_S_H ); gdouble colorDiff = CIEDE2000 / 100.0; /* normalize range [from 0.0 to 100.0] ==> [from 0.0 to 1.0] */ if(debugPrint) { printf("L*a*b (%.3f, %.3f, %.3f) rgb 1/2 (%03d %03d %03d) / (%03d %03d %03d) CIEDE2000:%f colorDiff:%f\n" , lab1.L , lab1.A , lab1.B , (int)(aPixelPtr[0]) , (int)(aPixelPtr[1]) , (int)(aPixelPtr[2]) , (int)(bPixelPtr[0]) , (int)(bPixelPtr[1]) , (int)(bPixelPtr[2]) , CIEDE2000 , colorDiff ); } return (colorDiff); } /* end gap_colordiff_LabDeltaE2000 */