#ifndef frb_geo_H
#define frb_geo_H

/* Miscellaneous geometry tools */
/* Last edited on 2004-12-31 12:20:04 by stolfi */

#include <r3.h>
#include <r4x4.h>
#include <frb_types.h>

r3_t frb_linear_interpolate
  ( double t, 
    double a, 
    r3_t *pa, 
    double b, 
    r3_t *pb 
  );
  /*
    Interpolates linearly the position at time {t} between 
    points {pa} and {b}, assuming they have times {a} and {b}. */

void frb_hermite_interpolate 
  ( double t, 
    double a, 
    r3_t *pa, 
    r3_t *va, 
    double b, 
    r3_t *pb, 
    r3_t *vb,  
    r3_t *p,
    r3_t *v 
  );
  /*
    Performs cubic Hermite interpolation for argument {t} given
    positions {pa} and {pb} and velocities {va} and {vb} at times {a}
    and {b}. Best used for {t} between {a} and {b}. */

r3_t frb_estimate_velocity_Q 
  ( double a, 
    r3_t *pa, 
    double b, 
    r3_t *pb, 
    double c, 
    r3_t *pc 
  );

r3_t frb_estimate_velocity_L
  ( double a, 
    r3_t *pa, 
    double b, 
    r3_t *pb, 
    double c, 
    r3_t *pc 
  );

r3_t frb_estimate_velocity_C
  ( double a, 
    r3_t *pa, 
    double b, 
    r3_t *pb, 
    double c, 
    r3_t *pc 
  );
  /* 
    These procedures return estimates of a curve's velocity at time {b}, 
    given its positions {pa}, {pb}, {pc} at three successive times {a}, {b}, {c}.
    
    frb_estimate_velocity_Q uses quadratic interpolation. It is precise for
    quadratic functions but is unstable when {b} is near {a} or {c}.
    
    frb_estimate_velocity_L uses linear interpolation between {(a,pa)} and {(c,pc)}.
    It ignores {b} and {pb}.  It is therefore robust for uneven intervals,
    but is not precise for quadratics. 
    
    frb_estimate_velocity_C uses a formula that degenerates to linear
    interpolation between {(a,pa)} and {(b,pb)} when {b} is close to
    {c}, and to linear interpolation between {(b,pb)} and {(c,pc)}
    when {b} is close to {a}.  It thus gives an {unconstrained
    derivative} effect at double nodes, which is useful for
    modeling. It is more robust than frb_estimate_velocity_Q, but 
    is not precise for quadratics. */

double frb_hermite_curve_length
  ( double a, 
    r3_t *pa, 
    r3_t *va, 
    double b, 
    r3_t *pb, 
    r3_t *vb 
  );
  /*
    Computes the approximate length between {pa} and {pb}
    of the cubic curve that interpolates {(a,pa)} and {(b,pb)}, 
    with velocities {va}, {vb} at those points. */

r3_t frb_B_spline_approximation
  ( double t,
    double a, 
    double b, 
    r3_t *Pabc,
    double c, 
    r3_t *Pbcd,
    double d, 
    r3_t *Pcde,
    double e, 
    r3_t *Pdef,
    double f 
  );
  /*
    Computes the position at time {t} of a cubic B-Spline curve
    with control points {Pabc}, {Pbcd}, {Pcde}, {Pdef},
    and knot sequence {a},... {f}.  Assumes {t} lies between {c}
    and {d}. */

double frb_avg_seg_dist
  ( r3_t *a1,
    r3_t *a2,
    r3_t *b1,
    r3_t *b2 
  );
  /* 
    A segment distance function.
    
    The result is the root mean square distance between {a(t)}
    and {b(t)}, which travel along the segments {a1--a2} and {b1--b2}
    at constant speed. */

double frb_avg_seg_dist_sqr
  ( r3_t *a1,
    r3_t *a2,
    r3_t *b1,
    r3_t *b2 
  );
  /* 
    The square of {frb_avg_seg_dist}, only faster. */

r4x4_t frb_translation_matrix ( r3_t *p );
  /*
    Builds a translation matrix that takes the origin of R^3 to 
    point {p} (in Cartesian coordinates). */

r4x4_t frb_rotation_matrix ( r3_t *u, r3_t *v );
  /*
    Builds a rotation matrix that takes the vector {u} to the
    vector {v} by the shortest route. */

r3_t frb_seg_dir ( r3_t *p, r3_t *q );
  /*
    Direction from {p} to {q}. */

r3_t frb_seg_mid ( r3_t *p, r3_t *q );
  /*
    Midpoint of segment from {p} to {q}. */


#endif
