GTKextra extention



Hi,
I have tryed to add a new class to GTKextra :
I would like to have a polar class with a specials symbol. This
symbol is a polygone with the four points define like this :
  ptx1 = (x - dx) * cos (y-dy); 
  pty1 = (x - dx) * sin (y-dy);
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[0].x), (gint *)&(point[0].y));
  ptx2 = (x + dx) * cos (y-dy); 
  pty2 = (x + dx) * sin (y-dy);
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[1].x), (gint *)&(point[1].y));
  ptx3 = (x - dx) * cos (y+dy); 
  pty3 = (x - dx) * cos (y+dy); 
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[2].x),(gint *) &(point[2].y));
  ptx4 = (x + dx) * cos (y+dy); 
  pty4 = (x + dx) * cos (y+dy); 
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[3].x), (gint *)&(point[3].y));
To do this, I have made the worst thing , copy paste the gtkplotpolar files and
added my privite_draw_symbol routines
But when I run it I've got a
Program received signal SIGSEGV, Segmentation fault.
0x401110e1 in gtk_type_check_object_cast () from /usr/lib/libgtk-1.2.so.0
If someone could help me to go through ....


Fred cazenave
-- 
 _________________________________________________________
|                                                          |
|               Frederic CAZENAVE                          |
|    _/\_  /^=  McGill Radar                               |
| \_/    \//    Box 198, MacDonald College                 |
|   | /-\ |     Ste Anne de Bellevue                       |
|   ||   ||     Quebec, Canada   H9X 3V9                   |
|               Tel (514) 398 7733 fax (514) 398 7755      |
|               mailto:Frederic Cazenave hmg inpg fr       |
|               http://www.mpl.orstom.fr/hydrologie/catch/ |
|__________________________________________________________|
 
/* gtkplotpolar - polar plots widget for gtk+
 * Copyright 1999-2001  Adrian E. Feiguin <feiguin ifir edu ar>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
#include "gtkplot.h"
#include "gtkplotdata.h"
#include "gtkplotpolarsurf.h"
#include "gtkpsfont.h"
#include "gtkplotpc.h"

#ifndef PIP
#define PI 3.14159265358979323846
#endif

static void gtk_plot_polar_surface_class_init           (GtkPlotPolarSurfaceClass *klass);
static void gtk_plot_polar_surface_init                 (GtkPlotPolarSurface *plot);
static void gtk_plot_polar_surface_draw                 (GtkWidget *widget, 
                                                         GdkRectangle *area);
static void gtk_plot_polar_surface_real_paint           (GtkWidget *widget);
static void gtk_plot_calc_ticks                 (GtkPlotPolarSurface *plot, 
                                                 GtkPlotAxis *axis);
static void gtk_plot_polar_surface_draw_grids           (GtkPlotPolarSurface *plot); 
static void gtk_plot_polar_surface_draw_axis            (GtkPlotPolarSurface *plot, 
                                                         GtkPlotAxis *axis,
                                                         GtkPlotVector tick_direction);
static void gtk_plot_polar_surface_draw_circle          (GtkPlotPolarSurface *polar);
static void gtk_plot_polar_surface_draw_labels          (GtkPlotPolarSurface *plot, 
                                                         GtkPlotAxis *axis, 
                                                         GtkPlotVector tick_direction );
static void gtk_plot_polar_surface_real_get_pixel       (GtkWidget *widget, 
                                                         gdouble x, 
                                                         gdouble y, 
                                                         gint *px,
                                                         gint *py); 
static void 
gtk_plot_polar_surface_real_get_point   (GtkWidget *widget, 
                                         gint px,
                                         gint py,
                                         gdouble *x, 
                                         gdouble *y); 
static void
gtk_plot_data_draw_gate (GtkPlotData *data,  
                         gdouble x, gdouble y, gdouble z, gdouble a,
                         gdouble dx, gdouble dy, gdouble dz, gdouble da,
                         gint filled);

static gint roundint                            (gdouble x);
static void parse_label                         (gdouble val, 
                                                 gint precision, 
                                                 gint style,
                                                 gchar *label);
static gint transform                           (GtkPlot *plot, gdouble x);
static void 
gtk_plot_data_real_draw_symbol (GtkPlotData *data, 
                                gdouble x, gdouble y, gdouble z, gdouble a,
                                gdouble dx, gdouble dy, gdouble dz, gdouble da);
static void
gtk_plot_data_draw_symbol_private (GtkPlotData *data, 
                                   gdouble x, gdouble y, gdouble z, gdouble a,
                                   gdouble dx, gdouble dy, gdouble dz, gdouble da,
                                   GtkPlotSymbol symbol);

static GtkPlotClass *parent_class = NULL;


GtkType
gtk_plot_polar_surface_get_type (void)
{
  static GtkType plot_type = 0;

  if (!plot_type)
    {
      GtkTypeInfo plot_info =
      {
        "GtkPlotPolarSurface",
        sizeof (GtkPlotPolarSurface),
        sizeof (GtkPlotPolarSurfaceClass),
        (GtkClassInitFunc) gtk_plot_polar_surface_class_init,
        (GtkObjectInitFunc) gtk_plot_polar_surface_init,
        /* reserved 1*/ NULL,
        /* reserved 2 */ NULL,
        (GtkClassInitFunc) NULL,
      };

      plot_type = gtk_type_unique (gtk_plot_get_type(), &plot_info);
    }
  return plot_type;
}

static void
gtk_plot_polar_surface_class_init (GtkPlotPolarSurfaceClass *klass)
{
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkPlotClass *plot_class;
  GtkPlotDataClass *data_class;

  parent_class = gtk_type_class (gtk_plot_polar_surface_get_type ());

  object_class = (GtkObjectClass *) klass;
  widget_class = (GtkWidgetClass *) klass;
  plot_class = (GtkPlotClass *) klass;
  data_class = (GtkPlotDataClass *) klass;
 
  widget_class->draw = gtk_plot_polar_surface_draw;

  plot_class->plot_paint = gtk_plot_polar_surface_real_paint;
  data_class->draw_symbol = gtk_plot_data_real_draw_symbol;
  plot_class->get_point = gtk_plot_polar_surface_real_get_point;
  plot_class->get_pixel = gtk_plot_polar_surface_real_get_pixel;
}


static void
gtk_plot_polar_surface_init (GtkPlotPolarSurface *plot)
{
 
  GTK_PLOT(plot)->legends_attr.transparent = FALSE;

  GTK_PLOT(plot)->xmin = 0;
  GTK_PLOT(plot)->xmax = 360;

  plot->r = GTK_PLOT(plot)->left;
  plot->angle = GTK_PLOT(plot)->bottom;

  GTK_PLOT(plot)->bottom->min = 0.0;
  GTK_PLOT(plot)->bottom->max = 360.0;
  GTK_PLOT(plot)->bottom->ticks.step = 30.;
  GTK_PLOT(plot)->top->min = 0.0;
  GTK_PLOT(plot)->top->max = 360.0;
  GTK_PLOT(plot)->top->ticks.step = 30.;

  GTK_PLOT(plot)->bottom->labels_offset = 15.;
  GTK_PLOT(plot)->bottom->label_precision = 0;

  GTK_PLOT(plot)->ymin = 0.2;
  GTK_PLOT(plot)->left->min = 0.2;
  GTK_PLOT(plot)->left->ticks.step = 0.2;
  GTK_PLOT(plot)->right->min = 0.2;
  GTK_PLOT(plot)->right->ticks.step = 0.2;

  GTK_PLOT(plot)->left->title.angle = 0.;

  gtk_plot_axis_set_title(GTK_PLOT(plot), GTK_PLOT_AXIS_LEFT, "R");

  GTK_PLOT(plot)->top->is_visible = FALSE;

  GTK_PLOT(plot)->bottom->show_major_grid = TRUE;
  GTK_PLOT(plot)->bottom->show_minor_grid = TRUE;
  GTK_PLOT(plot)->left->show_major_grid = TRUE;
  GTK_PLOT(plot)->left->show_minor_grid = TRUE;

  plot->rotation = 0.0;
}

static void
gtk_plot_polar_surface_draw (GtkWidget *widget, GdkRectangle *area)
{
  gtk_plot_paint(GTK_PLOT(widget));
  gtk_plot_refresh (GTK_PLOT(widget), area);
}

static void
gtk_plot_polar_surface_real_paint (GtkWidget *widget)
{
  GtkPlot *plot;
  GtkPlotText *child_text;
  GtkStyle *style;
  GdkPixmap *pixmap;
  GList *dataset;
  GList *text;
  GdkRectangle area;
  gint width, height;
  gint xoffset, yoffset ;
  gdouble min;

  plot = GTK_PLOT(widget);
  if(!GTK_WIDGET_DRAWABLE(plot)) return;

  if(!plot->drawable) return;

  area.x = widget->allocation.x;
  area.y = widget->allocation.y;
  area.width = widget->allocation.width;
  area.height = widget->allocation.height;
  xoffset = area.x + roundint(plot->x * widget->allocation.width);
  yoffset = area.y + roundint(plot->y * widget->allocation.height);
  width = roundint(plot->width * widget->allocation.width);
  height = roundint(plot->height * widget->allocation.height);

  style = gtk_widget_get_style(widget);

  pixmap = plot->drawable;

  gtk_plot_pc_gsave(plot->pc);
  gtk_plot_pc_set_color(plot->pc, &plot->background);

  if(!GTK_PLOT_TRANSPARENT(plot))
    gtk_plot_pc_draw_rectangle (plot->pc, TRUE,
                               xoffset, yoffset,
                               width , height);

  /* draw frame to guide the eyes*/
/*  gdk_draw_rectangle (pixmap, gc, FALSE,
                      xoffset, yoffset,
                      width , height);
*/

  /* draw the ticks & grid lines */

  min = plot->left->min;
  plot->left->min = 0.0;
  gtk_plot_calc_ticks(GTK_PLOT_POLAR_SURFACE(plot), plot->left);
  gtk_plot_calc_ticks(GTK_PLOT_POLAR_SURFACE(plot), plot->bottom);

  if(plot->left->is_visible)
    {
      GtkPlotVector tick_direction;

      tick_direction.x = 1.;
      tick_direction.y = 0.;
      plot->left->origin.x = (gfloat)width*plot->left_align;
      plot->left->origin.y = height;
      gtk_plot_polar_surface_draw_axis(GTK_PLOT_POLAR_SURFACE(plot), plot->left, tick_direction);
      gtk_plot_polar_surface_draw_labels(GTK_PLOT_POLAR_SURFACE(plot), plot->left, tick_direction);
    }


  if(plot->top->is_visible)
    {
      GtkPlotVector tick_direction;

      tick_direction.x = 0.;
      tick_direction.y = 1.;
      plot->left->direction.x = 1;
      plot->left->direction.y = 0;
      plot->left->origin.x = 0;
      plot->left->origin.y = (gfloat)height*plot->left_align;
      gtk_plot_polar_surface_draw_axis(GTK_PLOT_POLAR_SURFACE(plot), plot->left, tick_direction);
      gtk_plot_polar_surface_draw_labels(GTK_PLOT_POLAR_SURFACE(plot), plot->left, tick_direction);
      plot->left->direction.x = 0;
      plot->left->direction.y = -1;
    }

  if(plot->bottom->is_visible)
    {
      gtk_plot_polar_surface_draw_circle(GTK_PLOT_POLAR_SURFACE(plot));
    }

  plot->left->min = min;
  gtk_plot_calc_ticks(GTK_PLOT_POLAR_SURFACE(plot), plot->left);
  gtk_plot_polar_surface_draw_grids(GTK_PLOT_POLAR_SURFACE(plot));

  dataset = plot->data_sets;
   while(dataset)
     {
       GTK_PLOT_DATA_CLASS(GTK_OBJECT(dataset->data)->klass)->draw_data(GTK_PLOT_DATA(dataset->data));
       dataset = dataset->next;
     }

  text = plot->text;
  while(text)
   {
     child_text = (GtkPlotText *) text->data;
     gtk_plot_draw_text(plot, *child_text);
     text = text->next;
   }

  GTK_PLOT_CLASS(GTK_OBJECT(plot)->klass)->draw_legends(widget);;

  gtk_plot_pc_grestore(plot->pc);
}

static void
gtk_plot_data_real_draw_symbol (GtkPlotData *data, 
                                gdouble x, gdouble y, gdouble z, gdouble a,
                                gdouble dx, gdouble dy, gdouble dz, gdouble da)
{
  GtkPlot *plot;
  GtkPlotSymbol aux_symbol;

  plot = data->plot;

  aux_symbol = data->symbol;
  //aux_symbol.color = plot->background;
  aux_symbol.symbol_style = GTK_PLOT_SYMBOL_FILLED;
  aux_symbol.border.line_width = 0;

  if(data->symbol.symbol_style == GTK_PLOT_SYMBOL_OPAQUE)
     gtk_plot_data_draw_symbol_private (data, x, y, z, a, dx, dy, dz, da, aux_symbol); 

  if(data->symbol.symbol_style == GTK_PLOT_SYMBOL_FILLED){
     aux_symbol.color = data->symbol.color; 
     gtk_plot_data_draw_symbol_private (data, x, y, z, a, dx, dy, dz, da, aux_symbol);
  }

  aux_symbol = data->symbol;
  aux_symbol.color = data->symbol.border.color; 
  aux_symbol.symbol_style = GTK_PLOT_SYMBOL_EMPTY;
  gtk_plot_data_draw_symbol_private (data, x, y, z, a, dx, dy, dz, da, aux_symbol);
}

static void
gtk_plot_data_draw_symbol_private (GtkPlotData *data, 
                                   gdouble x, gdouble y, gdouble z, gdouble a,
                                   gdouble dx, gdouble dy, gdouble dz, gdouble da,
                                   GtkPlotSymbol symbol)
{
  GtkWidget *widget;
  GtkPlot *plot;
  GdkRectangle area, clip_area;
  gboolean filled;
  gint size;

  plot = data->plot;
  widget = GTK_WIDGET(plot);

  area.x = GTK_WIDGET(plot)->allocation.x;
  area.y = GTK_WIDGET(plot)->allocation.y;
  area.width = GTK_WIDGET(plot)->allocation.width;
  area.height = GTK_WIDGET(plot)->allocation.height;

  clip_area.x = area.x + roundint(plot->x * area.width);
  clip_area.y = area.y + roundint(plot->y * area.height);
  clip_area.width = roundint(plot->width * area.width);
  clip_area.height = roundint(plot->height * area.height);

/*
  gdk_gc_set_clip_rectangle(gc, &clip_area);
*/

  gtk_plot_pc_set_color(plot->pc, &symbol.color);
  gtk_plot_pc_set_lineattr (plot->pc, symbol.border.line_width, 0, 0, 0);
  filled = (symbol.symbol_style == GTK_PLOT_SYMBOL_FILLED) ? TRUE : FALSE;
  size = symbol.size;

  gtk_plot_data_draw_gate (data,x, y, z, a, dx, dy, dz, da, filled);

}
static void
gtk_plot_data_draw_gate (GtkPlotData *data,  
                         gdouble x, gdouble y, gdouble z, gdouble a,
                         gdouble dx, gdouble dy, gdouble dz, gdouble da,
                         gint filled)
{
  GtkPlot *plot;
  GdkPoint point[4];
  gdouble ptx,pty;
  gdouble m;

  plot = data->plot;
  m = plot->magnification;
  

  ptx = (x - dx) * cos (y-dy); 
  pty = (x - dx) * sin (y-dy);
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[0].x), (gint *)&(point[0].y));
  ptx = (x + dx) * cos (y-dy); 
  pty = (x + dx) * sin (y-dy);
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[1].x), (gint *)&(point[1].y));
  ptx = (x - dx) * cos (y+dy); 
  pty = (x - dx) * cos (y+dy); 
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[2].x),(gint *) &(point[2].y));
  ptx = (x + dx) * cos (y+dy); 
  pty = (x + dx) * cos (y+dy); 
  gtk_plot_get_pixel(plot, ptx, pty, (gint *)&(point[3].x), (gint *)&(point[3].y));

  gtk_plot_pc_draw_polygon (plot->pc,
                           filled,
                           point,
                           4);   
}
GtkWidget*
gtk_plot_polar_surface_new (GdkDrawable *drawable)
{
  GtkPlotPolarSurface *plot;

  plot = gtk_type_new (gtk_plot_polar_surface_get_type ());

  gtk_plot_polar_surface_construct(GTK_PLOT_POLAR_SURFACE(plot), drawable);

  return GTK_WIDGET (plot);
}

GtkWidget*
gtk_plot_polar_surface_new_with_size (GdkDrawable *drawable, gdouble width, gdouble height)
{
  GtkWidget *plot; 

  plot = gtk_type_new (gtk_plot_polar_surface_get_type ());

  gtk_plot_polar_surface_construct_with_size(GTK_PLOT_POLAR_SURFACE(plot), drawable,
                                     width, height);

  return(plot);
}

void
gtk_plot_polar_surface_construct(GtkPlotPolarSurface *plot, GdkDrawable *drawable)
{
  GTK_PLOT(plot)->drawable = drawable;
}

void
gtk_plot_polar_surface_construct_with_size(GtkPlotPolarSurface *plot, GdkDrawable *drawable, gdouble width, 
gdouble height)
{
  GTK_PLOT(plot)->drawable = drawable;
  gtk_plot_resize (GTK_PLOT(plot), width, height);
}

static void
gtk_plot_polar_surface_draw_grids(GtkPlotPolarSurface *polar)
{
  GtkWidget *widget;
  GtkPlot *plot;
  gint ix, iy;
  gint x1, y1, x2, y2;
  gint width, height, size;
  gint xp, yp;
  gint ntick;
  gint ox, oy;
  gdouble rotation;

  widget = GTK_WIDGET(polar);
  plot = GTK_PLOT(polar);

  rotation = polar->rotation;

  xp = roundint(plot->x * (gdouble)widget->allocation.width);
  yp = roundint(plot->y * (gdouble)widget->allocation.height);
  width = roundint(plot->width * (gdouble)widget->allocation.width);
  height = roundint(plot->height * (gdouble)widget->allocation.height);

  ox = xp + width / 2;
  oy = yp + height / 2;
  size = MIN(width, height) / 2;

  if(plot->bottom->show_minor_grid)
    {
          for(ntick = 0; ntick < plot->bottom->ticks.nminorticks; ntick++){
            if(plot->bottom->ticks.minor_values[ntick] >= plot->bottom->min){
              gtk_plot_get_pixel(plot,
                                 plot->ymax,
                                 plot->bottom->ticks.minor_values[ntick],
                                 &x1, &y1);
              gtk_plot_get_pixel(plot,
                                 plot->ymin,
                                 plot->bottom->ticks.minor_values[ntick],
                                 &x2, &y2);
              gtk_plot_draw_line(plot, plot->bottom->minor_grid,
                                 x1, y1, x2, y2);
            }
          }
    }
  if(plot->bottom->show_major_grid)
    {
          for(ntick = 0; ntick < plot->bottom->ticks.nmajorticks; ntick++){
           if(plot->bottom->ticks.major_values[ntick] >= plot->bottom->min){
              gtk_plot_get_pixel(plot,
                                 plot->ymax,
                                 plot->bottom->ticks.major_values[ntick],
                                 &x1, &y1);
              gtk_plot_get_pixel(plot,
                                 plot->ymin,
                                 plot->bottom->ticks.major_values[ntick],
                                 &x2, &y2);
              gtk_plot_draw_line(plot, plot->bottom->major_grid,
                                 x1, y1, x2, y2);
           }
          }
    }
  if(plot->left->show_minor_grid)
    {
          gtk_plot_set_line_attributes(plot, plot->left->minor_grid); 
          for(ntick = 0; ntick < plot->left->ticks.nminorticks; ntick++){
            if(plot->left->ticks.minor_values[ntick] >= plot->left->min){
              gtk_plot_get_pixel(plot,
                                 plot->left->ticks.minor_values[ntick],
                                 90.0 - rotation,
                                 &ix, &iy);
              iy = abs(oy - iy);
              gtk_plot_pc_draw_circle (plot->pc,
                                      FALSE,
                                      ox, oy,
                                      2 * iy);
            }
          }
    }
  if(plot->left->show_major_grid)

    {
          gtk_plot_set_line_attributes(plot, plot->left->major_grid); 
          for(ntick = 0; ntick < plot->left->ticks.nmajorticks; ntick++){
            if(plot->left->ticks.major_values[ntick] >= plot->left->min){
              gtk_plot_get_pixel(plot,
                                 plot->left->ticks.major_values[ntick],
                                 90.0 - rotation,
                                 &ix, &iy);
              iy = abs(oy - iy);
              gtk_plot_pc_draw_circle (plot->pc,
                                      FALSE,
                                      ox, oy,
                                      2 * iy);
            }
          }
    }

}

static void
gtk_plot_polar_surface_draw_axis(GtkPlotPolarSurface *polar, 
                         GtkPlotAxis *axis, GtkPlotVector tick_direction)
{
  GtkWidget *widget;
  GtkPlot *plot;
  gint x, y;
  gint xx;
  gint line_width;
  gint xp, yp, width, height, size;
  gint ntick;
  gdouble m;
  gint x1, y1;
  gint ox, oy;

  widget = GTK_WIDGET(polar);
  plot = GTK_PLOT(polar);

  m = plot->magnification;

  xp = roundint(plot->x * (gdouble)widget->allocation.width);
  yp = roundint(plot->y * (gdouble)widget->allocation.height);
  width = roundint(plot->width * (gdouble)widget->allocation.width);
  height = roundint(plot->height * (gdouble)widget->allocation.height);

  size = MIN(width, height);

  ox = width / 2.;
  oy = height / 2.;

  x = xp + ox * axis->direction.x + axis->origin.x;
  y = yp + oy * axis->direction.y + axis->origin.y;

  line_width = axis->line.line_width;
  gtk_plot_pc_set_color(plot->pc, &axis->line.color);

  gtk_plot_pc_set_lineattr(plot->pc, axis->line.line_width, 0, 3, 0);
  gtk_plot_pc_draw_line(plot->pc,
                x - size / 2 * axis->direction.x,
                y - size / 2 * axis->direction.y,
                x + axis->direction.x * size / 2,
                y + axis->direction.y * size / 2);
  gtk_plot_pc_set_lineattr(plot->pc, axis->ticks_width, 0, 1, 0);

  for(ntick = 0; ntick < axis->ticks.nmajorticks; ntick++){
    xx = axis->ticks.major[ntick];
    if(axis->ticks.major_values[ntick] >= axis->min){
      if(axis->major_mask & GTK_PLOT_TICKS_IN){
         x1 = x + xx * axis->direction.x;
         y1 = y + xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x * roundint(m*axis->ticks_length),
                       y1 + tick_direction.y * roundint(m*axis->ticks_length));
         x1 = x - xx * axis->direction.x;
         y1 = y - xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x * roundint(m*axis->ticks_length),
                       y1 + tick_direction.y * roundint(m*axis->ticks_length));
      }
      if(axis->major_mask & GTK_PLOT_TICKS_OUT){
         x1 = x + xx * axis->direction.x;
         y1 = y + xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x * roundint(m*axis->ticks_length),
                       y1 - tick_direction.y * roundint(m*axis->ticks_length));
         x1 = x - xx * axis->direction.x;
         y1 = y - xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x * roundint(m*axis->ticks_length),
                       y1 - tick_direction.y * roundint(m*axis->ticks_length));
      }
    }
  }    
  for(ntick = 0; ntick < axis->ticks.nminorticks; ntick++){
    xx = axis->ticks.minor[ntick];
    if(axis->ticks.minor_values[ntick] >= axis->min){
      if(axis->minor_mask & GTK_PLOT_TICKS_IN){
         x1 = x + xx * axis->direction.x;
         y1 = y + xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x*roundint(m*axis->ticks_length)/2,
                       y1 + tick_direction.y*roundint(m*axis->ticks_length)/2);
         x1 = x - xx * axis->direction.x;
         y1 = y - xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x*roundint(m*axis->ticks_length)/2,
                       y1 + tick_direction.y*roundint(m*axis->ticks_length)/2);
      }
      if(axis->minor_mask & GTK_PLOT_TICKS_OUT){
         x1 = x + xx * axis->direction.x;
         y1 = y + xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x*roundint(m*axis->ticks_length)/2,
                       y1 - tick_direction.y*roundint(m*axis->ticks_length)/2);
         x1 = x - xx * axis->direction.x;
         y1 = y - xx * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x*roundint(m*axis->ticks_length)/2,
                       y1 - tick_direction.y*roundint(m*axis->ticks_length)/2);
      }
    }
  }    

}


static void
gtk_plot_polar_surface_draw_labels(GtkPlotPolarSurface *polar, 
                           GtkPlotAxis *axis,
                           GtkPlotVector tick_direction)
{
  GtkWidget *widget;
  GtkPlot *plot;
  GdkFont *font;
  GtkPlotText title, tick;
  gchar label[100];
  gdouble x_tick;
  gint x, y;
  gint xx, yy;
  gint ox, oy;
  gint text_height;
  gint xp, yp, width, height;
  gint ntick;
  gdouble m;
  gboolean veto = FALSE;

  widget = GTK_WIDGET(polar);
  plot = GTK_PLOT(polar);

  m = plot->magnification;

  xp = roundint(plot->x * widget->allocation.width);
  yp = roundint(plot->y * widget->allocation.height);
  width = roundint(plot->width * widget->allocation.width);
  height = roundint(plot->height * widget->allocation.height);

  ox = width / 2.;
  oy = height / 2.;

  x = xp + ox * axis->direction.x + axis->origin.x;
  y = yp + oy * axis->direction.y + axis->origin.y;

  gtk_plot_pc_set_color(plot->pc, &axis->labels_attr.fg);

  font = gtk_psfont_get_gdkfont(axis->labels_attr.font,
                                roundint(axis->labels_attr.height * m));
  text_height = font->ascent + font->descent;

  switch(axis->labels_attr.angle){
    case 0:
           y += text_height / 2.;
           break;
    case 90:
           break;
    case 180:
           y -= text_height / 2.;
           break;
    case 270:
           break;
  }

  tick = axis->labels_attr;
  for(ntick = 0; ntick < axis->ticks.nmajorticks; ntick++){
    xx = axis->direction.x * axis->ticks.major[ntick];
    yy = axis->direction.y * axis->ticks.major[ntick];
    x_tick = axis->ticks.major_values[ntick];
    if(x_tick >= axis->min-1.e-9){
      if(!axis->custom_labels){
        parse_label(x_tick, axis->label_precision, axis->label_style, label);
      }
      else
      {
        gtk_signal_emit_by_name(GTK_OBJECT(axis), "tick_label", 
                                &x_tick, label, &veto);
        if(!veto)
          parse_label(x_tick, axis->label_precision, axis->label_style, label);
      }
      tick.text = label;

      if(axis->label_mask & GTK_PLOT_LABEL_IN){
         tick.x = x + xx;
         tick.y = y + yy;
         tick.x = tick.x + tick_direction.x*roundint(axis->labels_offset * m);
         tick.y = tick.y + tick_direction.y*roundint(axis->labels_offset * m);
         tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width;
         tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height;
         gtk_plot_draw_text(plot, tick);
         tick.x = x - xx;
         tick.y = y - yy;
         tick.x = tick.x + tick_direction.x*roundint(axis->labels_offset * m);
         tick.y = tick.y + tick_direction.y*roundint(axis->labels_offset * m);
         tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width;
         tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height;
         gtk_plot_draw_text(plot, tick);
      }
      if(axis->label_mask & GTK_PLOT_LABEL_OUT){
         tick.x = x + xx;
         tick.y = y + yy;
         tick.x = tick.x - tick_direction.x*roundint(axis->labels_offset * m);
         tick.y = tick.y - tick_direction.y*roundint(axis->labels_offset * m);
         tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width;
         tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height;
         gtk_plot_draw_text(plot, tick);
         tick.x = x - xx;
         tick.y = y - yy;
         tick.x = tick.x - tick_direction.x*roundint(axis->labels_offset * m);
         tick.y = tick.y - tick_direction.y*roundint(axis->labels_offset * m);
         tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width;
         tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height;
         gtk_plot_draw_text(plot, tick);
      }
    }
  }
  if(axis->title_visible && axis->title.text)
       {
         title = axis->title;
         gtk_plot_draw_text(plot, title);
       }

  gdk_font_unref(font);
}

static void
gtk_plot_polar_surface_draw_circle(GtkPlotPolarSurface *polar)
{
  GtkWidget *widget;
  GtkPlot *plot;
  GtkPlotAxis *axis, perp;
  GtkPlotText tick;
  GdkFont *font;
  gchar label[100];
  gint x, y;
  gint line_width;
  gint xp, yp, width, height, size;
  gint ntick;
  gdouble m;
  gdouble x_tick = 0.;
  gint x1, y1;
  gint ox, oy;
  gint text_height;
  gdouble rotation;
  gboolean veto = FALSE;

  widget = GTK_WIDGET(polar);
  plot = GTK_PLOT(polar);

  m = plot->magnification;
  rotation = polar->rotation;

  xp = roundint(plot->x * (gdouble)widget->allocation.width);
  yp = roundint(plot->y * (gdouble)widget->allocation.height);
  width = roundint(plot->width * (gdouble)widget->allocation.width);
  height = roundint(plot->height * (gdouble)widget->allocation.height);

  ox = width / 2.;
  oy = height / 2.;

  x = xp + ox;
  y = yp + oy;

  axis = plot->bottom;

  line_width = axis->line.line_width;
  gtk_plot_pc_set_color(plot->pc, &axis->line.color);

  gtk_plot_pc_set_lineattr(plot->pc, axis->line.line_width, 0, 3, 0);

  gtk_plot_get_pixel(plot,
                     plot->ymax,
                     90.0 - rotation,
                     &x1, &size);
  size = abs(size - y);
  gtk_plot_pc_draw_circle (plot->pc,
                          FALSE,
                          x, y,
                          2 * size);

  gtk_plot_pc_set_lineattr(plot->pc, axis->ticks_width, 0, 1, 0);

  font = gtk_psfont_get_gdkfont(axis->labels_attr.font,
                                roundint(axis->labels_attr.height * m));
  text_height = font->ascent + font->descent;

  for(ntick = 0; ntick < axis->ticks.nmajorticks; ntick++){
    if(axis->ticks.major_values[ntick] >= axis->min){
      x_tick = axis->ticks.major_values[ntick];

      if(!axis->custom_labels){
        parse_label(x_tick, axis->label_precision, axis->label_style, label);
      }
      else
      {
        gtk_signal_emit_by_name(GTK_OBJECT(axis), "tick_label", 
                                &x_tick, label, &veto);
        if(!veto)
          parse_label(x_tick, axis->label_precision, axis->label_style, label);
      }

      gtk_plot_get_pixel(plot,
                         plot->ymax,
                         x_tick,
                         &x1, &y1);

      x_tick += rotation;

      if(axis->major_mask & GTK_PLOT_TICKS_IN){
         perp.direction.x = cos(x_tick * PI / 180.);
         perp.direction.y = -sin(x_tick * PI / 180.);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + roundint(perp.direction.x*m*axis->ticks_length),
                       y1 + roundint(perp.direction.y*m*axis->ticks_length));
      }
      if(axis->major_mask & GTK_PLOT_TICKS_OUT){
         perp.direction.x = -cos(x_tick * PI / 180.);
         perp.direction.y = sin(x_tick * PI / 180.);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - roundint(perp.direction.x*m*axis->ticks_length),
                       y1 - roundint(perp.direction.y*m*axis->ticks_length));
      }

      tick = axis->labels_attr;
      tick.text = label;

      if((x_tick >= 0.0 && x_tick < 90.0) || (x_tick > 270.0 && x_tick <= 360.0)) 
                                  tick.justification = GTK_JUSTIFY_LEFT;
      if(x_tick > 90.0 && x_tick < 270.0) 
                                  tick.justification = GTK_JUSTIFY_RIGHT;
      if(x_tick == 90.0 || x_tick == 270.0) 
                                  tick.justification = GTK_JUSTIFY_CENTER;
      y1 += text_height / 2;

      if((x_tick - rotation) != 360.0 && axis->label_mask != 0){
         perp.direction.x = -cos(x_tick * PI / 180.);
         perp.direction.y = sin(x_tick * PI / 180.);
         tick.x = x1;
         tick.y = y1;
         tick.x -= roundint(perp.direction.x*axis->labels_offset * m);
         tick.y -= roundint(perp.direction.y*axis->labels_offset * m);
         tick.x = (gdouble)tick.x / (gdouble)widget->allocation.width;
         tick.y = (gdouble)tick.y / (gdouble)widget->allocation.height;
         gtk_plot_draw_text(plot, tick);
      }

    }
  }    

  for(ntick = 0; ntick < axis->ticks.nminorticks; ntick++){
    if(axis->ticks.minor_values[ntick] >= axis->min){
      x_tick = axis->ticks.minor_values[ntick];

      gtk_plot_get_pixel(plot,
                         plot->ymax,
                         x_tick,
                         &x1, &y1);

      x_tick += rotation;

      if(axis->minor_mask & GTK_PLOT_TICKS_IN){
         perp.direction.x = cos(x_tick * PI / 180.);
         perp.direction.y = -sin(x_tick * PI / 180.);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + roundint(perp.direction.x*m*axis->ticks_length)/2,
                       y1 + roundint(perp.direction.y*m*axis->ticks_length)/2);
      }
      if(axis->minor_mask & GTK_PLOT_TICKS_OUT){
         perp.direction.x = -cos(x_tick * PI / 180.);
         perp.direction.y = sin(x_tick * PI / 180.);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - roundint(perp.direction.x*m*axis->ticks_length)/2,
                       y1 - roundint(perp.direction.y*m*axis->ticks_length)/2);
      }
    }
  }    

  gdk_font_unref(font);
}


static gint
roundint (gdouble x)
{
 gint sign = 1;

/* if(x <= 0.) sign = -1; 
*/
 return (x+sign*.50999999471);
}

static void
parse_label(gdouble val, gint precision, gint style, gchar *label)
{
  gdouble auxval;
  gint intspace = 0;
  gint power;
  gfloat v;

  auxval = fabs(val);

  power = 0.0;
  if(auxval != 0.0)
       power = (gint)log10(auxval);

  v = val / pow(10.0, power); 
  if(abs(v) < 1.0 && v != 0.0){
     v *= 10.0;
     power -= 1;
  }
  if(abs(v) >= 10.0){
     v /= 10.0;
     power += 1;
  }
  if(power < -12){
     power = 0;
     v =0.0;
  }

  if(auxval > 1)
    intspace = (gint)log10(auxval);


  switch(style){
    case GTK_PLOT_LABEL_EXP:    
      sprintf (label, "%*.*E", 1, precision, val);
      break;
    case GTK_PLOT_LABEL_POW:    
      sprintf (label, "%*.*f\\4x\\N10\\S%i", intspace, precision, v, power);
      break;
    case GTK_PLOT_LABEL_FLOAT:
    default:
      sprintf (label, "%*.*f", intspace, precision, val);
  }

}


static void
gtk_plot_polar_surface_real_get_pixel(GtkWidget *widget, 
                              gdouble x, gdouble y,
                              gint *px, gint *py)
{
    GtkPlot *plot;
    GtkPlotPolarSurface *polar;
    gint xp, yp, width, height;
    gint ox, oy;
    gdouble rx, ry;

    plot = GTK_PLOT(widget);
    polar = GTK_PLOT_POLAR_SURFACE(widget);

    xp = roundint(plot->x * widget->allocation.width);
    yp = roundint(plot->y * widget->allocation.height);
    width = roundint(plot->width * widget->allocation.width);
    height = roundint(plot->height * widget->allocation.height);

    ox = xp + width / 2;
    oy = yp + height / 2;

    rx = x * cos((y + polar->rotation) / 180. * PI); 
    ry = x * sin((y + polar->rotation)/ 180. * PI); 

    *px = transform(plot, rx);
    *py = transform(plot, ry);
   
    *px += ox; 
    *py = oy - *py; 
}

static void
gtk_plot_polar_surface_real_get_point(GtkWidget *widget, 
                              gint px, gint py,
                              gdouble *x, gdouble *y)
{
    GtkPlot *plot;
    gint xp, yp, width, height;
    gdouble r, angle;
    gint ox, oy, size;
    gdouble rotation;

    plot = GTK_PLOT(widget);
    xp = roundint(plot->x * widget->allocation.width);
    yp = roundint(plot->y * widget->allocation.height);
    width = roundint(plot->width * widget->allocation.width);
    height = roundint(plot->height * widget->allocation.height);

    rotation = GTK_PLOT_POLAR_SURFACE(widget)->rotation;

    ox = xp + width / 2;
    oy = yp + height / 2;

    size = MIN(width, height);

    px = px - ox;
    py = oy - py;

    if(px == 0){
      if(py >= 0) angle = 90.0 - rotation; 
      if(py < 0) angle = 270.0 - rotation; 
    }
    else {
      angle = (gdouble) abs(py) / (gdouble) abs(px);
      angle = atan(angle);
      angle = angle * 180.0 / PI;
      if(px >= 0 && py < 0) angle = 360.0 - angle; 
      if(px < 0 && py >= 0) angle = 180.0 - angle; 
      if(px < 0 && py < 0) angle += 180.0; 
      angle -= rotation;
    }

    if(angle >= 360.0) angle -= 360.0;
    if(angle < 0.0) angle = 360.0 + angle;

    r = sqrt(px * px + py * py);

    *x = 2.0 * r * plot->ymax / (gdouble) size;
    *y = angle;
}


/***********************************************************/

static void
gtk_plot_calc_ticks(GtkPlotPolarSurface *polar, GtkPlotAxis *axis)
{
  GtkPlot *plot;
  GtkPlotTicks *ticks = NULL;
  GtkPlotScale scale;
  gdouble min = 0., max = 0.;
  gdouble absmin = 0., absmax = 0.;
  gint pt = 0;
  gdouble tick;
  gdouble major_step;
  gdouble minor_step;
  gint nmajor, nminor;
  gint n;

  plot = GTK_PLOT(polar); 

  scale = axis->scale;
  ticks = &axis->ticks;

  max = axis->max;
  min = axis->min;

  absmin = axis->min;
  absmax = axis->max;

  if(ticks->major != NULL){
     g_free(ticks->major);
     g_free(ticks->minor);
     g_free(ticks->major_values);
     g_free(ticks->minor_values);
     ticks->major = NULL;
     ticks->minor = NULL;
     ticks->major_values = NULL;
     ticks->minor_values = NULL;
  }

  nmajor = 0;
  nminor = 0;
  ticks->nmajorticks = 0;
  ticks->nminorticks = 0;
  major_step = ticks->step;
  minor_step = major_step / ((gdouble)ticks->nminor + 1.0);

  if(ticks->step > 0.){
   tick = min - major_step;
   while(tick <= absmax + 2*fabs(major_step)){
     if(tick >= min-1.E-10 && tick <= absmax+1.E-10){
        pt = transform(plot, tick);
        nmajor ++;
        ticks->major = (gint *)g_realloc(ticks->major, nmajor*sizeof(gint));
        ticks->major_values = (gdouble *)g_realloc(ticks->major_values, nmajor*sizeof(gdouble));
        ticks->major[nmajor-1] = pt;
        ticks->major_values[nmajor-1] = tick;
        ticks->nmajorticks = nmajor;
     }
     tick += major_step;
   }
  }

  if(ticks->step >0. && ticks->nminor > 0){
   for(nmajor = 0; nmajor < ticks->nmajorticks; nmajor++){
    tick = ticks->major_values[nmajor];
    for(n = 1; n <= ticks->nminor; n++){
     tick += minor_step;
     if(tick >= min-1.E-10 && tick <= absmax+1.E-10){
        pt = transform(plot, tick);
        nminor ++;
        ticks->minor = (gint *)g_realloc(ticks->minor, nminor*sizeof(gint));
        ticks->minor_values = (gdouble *)g_realloc(ticks->minor_values, nminor*sizeof(gdouble));
        ticks->minor[nminor-1] = pt;
        ticks->minor_values[nminor-1] = tick;
        ticks->nminorticks = nminor;
     }
    }
   }
  }
}

static gint
transform(GtkPlot *plot, gdouble y)
{
  gdouble width, height, size, position;

  position = y / plot->ymax;

  width = (gdouble)GTK_WIDGET(plot)->allocation.width * plot->width;
  height = (gdouble)GTK_WIDGET(plot)->allocation.height * plot->height;

  size = MIN(width, height) / 2;

  return(roundint(size * position));
}

/*******************************************
 * gtk_plot_polar_surface_rotate
 *******************************************/
void
gtk_plot_polar_surface_rotate(GtkPlotPolarSurface *polar, gdouble angle)
{
  polar->rotation = angle;
}


/* gtkplotpolar - polar plots widget for gtk+
 * Copyright 1999-2001  Adrian E. Feiguin <feiguin ifir edu ar>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef __GTK_PLOT_POLAR_SURFACE_H__
#define __GTK_PLOT_POLAR_SURFACE_H__

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include "gtkplot.h"
#include "gtkplotpc.h"


#define GTK_PLOT_POLAR_SURFACE(obj)        GTK_CHECK_CAST (obj, gtk_plot_polar_surface_get_type (), 
GtkPlotPolarSurface)
#define GTK_TYPE_PLOT_POLAR_SURFACE        (gtk_plot_polar_surface_get_type ())
#define GTK_PLOT_POLAR_SURFACE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_plot_polar_surface_get_type, 
GtkPlotPolarSurfaceClass)
#define GTK_IS_PLOT_POLAR_SURFACE(obj)     GTK_CHECK_TYPE (obj, gtk_plot_polar_surface_get_type ())
#define GTK_PLOT_POLAR_SURFACE_FLAGS(plot)         (GTK_PLOT_POLAR_SURFACE(plot)->flags)
#define GTK_PLOT_POLAR_SURFACE_SET_FLAGS(plot,flag) (GTK_PLOT_POLAR_SURFACE_FLAGS(plot) |= (flag))
#define GTK_PLOT_POLAR_SURFACE_UNSET_FLAGS(plot,flag) (GTK_PLOT_POLAR_SURFACE_FLAGS(plot) &= ~(flag))

#define GTK_PLOT_POLAR_SURFACE_TRANSPARENT(plot) (GTK_PLOT_POLAR_SURFACE_FLAGS(plot) & 
GTK_PLOT_POLAR_SURFACE_TRANSPARENT)

typedef struct _GtkPlotPolarSurface             GtkPlotPolarSurface;
typedef struct _GtkPlotPolarSurfaceClass        GtkPlotPolarSurfaceClass;

struct _GtkPlotPolarSurface
{
  GtkPlot plot;
  GdkColor color;
  GdkColor shadow;

  GdkColor grid_foreground;
  GdkColor grid_background;
 
  GtkPlotAxis *r;
  GtkPlotAxis *angle;

  gdouble beamwidth;

  gdouble rotation;
};

struct _GtkPlotPolarSurfaceClass
{
  GtkPlotClass parent_class;
};

/* PlotPolar */

GtkType         gtk_plot_polar_surface_get_type         (void);
GtkWidget*      gtk_plot_polar_surface_new              (GdkDrawable *drawable);
GtkWidget*      gtk_plot_polar_surface_new_with_size    (GdkDrawable *drawable,
                                                         gdouble width, gdouble height);
void            gtk_plot_polar_surface_construct        (GtkPlotPolarSurface *plot,
                                                         GdkDrawable *drawable);
void            gtk_plot_polar_surface_construct_with_size (GtkPlotPolarSurface *plot,
                                                            GdkDrawable *drawable,
                                                            gdouble width, 
                                                            gdouble height);

void            gtk_plot_polar_surface_rotate           (GtkPlotPolarSurface *plot,
                                                         gdouble angle);

#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __GTK_PLOT_POLAR_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]