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 ();
}
Exemple #2
0
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]);
}
Exemple #3
0
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;
}
Exemple #6
0
/* ---------------------------------
 * 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 */