/* This is -*- C -*- */ /* $Id: guppi-curve-func.c,v 1.1 2002/01/08 06:28:59 trow Exp $ */ /* * guppi-curve-func-impl.c * * Copyright (C) 2000 EMC Capital Management, Inc. * Copyright (C) 2001 The Free Software Foundation * * Developed by Jon Trowbridge and * Havoc Pennington . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include "guppi-curve-func.h" #include #include #include #include #include #include static GtkObjectClass *parent_class = NULL; enum { ARG_0, ARG_CURVE, ARG_REPARAMETERIZE, ARG_T0, ARG_T1, ARG_T_FUNC, ARG_X_FUNC, ARG_Y_FUNC, ARG_X_BINARY_FUNC, ARG_Y_BINARY_FUNC, ARG_USE_2x2_MATRIX, ARG_MATRIX_A, ARG_MATRIX_B, ARG_MATRIX_C, ARG_MATRIX_D }; static void guppi_curve_func_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id) { switch (arg_id) { default: break; }; } static void guppi_curve_func_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id) { GuppiCurveFunc *func = GUPPI_CURVE_FUNC (obj); GuppiCurve *c; gboolean rp; double t; GuppiFnWrapper *fw; switch (arg_id) { case ARG_CURVE: c = GUPPI_CURVE (GTK_VALUE_POINTER (*arg)); if (func->base_curve != c) { guppi_refcounting_assign (func->base_curve, c); guppi_data_changed (GUPPI_DATA (obj)); }; break; case ARG_REPARAMETERIZE: rp = GTK_VALUE_BOOL (*arg); if (func->reparameterize != rp) { func->reparameterize = rp; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_T0: t = GTK_VALUE_DOUBLE (*arg); if (func->t0 != t || !func->reparameterize) { func->t0 = t; func->reparameterize = TRUE; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_T1: t = GTK_VALUE_DOUBLE (*arg); if (func->t1 != t || !func->reparameterize) { func->t1 = t; func->reparameterize = TRUE; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_T_FUNC: fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg)); if (func->t_fn_wrapper != fw || !func->reparameterize) { func->reparameterize = TRUE; guppi_refcounting_assign (func->t_fn_wrapper, fw); guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_X_FUNC: fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg)); if (func->x_fn_wrapper != fw) { guppi_refcounting_assign (func->x_fn_wrapper, fw); guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_Y_FUNC: fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg)); if (func->y_fn_wrapper != fw) { guppi_refcounting_assign (func->y_fn_wrapper, fw); guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_X_BINARY_FUNC: fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg)); if (func->x_binary_fn_wrapper != fw) { guppi_refcounting_assign (func->x_binary_fn_wrapper, fw); guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_Y_BINARY_FUNC: fw = GUPPI_FN_WRAPPER (GTK_VALUE_POINTER (*arg)); if (func->y_binary_fn_wrapper != fw) { guppi_refcounting_assign (func->y_binary_fn_wrapper, fw); guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_USE_2x2_MATRIX: rp = GTK_VALUE_BOOL (*arg); if (func->use_2x2_matrix != rp) { func->use_2x2_matrix = rp; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_MATRIX_A: t = GTK_VALUE_DOUBLE (*arg); if (func->a != t) { func->a = t; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_MATRIX_B: t = GTK_VALUE_DOUBLE (*arg); if (func->b != t) { func->b = t; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_MATRIX_C: t = GTK_VALUE_DOUBLE (*arg); if (func->c != t) { func->c = t; guppi_data_changed (GUPPI_DATA (obj)); } break; case ARG_MATRIX_D: t = GTK_VALUE_DOUBLE (*arg); if (func->d != t) { func->d = t; guppi_data_changed (GUPPI_DATA (obj)); } break; default: break; }; } static void guppi_curve_func_finalize (GtkObject *obj) { GuppiCurveFunc *func = GUPPI_CURVE_FUNC (obj); guppi_unref0 (func->t_fn_wrapper); guppi_unref0 (func->x_fn_wrapper); guppi_unref0 (func->y_fn_wrapper); guppi_unref0 (func->x_binary_fn_wrapper); guppi_unref0 (func->y_binary_fn_wrapper); guppi_unref0 (func->base_curve); if (parent_class->finalize) parent_class->finalize (obj); } /**************************************************************************/ static void v_curve_bounds (GuppiCurve *curve, double *a, double *b) { GuppiCurveFunc *cfi = GUPPI_CURVE_FUNC (curve); if (cfi->reparameterize) { if (a) *a = cfi->t0; if (b) *b = cfi->t1; } else { guppi_curve_parameter_bounds (cfi->base_curve, a, b); } } static void v_curve_get (GuppiCurve *curve, double t, double *x, double *y) { GuppiCurveFunc *cfi = GUPPI_CURVE_FUNC (curve); double xx, yy; if (cfi->reparameterize) { if (cfi->t_fn_wrapper) { t = guppi_fn_wrapper_eval_d__d (cfi->t_fn_wrapper, t); t = guppi_curve_clamp_parameter (cfi->base_curve, t); } else { double a, b, u; guppi_curve_parameter_bounds (cfi->base_curve, &a, &b); u = (t - cfi->t0)/(cfi->t1 - cfi->t0); t = a * u + b * (1-u); } } guppi_curve_get (cfi->base_curve, t, &xx, &yy); if (cfi->use_2x2_matrix) { if (x) *x = cfi->a * xx + cfi->b * yy; if (y) *y = cfi->c * xx + cfi->d * yy; return; } if (x) { if (cfi->x_binary_fn_wrapper) *x = guppi_fn_wrapper_eval_d__d_d (cfi->x_binary_fn_wrapper, xx, yy); else if (cfi->x_fn_wrapper) *x = guppi_fn_wrapper_eval_d__d (cfi->x_fn_wrapper, xx); else /* default is identity fn. */ *x = xx; } if (y) { if (cfi->y_binary_fn_wrapper) *y = guppi_fn_wrapper_eval_d__d_d (cfi->y_binary_fn_wrapper, xx, yy); else if (cfi->y_fn_wrapper) *y = guppi_fn_wrapper_eval_d__d (cfi->y_fn_wrapper, yy); else /* default is identity fn. */ *y = yy; } } /**************************************************************************/ #define add_arg(str, t, symb) \ gtk_object_add_arg_type("GuppiCurveFunc::" str, t, GTK_ARG_WRITABLE, symb) static void guppi_curve_func_class_init (GuppiCurveFuncClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; GuppiCurveClass *curve_class = GUPPI_CURVE_CLASS (klass); GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_CURVE); object_class->get_arg = guppi_curve_func_get_arg; object_class->set_arg = guppi_curve_func_set_arg; object_class->finalize = guppi_curve_func_finalize; data_class->is_leaf_type = TRUE; curve_class->bounds = v_curve_bounds; curve_class->get = v_curve_get; add_arg ("curve", GTK_TYPE_POINTER, ARG_CURVE); add_arg ("reparameterize", GTK_TYPE_BOOL, ARG_REPARAMETERIZE); add_arg ("t0", GTK_TYPE_DOUBLE, ARG_T0); add_arg ("t1", GTK_TYPE_DOUBLE, ARG_T1); add_arg ("t_function", GTK_TYPE_POINTER, ARG_T_FUNC); add_arg ("x_function", GTK_TYPE_POINTER, ARG_X_FUNC); add_arg ("y_function", GTK_TYPE_POINTER, ARG_Y_FUNC); add_arg ("x_binary_function", GTK_TYPE_POINTER, ARG_X_BINARY_FUNC); add_arg ("y_binary_function", GTK_TYPE_POINTER, ARG_Y_BINARY_FUNC); add_arg ("use_2x2_matrix", GTK_TYPE_BOOL, ARG_USE_2x2_MATRIX); add_arg ("matrix_a", GTK_TYPE_DOUBLE, ARG_MATRIX_A); add_arg ("matrix_b", GTK_TYPE_DOUBLE, ARG_MATRIX_B); add_arg ("matrix_c", GTK_TYPE_DOUBLE, ARG_MATRIX_C); add_arg ("matrix_d", GTK_TYPE_DOUBLE, ARG_MATRIX_D); } static void guppi_curve_func_init (GuppiCurveFunc *obj) { obj->t0 = 0; obj->t1 = 1; } GtkType guppi_curve_func_get_type (void) { static GtkType guppi_curve_func_type = 0; if (!guppi_curve_func_type) { static const GtkTypeInfo guppi_curve_func_info = { "GuppiCurveFunc", sizeof (GuppiCurveFunc), sizeof (GuppiCurveFuncClass), (GtkClassInitFunc) guppi_curve_func_class_init, (GtkObjectInitFunc) guppi_curve_func_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_curve_func_type = gtk_type_unique (GUPPI_TYPE_CURVE, &guppi_curve_func_info); } return guppi_curve_func_type; } /**************************************************************************/ #if 0 GuppiData * guppi_curve_new_reparameterize_linearly (double t0, double t1, GuppiCurve *curve) { g_return_val_if_fail (curve && GUPPI_IS_CURVE (curve), NULL); return guppi_data_new_by_type (GUPPI_TYPE_CURVE, GUPPI_TYPE_CURVE_FUNC, "curve", curve, "t0", t0, "t1", t1, NULL); } GuppiData * guppi_curve_new_reparameterize (double t0, double t1, GuppiFnWrapper *t_fn, GuppiCurve *curve) { g_return_val_if_fail (curve && GUPPI_IS_CURVE (curve), NULL); g_return_val_if_fail (t_fn && GUPPI_IS_FN_WRAPPER (t_fn), NULL); return guppi_data_new_by_type (GUPPI_TYPE_CURVE, GUPPI_TYPE_CURVE_FUNC, "curve", curve, "t0", t0, "t1", t1, "t_function", t_fn, NULL); } #endif /* $Id: guppi-curve-func.c,v 1.1 2002/01/08 06:28:59 trow Exp $ */