/* This is -*- C -*- */
/* vim: set sw=2: */
/* $Id: guppi-curve-poly.c,v 1.1 2002/01/08 06:28:59 trow Exp $ */
/*
* guppi-curve-poly-impl.c
*
* Copyright (C) 2000 EMC Capital Management, Inc.
* Copyright (C) 2001 The Free Software Foundation
*
* Developed by Jon Trowbridge <trow@gnu.org>
*
* 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 <config.h>
#include "guppi-curve-poly.h"
#include <math.h>
#include <gnan.h>
#include <guppi-memory.h>
#include <guppi-convenient.h>
#include <guppi-data-plug-in.h>
static GtkObjectClass *parent_class = NULL;
enum {
ARG_0,
ARG_POLYNOMIAL
};
static void
guppi_curve_poly_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
GuppiCurvePoly *poly = GUPPI_CURVE_POLY (obj);
switch (arg_id) {
case ARG_POLYNOMIAL:
GTK_VALUE_POINTER (*arg) = guppi_curve_poly_get_polynomial (poly);
break;
default:
break;
};
}
static void
guppi_curve_poly_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
GuppiCurvePoly *poly = GUPPI_CURVE_POLY (obj);
switch (arg_id) {
case ARG_POLYNOMIAL:
guppi_curve_poly_set_polynomial (poly, GUPPI_POLYNOMIAL (GTK_VALUE_POINTER (*arg)));
break;
default:
break;
};
}
static void
guppi_curve_poly_finalize (GtkObject *obj)
{
GuppiCurvePoly *x = GUPPI_CURVE_POLY(obj);
guppi_unref (x->poly);
if (x->changed_handler)
gtk_signal_disconnect (obj, x->changed_handler);
if (parent_class->finalize)
parent_class->finalize (obj);
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
static void
get (GuppiCurve *curve, double t, double *x, double *y)
{
GuppiCurvePoly *poly = GUPPI_CURVE_POLY (curve);
if (x)
*x = t;
if (y)
*y = guppi_polynomial_eval (poly->poly, t);
}
static void
bbox (GuppiCurve *curve, double a, double b,
double *x0, double *y0, double *x1, double *y1)
{
GuppiCurvePoly *poly = GUPPI_CURVE_POLY (curve);
if (x0) *x0 = a;
if (x1) *x1 = b;
if (! (y0 || y1))
return;
guppi_polynomial_minmax_on_range (poly->poly, a, b, y0, y1);
}
static gboolean
clamp (GuppiCurve *curve, double *a, double *b,
double x0, double y0, double x1, double y1)
{
/*GuppiCurvePoly *poly = GUPPI_CURVE_POLY (curve);*/
if (a) *a = x0;
if (b) *b = x1;
return TRUE;
}
static void
sample (GuppiCurve *curve, gconstpointer t_vec, gint t_stride, gsize N,
gpointer x_vec, gint x_stride,
gpointer y_vec, gint y_stride)
{
GuppiCurvePoly *cp = GUPPI_CURVE_POLY (curve);
GuppiPolynomial *poly = guppi_curve_poly_get_polynomial (cp);
gint i;
guppi_polynomial_sample (poly, N,
(const double *) t_vec, t_stride,
(double *) y_vec, y_stride);
if (x_vec) {
for (i = 0; i < N; ++i) {
*(double *) x_vec = *(double *) t_vec;
t_vec = (gconstpointer) (((gchar *) t_vec) + t_stride);
x_vec = (gpointer) (((gchar *) x_vec) + x_stride);
}
}
}
static void
sample_uniformly (GuppiCurve *curve,
double t0, double t1, gsize N,
double *x_vec, gint x_stride,
double *y_vec, gint y_stride)
{
GuppiCurvePoly *cp = GUPPI_CURVE_POLY (curve);
GuppiPolynomial *poly = guppi_curve_poly_get_polynomial (cp);
guppi_polynomial_sample_uniformly (poly, t0, t1, N,
x_vec, x_stride,
y_vec, y_stride);
}
static ArtVpath *
approx_to_path (GuppiCurve *curve, double t0, double t1,
double x_error, double y_error,
double x0, double y0, double x1, double y1,
double scale_x, double scale_y)
{
GuppiCurvePoly *cp = GUPPI_CURVE_POLY (cp);
GuppiPolynomial *poly = guppi_curve_poly_get_polynomial (cp);
return guppi_polynomial_approximate_path (poly, t0, t1, y0, y1,
x_error, y_error, 0,
scale_x, scale_y);
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
#define add_arg(str, t, symb) \
gtk_object_add_arg_type ("GuppiCurvePoly::" str, t, GTK_ARG_READWRITE, symb)
static void
guppi_curve_poly_class_init (GuppiCurvePolyClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *)klass;
GuppiCurveClass *curve_class = GUPPI_CURVE_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_CURVE);
// curve_class->bounds = bounds;
curve_class->get = get;
curve_class->bbox = bbox;
curve_class->clamp = clamp;
curve_class->sample = sample;
curve_class->sample_uniformly = sample_uniformly;
curve_class->approx_to_path = approx_to_path;
object_class->get_arg = guppi_curve_poly_get_arg;
object_class->set_arg = guppi_curve_poly_set_arg;
object_class->finalize = guppi_curve_poly_finalize;
add_arg ("polynomial", GTK_TYPE_POINTER, ARG_POLYNOMIAL);
}
static void
guppi_curve_poly_init (GuppiCurvePoly *obj)
{
obj->min = -G_INFINITY;
obj->max = G_INFINITY;
}
GtkType
guppi_curve_poly_get_type (void)
{
static GtkType guppi_curve_poly_type = 0;
if (!guppi_curve_poly_type) {
static const GtkTypeInfo guppi_curve_poly_info = {
"GuppiCurvePoly",
sizeof (GuppiCurvePoly),
sizeof (GuppiCurvePolyClass),
(GtkClassInitFunc)guppi_curve_poly_class_init,
(GtkObjectInitFunc)guppi_curve_poly_init,
NULL, NULL, (GtkClassInitFunc)NULL
};
guppi_curve_poly_type = gtk_type_unique (GUPPI_TYPE_CURVE, &guppi_curve_poly_info);
}
return guppi_curve_poly_type;
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
GuppiCurve *
guppi_curve_poly_new (void)
{
return GUPPI_CURVE (guppi_type_new (guppi_curve_poly_get_type ()));
}
GuppiPolynomial *
guppi_curve_poly_get_polynomial (GuppiCurvePoly *curve)
{
g_return_val_if_fail (GUPPI_IS_CURVE_POLY (curve), NULL);
return curve->poly;
}
void
guppi_curve_poly_set_polynomial (GuppiCurvePoly *curve, GuppiPolynomial *p)
{
g_return_if_fail (GUPPI_IS_CURVE_POLY (curve));
g_return_if_fail (p && GUPPI_IS_POLYNOMIAL (p));
if (p != curve->poly) {
if (curve->changed_handler)
gtk_signal_disconnect (GTK_OBJECT (curve->poly), curve->changed_handler);
guppi_refcounting_assign (curve->poly, p);
curve->changed_handler = gtk_signal_connect_object (GTK_OBJECT (p),
"changed",
GTK_SIGNAL_FUNC (guppi_data_changed),
GTK_OBJECT (curve));
guppi_data_changed (GUPPI_DATA (curve));
}
}
GuppiPolynomial *
guppi_curve_get_polynomial (GuppiData *data)
{
g_return_val_if_fail (data && GUPPI_IS_DATA (data), NULL);
if (!GUPPI_IS_CURVE_POLY (data))
return NULL;
return guppi_curve_poly_get_polynomial (GUPPI_CURVE_POLY (data));
}
syntax highlighted by Code2HTML, v. 0.9.1