Commit 845fa0cb authored by Michael Schumacher's avatar Michael Schumacher Committed by Michael Schumacher

plug-ins/gfig/gfig-dialog.c plug-ins/gfig/gfig-grid.c applied a patch by

2005-07-13  Michael Schumacher  <schumaml@cvs.gnome.org>

	* plug-ins/gfig/gfig-dialog.c
	* plug-ins/gfig/gfig-grid.c
	* plug-ins/gfig/gfig.h: applied a patch by Ted Shaneyfelt that
	addresses parts of bug 151092: less sectors on inner, more sectors
	on outer tracks.
parent c6ea4250
2005-07-13 Michael Schumacher <schumaml@cvs.gnome.org>
* plug-ins/gfig/gfig-dialog.c
* plug-ins/gfig/gfig-grid.c
* plug-ins/gfig/gfig.h: applied a patch by Ted Shaneyfelt that
addresses parts of bug 151092: less sectors on inner, more sectors
on outer tracks.
2005-07-13 Sven Neumann <sven@gimp.org>
* app/base/Makefile.am
......
......@@ -94,7 +94,12 @@ SelectItVals selvals =
FALSE, /* drawgrid */
FALSE, /* snap2grid */
FALSE, /* lockongrid */
TRUE /* show control points */
TRUE, /* show control points */
0.0, /* grid_radius_min */
10.0, /* grid_radius_interval */
0.0, /* grid_rotation */
5.0, /* grid_granularity */
120 /* grid_sectors_desired */
},
FALSE, /* show image */
MIN_UNDO + (MAX_UNDO - MIN_UNDO)/2, /* Max level of undos */
......@@ -127,6 +132,8 @@ selection_option selopt =
typedef struct
{
GtkAdjustment *gridspacing;
GtkAdjustment *grid_sectors_desired;
GtkAdjustment *grid_radius_interval;
GtkWidget *gridtypemenu;
GtkWidget *drawgrid;
GtkWidget *snap2grid;
......@@ -1348,6 +1355,8 @@ gfig_grid_action_callback (GtkAction *action,
GtkWidget *table;
GtkWidget *combo;
GtkObject *size_data;
GtkObject *sectors_data;
GtkObject *radius_data;
dialog = gimp_dialog_new (_("Grid"), "gfig-grid",
GTK_WIDGET (data), 0, NULL, NULL,
......@@ -1396,6 +1405,45 @@ gfig_grid_action_callback (GtkAction *action,
g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.gridspacing),
(gpointer) &gfig_opt_widget.gridspacing);
sectors_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 3,
_("Polar grid sectors desired:"), 1, 5,
selvals.opts.grid_sectors_desired,
5, 360, 5, 1, 0,
TRUE, 0, 0,
NULL, NULL);
g_signal_connect (sectors_data, "value_changed",
G_CALLBACK (gimp_int_adjustment_update),
&selvals.opts.grid_sectors_desired);
g_signal_connect (sectors_data, "value_changed",
G_CALLBACK (draw_grid_clear),
NULL);
gfig_opt_widget.grid_sectors_desired = GTK_ADJUSTMENT (sectors_data);
g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.grid_sectors_desired),
(gpointer) &gfig_opt_widget.grid_sectors_desired);
gfig_opt_widget.gridspacing = GTK_ADJUSTMENT (size_data);
g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.gridspacing),
(gpointer) &gfig_opt_widget.gridspacing);
radius_data = gimp_scale_entry_new (GTK_TABLE (table), 0, 4,
_("Polar grid radius interval:"), 1, 5,
selvals.opts.grid_radius_interval,
5, 50, 5, 1, 0,
TRUE, 0, 0,
NULL, NULL);
g_signal_connect (radius_data, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&selvals.opts.grid_radius_interval);
g_signal_connect (radius_data, "value_changed",
G_CALLBACK (draw_grid_clear),
NULL);
gfig_opt_widget.grid_radius_interval = GTK_ADJUSTMENT (radius_data);
g_object_add_weak_pointer (G_OBJECT (gfig_opt_widget.grid_radius_interval),
(gpointer) &gfig_opt_widget.grid_radius_interval);
combo = gimp_int_combo_box_new (_("Rectangle"), RECT_GRID,
_("Polar"), POLAR_GRID,
_("Isometric"), ISO_GRID,
......@@ -1448,6 +1496,14 @@ options_update (GFigObj *old_obj)
{
old_obj->opts.gridspacing = selvals.opts.gridspacing;
}
if (selvals.opts.grid_sectors_desired != old_obj->opts.grid_sectors_desired)
{
old_obj->opts.grid_sectors_desired = selvals.opts.grid_sectors_desired;
}
if (selvals.opts.grid_radius_interval != old_obj->opts.grid_radius_interval)
{
old_obj->opts.grid_radius_interval = selvals.opts.grid_radius_interval;
}
if (selvals.opts.gridtype != old_obj->opts.gridtype)
{
old_obj->opts.gridtype = selvals.opts.gridtype;
......@@ -1476,6 +1532,18 @@ options_update (GFigObj *old_obj)
gtk_adjustment_set_value (gfig_opt_widget.gridspacing,
gfig_context->current_obj->opts.gridspacing);
}
if (selvals.opts.grid_sectors_desired != gfig_context->current_obj->opts.grid_sectors_desired)
{
if (gfig_opt_widget.grid_sectors_desired)
gtk_adjustment_set_value (gfig_opt_widget.grid_sectors_desired,
gfig_context->current_obj->opts.grid_sectors_desired);
}
if (selvals.opts.grid_radius_interval != gfig_context->current_obj->opts.grid_radius_interval)
{
if (gfig_opt_widget.grid_radius_interval)
gtk_adjustment_set_value (gfig_opt_widget.grid_radius_interval,
gfig_context->current_obj->opts.grid_radius_interval);
}
if (selvals.opts.gridtype != gfig_context->current_obj->opts.gridtype)
{
if (gfig_opt_widget.gridtypemenu)
......
......@@ -50,7 +50,122 @@ static void draw_grid_iso (GdkGC *drawgc);
static GdkGC *gfig_get_grid_gc (GtkWidget *widget,
gint gctype);
static gint get_num_radials (void);
static void find_grid_pos_polar (GdkPoint *p,
GdkPoint *gp);
/********** PrimeFactors for Shaneyfelt-style Polar Grid **********
* Quickly factor any number up to 17160
* Correctly factors numbers up to 131 * 131 - 1
*/
typedef struct
{
gint product;
gint remaining;
gint current;
gint next;
gint index;
} PrimeFactors;
static char
primes[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,
59,61,67,71,73,79,83,89,97,101,103,107,109,113,127};
#define PRIMES_MAX_INDEX 30
static gint
prime_factors_get (PrimeFactors *this)
{
this->current = this->next;
while (this->index <= PRIMES_MAX_INDEX)
{
if (this->remaining % primes[this->index]==0) // divisible
{
this->remaining /= primes[this->index];
this->next = primes[this->index];
return this->current;
}
this->index++;
}
this->next = this->remaining;
this->remaining = 1;
return this->current;
}
static gint
prime_factors_lookahead (PrimeFactors *this)
{
return this->next;
}
static void
prime_factors_reset (PrimeFactors *this)
{
this->remaining = this->product;
this->index = 0;
prime_factors_get (this);
}
static PrimeFactors *
prime_factors_new (gint n)
{
PrimeFactors *this = (PrimeFactors*)g_malloc (sizeof(PrimeFactors));
this->product = n;
prime_factors_reset (this);
return this;
}
static void
prime_factors_delete (PrimeFactors* this)
{
free (this);
}
/********** ********** **********/
static gdouble
sector_size_at_radius (gdouble inner_radius)
{
PrimeFactors *factors = prime_factors_new(selvals.opts.grid_sectors_desired);
gint current_sectors = 1;
gdouble sector_size = 2*G_PI / current_sectors;
while ((current_sectors < selvals.opts.grid_sectors_desired)
&& (inner_radius*sector_size
> prime_factors_lookahead(factors) * selvals.opts.grid_granularity))
{
current_sectors *= prime_factors_get(factors);
sector_size = 2*G_PI / current_sectors;
}
prime_factors_delete(factors);
return sector_size;
}
static void
find_grid_pos_polar (GdkPoint *p,
GdkPoint *gp)
{
gdouble cx = preview_width / 2.0;
gdouble cy = preview_height / 2.0;
gdouble px = p->x - cx;
gdouble py = p->y - cy;
gdouble x = 0;
gdouble y = 0;
gdouble r = sqrt (px*px+py*py);
if (r>=selvals.opts.grid_radius_min*.5)
{
r = selvals.opts.grid_radius_interval
* (gint)( 0.5 + ( (r - selvals.opts.grid_radius_min) / selvals.opts.grid_radius_interval))
+ selvals.opts.grid_radius_min;
gdouble t = atan2 (py, px) + 2*G_PI;
gdouble sectorSize = sector_size_at_radius (r);
t = selvals.opts.grid_rotation
+ (gint)( 0.5 + ( (t - selvals.opts.grid_rotation) / sectorSize ))
* sectorSize;
x = r * cos (t);
y = r * sin (t);
}
gp->x = x + cx;
gp->y = y + cy;
}
/* find_grid_pos - Given an x, y point return the grid position of it */
/* return the new position in the passed point */
......@@ -103,9 +218,6 @@ find_grid_pos (GdkPoint *p,
gint16 x = p->x;
gint16 y = p->y;
static GdkPoint cons_pnt;
static gdouble cons_radius;
static gdouble cons_ang;
static gboolean cons_center;
if (selvals.opts.gridtype == RECT_GRID)
{
......@@ -133,71 +245,7 @@ find_grid_pos (GdkPoint *p,
}
else if (selvals.opts.gridtype == POLAR_GRID)
{
gdouble ang_grid;
gdouble ang_radius;
gdouble real_radius;
gdouble real_angle;
gdouble rounded_angle;
gint rounded_radius;
gint16 shift_x = x - preview_width/2;
gint16 shift_y = -y + preview_height/2;
real_radius = ang_radius = sqrt ((shift_y*shift_y) + (shift_x*shift_x));
/* round radius */
rounded_radius = (gint)(RINT (ang_radius/selvals.opts.gridspacing))*selvals.opts.gridspacing;
if (rounded_radius <= 0 || real_radius <=0)
{
/* DEAD CENTER */
gp->x = preview_width/2;
gp->y = preview_height/2;
if (!is_butt3) cons_center = TRUE;
#ifdef DEBUG
printf ("Dead center\n");
#endif /* DEBUG */
return;
}
ang_grid = 2*G_PI/get_num_radials ();
real_angle = atan2 (shift_y, shift_x);
if (real_angle < 0)
real_angle += 2*G_PI;
rounded_angle = (RINT ((real_angle/ang_grid)))*ang_grid;
#ifdef DEBUG
printf ("real_ang = %f ang_gid = %f rounded_angle = %f rounded radius = %d\n",
real_angle, ang_grid, rounded_angle, rounded_radius);
printf ("preview_width = %d preview_height = %d\n", preview_width, preview_height);
#endif /* DEBUG */
gp->x = (gint)RINT ((rounded_radius*cos (rounded_angle))) + preview_width/2;
gp->y = -(gint)RINT ((rounded_radius*sin (rounded_angle))) + preview_height/2;
if (is_butt3)
{
if (!cons_center)
{
if (fabs (rounded_angle - cons_ang) > ang_grid/2)
{
gp->x = (gint)RINT ((cons_radius*cos (rounded_angle))) + preview_width/2;
gp->y = -(gint)RINT ((cons_radius*sin (rounded_angle))) + preview_height/2;
}
else
{
gp->x = (gint)RINT ((rounded_radius*cos (cons_ang))) + preview_width/2;
gp->y = -(gint)RINT ((rounded_radius*sin (cons_ang))) + preview_height/2;
}
}
}
else
{
cons_radius = rounded_radius;
cons_ang = rounded_angle;
cons_center = FALSE;
}
find_grid_pos_polar (p,gp);
}
else if (selvals.opts.gridtype == ISO_GRID)
{
......@@ -313,60 +361,52 @@ find_grid_pos (GdkPoint *p,
static void
draw_grid_polar (GdkGC *drawgc)
{
gint step;
gint loop;
gint radius;
gint max_rad;
gdouble ang_grid;
gdouble ang_loop;
gdouble ang_radius;
/* Pick center and draw concentric circles */
gint grid_x_center = preview_width/2;
gint grid_y_center = preview_height/2;
step = selvals.opts.gridspacing;
max_rad = sqrt (preview_width * preview_width +
preview_height * preview_height) / 2;
for (loop = 0; loop < max_rad; loop += step)
{
radius = loop;
gdk_draw_arc (gfig_context->preview->window,
drawgc,
0,
grid_x_center - radius,
grid_y_center - radius,
radius*2,
radius*2,
0,
360 * 64);
}
/* Lines */
ang_grid = 2 * G_PI / get_num_radials ();
ang_radius = sqrt ((preview_width * preview_width) +
(preview_height * preview_height)) / 2;
for (loop = 0; loop <= get_num_radials (); loop++)
gdouble inner_radius;
gdouble outer_radius;
gdouble max_radius = sqrt (preview_width * preview_width + preview_height * preview_height);
gint current_sectors = 1;
PrimeFactors *factors = prime_factors_new(selvals.opts.grid_sectors_desired);
for ( inner_radius = 0 , outer_radius = selvals.opts.grid_radius_min;
outer_radius <= max_radius;
inner_radius = outer_radius , outer_radius += selvals.opts.grid_radius_interval )
{
gint lx, ly;
ang_loop = loop * ang_grid;
lx = RINT (ang_radius * cos (ang_loop));
ly = RINT (ang_radius * sin (ang_loop));
gdk_draw_line (gfig_context->preview->window,
drawgc,
lx + (preview_width) / 2,
- ly + (preview_height) / 2,
(preview_width) / 2,
(preview_height) / 2);
gdouble t;
gdouble sector_size = 2*G_PI / current_sectors;
gdk_draw_arc (gfig_context->preview->window,
drawgc,
0,
0.5 + (preview_width / 2 - outer_radius),
0.5 + (preview_height / 2 - outer_radius),
0.5 + (outer_radius * 2),
0.5 + (outer_radius * 2),
0,
360 * 64);
while ( (current_sectors < selvals.opts.grid_sectors_desired)
&& ( inner_radius * sector_size
> prime_factors_lookahead (factors) * selvals.opts.grid_granularity ) )
{
current_sectors *= prime_factors_get (factors);
sector_size = 2*G_PI / current_sectors;
}
for (t = 0 ; t < 2*G_PI ; t += sector_size)
{
gdouble normal_x = cos (selvals.opts.grid_rotation+t);
gdouble normal_y = sin (selvals.opts.grid_rotation+t);
gdk_draw_line (gfig_context->preview->window,
drawgc,
0.5 + (preview_width / 2 + inner_radius * normal_x),
0.5 + (preview_height / 2 - inner_radius * normal_y),
0.5 + (preview_width / 2 + outer_radius * normal_x),
0.5 + (preview_height / 2 - outer_radius * normal_y) );
}
}
prime_factors_delete (factors);
}
static void
draw_grid_sq (GdkGC *drawgc)
{
......@@ -510,13 +550,4 @@ draw_grid (void)
draw_grid_iso (drawgc);
}
static gint
get_num_radials (void)
{
gint gridsp = MAX_GRID + MIN_GRID;
/* select number of radials to draw */
/* Either have 16 32 or 48 */
/* correspond to GRID_MAX, midway and GRID_MIN */
return gridsp - selvals.opts.gridspacing;
}
......@@ -40,6 +40,11 @@ typedef struct
gboolean snap2grid;
gboolean lockongrid;
gboolean showcontrol;
gdouble grid_radius_min;
gdouble grid_radius_interval;
gdouble grid_rotation;
gdouble grid_granularity;
gint grid_sectors_desired;
} GfigOpts;
typedef struct
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment