#ifndef frb_curve_H #define frb_curve_H /* Sequences of points of {R^3}, closed or open. */ /* Last edited on 2004-12-31 12:20:05 by stolfi */ #include #include #include #include #include #include typedef r3_vec_t frb_curve_t; /* A sequence of points of {R^3}, often used to represent points on the plane (with the third component set to zero). The elements may be also velocities or accelerations. The curve may be interpreted as a polygonal or a spline, closed or open, depending on the context. */ #define frb_curve_new r3_vec_new /* BASIC MANIPULATION */ /* The {DoXXX} procedures below are analogous to the {XXX} procedures, except that the result is returned in an array provided by the client (which must have the correct size). */ frb_curve_t frb_curve_from_line_segment ( r3_t *p, r3_t *q, int n ); /* Creates a curve with {n} points equally spaced along the segment {p--q}. */ frb_curve_t frb_curve_trim ( frb_curve_t *c, int start, int length ); void frb_curve_do_trim ( frb_curve_t *c, int start, int length, frb_curve_t *x ); /* Returns a new curve that is a copy of elements from {c[start]} to {c[start+length-1]}. Assumes the curve is periodic, i.e. {c[i+n]==c[i]} for all {i}, where {n==(c.nel)}. */ void frb_curve_reverse ( frb_curve_t *c ); /* frb_curve_reverses the direction of traversal of the Curve {c}. */ frb_curve_t frb_curve_extract_segment ( frb_curve_t *c, frb_segment_t *s ); /* Extracts from {c} the part described by {s}, reversing it if {s.rev} is TRUE. */ void frb_curve_do_extract_segment ( frb_curve_t *c, frb_segment_t *s, frb_curve_t *t ); /* Same as {frb_curve_extract_segment} but stores the result in the preallocated curve {*t}. */ r3_t frb_curve_sample_barycenter ( frb_curve_t *c ); /* The barycenter of all points of the curve. */ r3_t frb_curve_area_barycenter ( frb_curve_t *c ); /* Returns the barycenter {b} of the projection of {c} on the XY plane, seen as a polygonal *area*, with {b[2] == 0}. */ frb_window_t frb_curve_get_window ( frb_curve_t *c ); /* Returns the curve's bounding box. */ frb_curve_t frb_curve_translate ( frb_curve_t *c, r3_t t ); void frb_curve_do_translate ( frb_curve_t *c, r3_t t ); /* Translates {c} by the vector {t}. {frb_curve_translate} makes a new copy and translates it, leaving {c} unchanged; {frb_curve_do_translate} modifies {c} itself. */ frb_curve_t frb_curve_map ( frb_curve_t *c, r4x4_t *M ); void frb_curve_do_map ( frb_curve_t *c, r4x4_t *M ); /* Maps {c} by the given projective transformation. {frb_curve_map} makes a new copy and transforms it, leaving {c} unchanged; {frb_curve_do_map} modifies {c} itself. */ r4x4_t frb_curve_normalization_matrix ( frb_curve_t *c, bool_t reverse ); /* Returns a matrix that moves the first sample of {c} to the origin, and the last sample to a point on the positive {X}-axis. If {reverse} is true, reverses the roles of the first and last samples. Requires that the line be open. */ r4x4_t frb_curve_alignment_matrix ( frb_curve_t *a, frb_curve_t *b, double pos ); /* Given two open curves {a} and {b}, returns a matrix that moves the barycenter of {a} to the barycenter of {b}, and rotates {a} so that its general direction is parallel to the general direction of {b}. The general direction is computed from two points {pos*n} steps away from each end, where {n} is the total steps in the curve. */ /* CURVES AS CLOSED POLYGONS */ /* The procedures in this section interpret the curve {p} as the vertices of a closed polygonal curve with {m == (p.nel)} sides. It is assumed that each edge is traversed at constant speed, in such a way that the curve reaches vertex {p[i]} at time {t[i]}, for {i IN [0..m-1]}; and the curve goes back to vertex {p[0]} at time {t[0] + tPeriod}. */ double frb_curve_linear_lengths ( frb_curve_t *p, frb_signal_t *s ); /* Assumes that {p[j]} is the curve position at time {t[j]}. Computes the Euclidean length {s[j]} on the polygonal from vertex {p[0]} to vertex {p[j]}, for {j} in {[0..(p.nel - 1)]}. Returns the total length of the polygonal as the result of the call. */ void frb_curve_linear_uniform_sample ( frb_signal_t *t, /* Times of input samples. */ double tPeriod, /* Time period */ frb_curve_t *p, /* {p[i]} is curve position at time {t[i]}. */ double tStart, /* Time of first output sample */ frb_curve_t *q /* {q[j]} will be position sample number {j}. */ ); /* Computes {n} samples along the curve, equally spaced in time, starting with time {tStart}. The samples are returned in {q[j]}, {j IN [0..n-1]}. */ void frb_curve_linear_equidistant_sample ( frb_curve_t *p, /* {p[i]} is curve position at time {t[i]}. */ double tStart, /* Time of first output sample */ frb_curve_t *q /* {q[j]} will be position sample number {j}. */ ); /* Same as {frb_curve_linear_uniform_sample}, assuming that the curve is traversed with constant velocity in unit time. */ void frb_curve_linear_time_sample ( frb_signal_t *t, /* Times of input samples. */ double tPeriod, /* Time period */ frb_curve_t *p, /* Input curve positions at times {t[i]}. */ frb_signal_t *r, /* Times of output samples. */ frb_curve_t *q /* Output curve positions at times {r[j]}. */ ); /* Computes the positions {q[j]} at the specified times {tq[j]}, {j IN [0..n-1]}. */ /* CURVES AS CLOSED C_1 CUBIC SPLINES */ /* The procedures in this section interpret the curves {p} and {dp} as the positions and velocities of a closed spline curve with {m == (p.nel)} cubic arcs, at the nodal times {t[0..m-1]}. It is assumed the curve goes back to vertex {p[0]} and velocity {dp[0]} at time {t[0] + tPeriod}. */ void frb_curve_hermite_uniform_sample ( frb_signal_t *t, /* Times of input samples. */ double tPeriod, /* Time period */ frb_curve_t *p, /* {p[i]} is curve position at time {t[i]}. */ frb_curve_t *dp, /* {dp[i]} is velocity at time {t[i]}. */ double tStart, /* Time of first output sample */ frb_curve_t *q, /* {q[j]} will be position sample number {j}. */ frb_curve_t *dq /* {dq[j]} will be velocity at point {q[j]}. */ ); /* Computes {n} samples {q[0..n-1]} along the curve, and their velocities {dq[0..n-1]}, equally spaced in time, starting with time {tStart}. */ void frb_curve_hermite_equidistant_sample ( frb_curve_t *p, /* {p[i]} is curve position at time {t[i]}. */ double tStart, /* Time of first output sample */ frb_curve_t *q, /* {q[j]} will be position sample number {j}. */ frb_curve_t *dq /* {dq[j]} will be velocity at point {q[j]}. */ ); /* Same as {frb_curve_hermite_uniform_sample}, assuming that the curve is traversed with constant velocity in the total time {tPeriod}. */ void frb_curve_hermite_time_sample ( frb_signal_t *t, /* Times of input samples. */ double tPeriod, /* Time period */ frb_curve_t *p, /* {p[i]} is curve position at time {t[i]}. */ frb_curve_t *dp, /* {dp[i]} is velocity at time {t[i]}. */ frb_signal_t *r, /* Times of output samples. */ frb_curve_t *q, /* {q[j]} will be curve position at time {r[j]}. */ frb_curve_t *dq /* {dq[j]} will be velocity at time {r[j]}. */ ); /* Computes the positions {q[j]} and velocities {dq[j]} at the specified times {r[j]}, {j IN [0..n-1]}. */ typedef r3_t frb_curve_vel_estimator_t ( double a, r3_t *pa, double b, r3_t *pb, double c, r3_t *pc ); void frb_curve_estimate_velocities ( frb_signal_t *t, double tPeriod, frb_curve_t *p, frb_curve_t *dp, frb_curve_vel_estimator_t est ); /* Estimates the velocity {dp[i]} at each point {p[i]}, by applying the estimator {est} to three consecutive times. */ /* INPUT/OUTPUT */ double frb_curve_adjust_unit ( double givenUnit, frb_curve_t *c ); /* Adjusts the {givenUnit} if needed to avoid overflow or excessive error when quantizing the values in {c}. May print warnings to {stderr}. */ typedef struct frb_curve_read_data_t { char *cmt; /* Comment text. */ int samples; /* Number of samples in curve. */ frb_curve_t c; /* The samples. */ double unit; /* Quantization unit used. */ } frb_curve_read_data_t; frb_curve_read_data_t frb_curve_read ( FILE *rd, double scale, bool_t header_only, bool_t centralize ); /* Reads a curve (and its comments) from {rd}. The curve is magnified by the given {scale} factor. If {header_only==TRUE}, reads only the parameters, and leaves the {c} field as NULL. If {centralize==TRUE}, displaces the curve so that its {frb_curve_area_barycenter} lies at the origin. */ void frb_curve_write ( FILE *wr, char *cmt, frb_curve_t *c, double unit, double scale ); /* Writes curve {c} to {wr}, prefixed with comments {cmt}. The coordinates will be written as integer multiples of the given {unit}. The curve coordinates (as well as the {unit}) are automatically scaled by {1/scale}. */ typedef struct frb_curve_list_read_data_t { frb_curve_read_data_t **sgData; int ncv; /* Number of entries in {sgData}. */ double unitMin; /* Minimum quantization unit. */ double unitMax; /* Maximum quantization unit. */ char *cmt; /* Comment of first curve, if any. */ } frb_curve_list_read_data_t; frb_curve_list_read_data_t frb_curve_list_read ( char *dir, char *fileName, double scale, bool_vec_t *sel, bool_t header_only, bool_t centralize ); /* Reads a set of numbered curves, scales them by the given {scale} factor. Curve number {i} is read if and only if {sel[i] == TRUE}, and its {frb_curve_read_data_t} is stored in {r.curve[i]}; otherwise {r.curve[i] } is set to a record with null {c} field. The data is read from file "{dir}/{KKKK}/{fileName}", where {KKKK} is the curve number {k} (4 digits, zero padded). If {header_only} is TRUE, only the header of each file is read; the {c} fields are all set to NULL. The range of quantization {unit}s of the curves that were read, after scaling, is returned in {r.unitMin}, {r.unitMax}. The comment of the first curve read, plus the call arguments, are stored in {r.cmt}. */ #endif