Laxkit  0.0.7.1
Functions | Variables
Math Related Functions

Functions

int Laxkit::bez_bbox (flatpoint p, flatpoint c, flatpoint d, flatpoint q, DoubleBBox *bbox, double *extrema)
 Update a bounding box to include the given bezier segment.
double Laxkit::bez_closest_point (flatpoint p, flatpoint p1, flatpoint c1, flatpoint c2, flatpoint p2, int maxpoints, double *d_ret, double *dalong_ret, flatpoint *found)
 Return the t parament for the point closest to p in the bezier segment p1,c1,c2,p2.
flatpoint Laxkit::bez_point (double t, flatpoint p1, flatpoint c1, flatpoint c2, flatpoint p2)
 Return the cubic bezier point at t. t==0 is p1, t==1 is p2.
flatpointLaxkit::bez_points (flatpoint *to_points, flatpoint *from_points, int resolution, int ignorefirst)
 Break down the bezier segment to a polyline with resolution points.
flatpointLaxkit::bez_points (flatpoint *to_points, flatpoint p1, flatpoint c1, flatpoint c2, flatpoint p2, int resolution, int ignorefirst)
 Break down the bezier segment to a polyline with resolution points.
double Laxkit::bez_near_point (flatpoint p, flatpoint *points, int n, int maxpoints, double *t_ret, int *i_ret)
 Return the distance p is from the bezier curve in points.
double Laxkit::bez_near_point_p (flatpoint p, flatpoint **points, int n, int maxpoints, double *t_ret, int *i_ret)
 Just like bez_near_point() but with a list of pointers to points, rather than directly at points.
int Laxkit::point_is_in_bez (flatpoint p, flatpoint *points, int n, int resolution)
 Return the winding number of p relative to the bezier curve in points. 0 means point is inside.
void LaxInterfaces::getT (double *v, double t)
 v=[ t^3, t^2, t, 1 ]
double LaxInterfaces::dot (double *a, double *b)
 Returns a*b, a and b are double[4]..
void LaxInterfaces::m_times_v (double *m, double *b, double *v)
 v = m b (b is the vector), m is 4x4 matrix, b and v are double[4]
void LaxInterfaces::m_times_m (double *a, double *b, double *m)
 m = a x b, a and b are 4x4 matrices
void LaxInterfaces::getI (double *I)
 Fill I with 4x4 Identity matrix.
void LaxInterfaces::getScaledI (double *I, double a, double b, double c, double d)
 Fill 4x4 I with x,y,z,w scaled by a,b,c,d.
void LaxInterfaces::printG (const char *ch, double *G)
 For debugging: cout a 4x4 matrix G[16].
void LaxInterfaces::m_transpose (double *M)
 Transpose the 4x4 matrix.
void LaxInterfaces::getPolyT (double *N, double n, double t0)
 This makes a polynomial column vector T:

Variables

double LaxInterfaces::B [16]
 The bezier matrix.
double LaxInterfaces::Binv [16]
 The inverse of the bezier matrix.

Detailed Description

These are functions mainly pertaining to matrix manipulation,

See also pages on transform math and vectors.

Also see this page for a wholesome introduction to the math for bezier curves and patches.

Todo:
*** must add in and make available the bez/bezpatch matrix utils from bezinterface.cc and patchinterface.cc

Function Documentation

int Laxkit::bez_bbox ( flatpoint  p,
flatpoint  c,
flatpoint  d,
flatpoint  q,
DoubleBBox *  bbox,
double *  extrema 
)

Update a bounding box to include the given bezier segment.

This assumes that p has already been figured in bbox, and bbox is already a suitable bbox. That allows easy bounds checking per segment without checking the endpoints more than once.

If extrema is not null, it should be a double[5]. It gets filled with the t parameters corresponding to the extrema of the bez segment (where the tangent to the curve is either vertical or horizontal), where the segment from p to q corresponds to t=[0,1]. Repeated extrema are only included once.

Returns the number of extrema (up to 4).

Todo:
*** something is fishy with quad, occasionally finds way out extreme??

Referenced by LaxInterfaces::ImagePatchInterface::drawpatch(), and LaxInterfaces::PathsData::FindBBox().

double Laxkit::bez_closest_point ( flatpoint  p,
flatpoint  p1,
flatpoint  c1,
flatpoint  c2,
flatpoint  p2,
int  maxpoints,
double *  d_ret,
double *  dalong_ret,
flatpoint found 
)

Return the t parament for the point closest to p in the bezier segment p1,c1,c2,p2.

This merely finds the least distance to p of any point at t=0,1/maxpoints,2/maxpoints,...,1.0.

maxpoints must somehow be chosen so that for each segment [t,t+1/maxpoints], its length is no longer than the distance one is really looking for.

If d_ret!=NULL, then return the minimum distance to the path in it.

References norm().

Referenced by Laxkit::bez_near_point(), Laxkit::bez_near_point_p(), and LaxInterfaces::Path::ClosestPoint().

double Laxkit::bez_near_point ( flatpoint  p,
flatpoint points,
int  n,
int  maxpoints,
double *  t_ret,
int i_ret 
)

Return the distance p is from the bezier curve in points.

points is v-c-c-v-c-c-v-...-v, and n is the number of all points including control points. So (n mod 3) must be 1.

Returns the shortest distance of p to the curve. t_ret gets filled with the t index [0..1] within the segment starting at i_ret. i_ret gets filled with the index in points of the vertex for the segment the point is just after. If there is no point within 1e+10 units of the curve, then i_ret gets -1 and 1e+10 is returned.

This is a very rough approximation. Only checks against maxpoints sample points per segment.

Todo:
I'm sure this could be optimized and improved somehow.

References Laxkit::bez_closest_point().

Referenced by LaxInterfaces::PatchInterface::findNearHorizontal(), and LaxInterfaces::PatchInterface::findNearVertical().

double Laxkit::bez_near_point_p ( flatpoint  p,
flatpoint **  points,
int  n,
int  maxpoints,
double *  t_ret,
int i_ret 
)

Just like bez_near_point() but with a list of pointers to points, rather than directly at points.

This makes it slightly easier to process bezier curves that are not stored as a simple array of flatpoints.

References Laxkit::bez_closest_point().

flatpoint Laxkit::bez_point ( double  t,
flatpoint  p1,
flatpoint  c1,
flatpoint  c2,
flatpoint  p2 
)

Return the cubic bezier point at t. t==0 is p1, t==1 is p2.

Todo:
*** make sure this is really optimized!

Referenced by Laxkit::bez_subdivide(), Laxkit::bez_visual_tangent(), LaxInterfaces::PatchData::bezCrossSection(), LaxInterfaces::Coordinate::direction(), and LaxInterfaces::Path::PointAlongPath().

flatpoint * Laxkit::bez_points ( flatpoint to_points,
flatpoint from_points,
int  resolution,
int  ignorefirst 
)

Break down the bezier segment to a polyline with resolution points.

If ignorefirst, do not compute the first point. This allows code to call this repeatedly without calculating vertices twice.

If to_points!=NULL, it must have room for resolution number of points. If to_points==NULL, then return a new flatpoint[resolution]. In either case, the generates points array is returned.

from_points is an array of the 4 flatpoints of the bezier segment: v-c-c-v.

Todo:
optimize me
flatpoint * Laxkit::bez_points ( flatpoint to_points,
flatpoint  p1,
flatpoint  c1,
flatpoint  c2,
flatpoint  p2,
int  resolution,
int  ignorefirst 
)

Break down the bezier segment to a polyline with resolution points.

If ignorefirst, do not compute the first point. This allows code to call this repeatedly without calculating vertices twice.

If to_points!=NULL, it must have room for resolution number of points. If to_points==NULL, then return a new flatpoint[resolution]. In either case, to_points is returned.

p1,c1,c2,p2 define the bezier segment. This just puts the points in an array and calls bezpoints(flatpoint *,flatpoint *,int,int).

References Laxkit::bez_points().

void LaxInterfaces::getPolyT ( double *  N,
double  n,
double  t0 
)

This makes a polynomial column vector T:

    [ t^3 ]
  T=[ t^2 ], v=n*(t-t0), t=v/n + t0, 
    [  t  ]
    [  1  ]
    V = N T
     [ 1/n^3  3*t0/n^2  3*t0^2/n   t0^3 ] 
   N=[   0     1/n^2     2*t0/n    t0^2 ]
     [   0       0         1/n      t0  ]
     [   0       0          0        1  ]
 
Todo:
this could be optimized a little

Referenced by LaxInterfaces::PatchData::subdivide().

int Laxkit::point_is_in_bez ( flatpoint  p,
flatpoint points,
int  n,
int  resolution 
)

Return the winding number of p relative to the bezier curve in points. 0 means point is inside.

points is assumed to be: c-v-c-c-v-...-v-c, and n must be number of vertices. So there must be n*3 points in the array.

This breaks down the curve into (number of vertices-1)*resolution points, and then finds the winding number for the resulting polyline.

References Laxkit::bez_to_points(), and point_is_in().

Referenced by LaxInterfaces::PatchData::inSubPatch().


Variable Documentation

double LaxInterfaces::B
double LaxInterfaces::Binv
Initial value:
{ 0, 0, 0, 1,
0, 0, 1./3, 1,
0, 1./3, 2./3, 1,
1, 1, 1, 1
}

The inverse of the bezier matrix.

See here for what this is.

Referenced by LaxInterfaces::PatchData::subdivide().


Mon Feb 17 2014 11:52:58, Laxkit