Clone in a terminal:
Commit 9865e66
Johan Mattsson - 2025-11-23T19:41:38+00:00
9865e6611e0bf00cbc5742ae1aab6eca4d04f072johan.mattsson.m@gmail.com

Fix compile time issue in libbirdgems code The Graphics Gems code was writen by Andrew Glassner and published in Academic Press, 1990. It is amazing that the code still compiles and works in 2025. However, the last version off gcc complains about the function definitions. I updated the function definitions.

Changed files (3)

Diff

diff --git a/libbirdgems/GGVecLib.c b/libbirdgems/GGVecLib.cindex 55393a8..acee019 100644--- a/libbirdgems/GGVecLib.c+++ b/libbirdgems/GGVecLib.c@@ -17,37 +17,36 @@ from "Graphics Gems", Academic Press, 1990  */  #include <math.h>-#include <stdlib.h> #include "GraphicsGems.h" +#ifdef __linux__+#include <malloc.h>+#else+#include <stdlib.h>+#endif+ /******************/ /*   2d Library   */ /******************/  /* returns squared length of input vector */	-double V2SquaredLength(a) -Vector2 *a;-{	return((a->x * a->x)+(a->y * a->y));-	}+double V2SquaredLength(Vector2* a) {+	return((a->x * a->x)+(a->y * a->y));+} 	 /* returns length of input vector */-double V2Length(a) -Vector2 *a;-{-	return(sqrt(V2SquaredLength(a)));-	}+double V2Length(Vector2 *a)  {+	return sqrt(V2SquaredLength(a));+} 	 /* negates the input vector and returns it */-Vector2 *V2Negate(v) -Vector2 *v;-{+Vector2 *V2Negate(Vector2 * v) { 	v->x = -v->x;  v->y = -v->y; 	return(v);-	}+}  /* normalizes the input vector and returns it */-Vector2 *V2Normalize(v) -Vector2 *v;+Vector2 *V2Normalize(Vector2* v)  { double len = V2Length(v); 	if (len != 0.0) { v->x /= len;  v->y /= len; }@@ -56,9 +55,7 @@ double len = V2Length(v);   /* scales the input vector to the new length and returns it */-Vector2 *V2Scale(v, newlen) -Vector2 *v;-double newlen;+Vector2 *V2Scale(Vector2 *v, double newlen)  { double len = V2Length(v); 	if (len != 0.0) { v->x *= newlen/len;   v->y *= newlen/len; }@@ -66,24 +63,21 @@ double len = V2Length(v); 	}  /* return vector sum c = a+b */-Vector2 *V2Add(a, b, c)-Vector2 *a, *b, *c;+Vector2* V2Add(Vector2* a, Vector2* b, Vector2* c) { 	c->x = a->x+b->x;  c->y = a->y+b->y; 	return(c); 	} 	 /* return vector difference c = a-b */-Vector2 *V2Sub(a, b, c)-Vector2 *a, *b, *c;+Vector2 *V2Sub(Vector2 *a, Vector2 *b, Vector2 *c) { 	c->x = a->x-b->x;  c->y = a->y-b->y; 	return(c); 	}  /* return the dot product of vectors a and b */-double V2Dot(a, b) -Vector2 *a, *b; +double V2Dot(Vector2 *a, Vector2 *b)  { 	return((a->x*b->x)+(a->y*b->y)); 	}@@ -91,21 +85,17 @@ Vector2 *a, *b; /* linearly interpolate between vectors by an amount alpha */ /* and return the resulting vector. */ /* When alpha=0, result=lo.  When alpha=1, result=hi. */-Vector2 *V2Lerp(lo, hi, alpha, result) -Vector2 *lo, *hi, *result; -double alpha;+Vector2 *V2Lerp(Vector2 *lo, Vector2 *hi, double alpha, Vector2 *result)  {-	result->x = LERP(alpha, lo->x, hi->x);-	result->y = LERP(alpha, lo->y, hi->y);+	        result->x = LERP(alpha, (lo->x), (hi->x));+	        result->y = LERP(alpha, (lo->y), (hi->y)); 	return(result); 	}   /* make a linear combination of two vectors and return the result. */ /* result = (a * ascl) + (b * bscl) */-Vector2 *V2Combine (a, b, result, ascl, bscl) -Vector2 *a, *b, *result;-double ascl, bscl;+Vector2 *V2Combine (Vector2 *a, Vector2 *b, Vector2 *result, double ascl, double bscl)  { 	result->x = (ascl * a->x) + (bscl * b->x); 	result->y = (ascl * a->y) + (bscl * b->y);@@ -113,8 +103,7 @@ double ascl, bscl; 	}  /* multiply two vectors together component-wise */-Vector2 *V2Mul (a, b, result) -Vector2 *a, *b, *result;+Vector2 *V2Mul (Vector2 *a, Vector2 *b, Vector2 *result)  { 	result->x = a->x * b->x; 	result->y = a->y * b->y;@@ -122,8 +111,7 @@ Vector2 *a, *b, *result; 	}  /* return the distance between two points */-double V2DistanceBetween2Points(a, b)-Point2 *a, *b;+double V2DistanceBetween2Points(Point2 *a, Point2 *b) { double dx = a->x - b->x; double dy = a->y - b->y;@@ -131,8 +119,7 @@ double dy = a->y - b->y; 	}  /* return the vector perpendicular to the input vector a */-Vector2 *V2MakePerpendicular(a, ap)-Vector2 *a, *ap;+Vector2 *V2MakePerpendicular(Vector2 *a, Vector2 *ap) { 	ap->x = -a->y; 	ap->y = a->x;@@ -140,8 +127,7 @@ Vector2 *a, *ap; 	}  /* create, initialize, and return a new vector */-Vector2 *V2New(x, y)-double x, y;+Vector2 *V2New(double x, double y) { Vector2 *v = NEWTYPE(Vector2); 	v->x = x;  v->y = y; @@ -150,8 +136,7 @@ Vector2 *v = NEWTYPE(Vector2); 	  /* create, initialize, and return a duplicate vector */-Vector2 *V2Duplicate(a)-Vector2 *a;+Vector2 *V2Duplicate(Vector2 *a) { Vector2 *v = NEWTYPE(Vector2); 	v->x = a->x;  v->y = a->y; @@ -159,9 +144,7 @@ Vector2 *v = NEWTYPE(Vector2); 	} 	 /* multiply a point by a matrix and return the transformed point */-Point2 *V2MulPointByMatrix(p, m)-Point2 *p;-Matrix3 *m;+Point2 *V2MulPointByMatrix(Point2 *p, Matrix3 *m) { double w; Point2 ptmp;@@ -178,8 +161,7 @@ Point2 ptmp;  /* multiply together matrices c = ab */ /* note that c must not point to either of the input matrices */-Matrix3 *V2MatMul(a, b, c)-Matrix3 *a, *b, *c;+Matrix3 *V2MatMul(Matrix3 *a, Matrix3 *b, Matrix3 *c) { int i, j, k; 	for (i=0; i<3; i++) {@@ -200,30 +182,26 @@ int i, j, k; /******************/ 	 /* returns squared length of input vector */	-double V3SquaredLength(a) -Vector3 *a;+double V3SquaredLength(Vector3 *a)  { 	return((a->x * a->x)+(a->y * a->y)+(a->z * a->z)); 	}  /* returns length of input vector */-double V3Length(a) -Vector3 *a;+double V3Length(Vector3 *a)  { 	return(sqrt(V3SquaredLength(a))); 	}  /* negates the input vector and returns it */-Vector3 *V3Negate(v) -Vector3 *v;+Vector3 *V3Negate(Vector3 *v)  { 	v->x = -v->x;  v->y = -v->y;  v->z = -v->z; 	return(v); 	}  /* normalizes the input vector and returns it */-Vector3 *V3Normalize(v) -Vector3 *v;+Vector3 *V3Normalize(Vector3 *v)  { double len = V3Length(v); 	if (len != 0.0) { v->x /= len;  v->y /= len; v->z /= len; }@@ -231,9 +209,7 @@ double len = V3Length(v); 	}  /* scales the input vector to the new length and returns it */-Vector3 *V3Scale(v, newlen) -Vector3 *v;-double newlen;+Vector3 *V3Scale(Vector3 *v, double newlen)  { double len = V3Length(v); 	if (len != 0.0) {@@ -244,24 +220,21 @@ double len = V3Length(v);   /* return vector sum c = a+b */-Vector3 *V3Add(a, b, c)-Vector3 *a, *b, *c;+Vector3 *V3Add(Vector3 *a, Vector3 *b, Vector3 *c) { 	c->x = a->x+b->x;  c->y = a->y+b->y;  c->z = a->z+b->z; 	return(c); 	} 	 /* return vector difference c = a-b */-Vector3 *V3Sub(a, b, c)-Vector3 *a, *b, *c;+Vector3 *V3Sub(Vector3 *a, Vector3 *b, Vector3 *c) { 	c->x = a->x-b->x;  c->y = a->y-b->y;  c->z = a->z-b->z; 	return(c); 	}  /* return the dot product of vectors a and b */-double V3Dot(a, b) -Vector3 *a, *b; +double V3Dot(Vector3 *a, Vector3 *b)  { 	return((a->x*b->x)+(a->y*b->y)+(a->z*b->z)); 	}@@ -269,9 +242,7 @@ Vector3 *a, *b; /* linearly interpolate between vectors by an amount alpha */ /* and return the resulting vector. */ /* When alpha=0, result=lo.  When alpha=1, result=hi. */-Vector3 *V3Lerp(lo, hi, alpha, result) -Vector3 *lo, *hi, *result; -double alpha;+Vector3 *V3Lerp(Vector3 *lo, Vector3 *hi, double alpha, Vector3 *result)  { 	result->x = LERP(alpha, lo->x, hi->x); 	result->y = LERP(alpha, lo->y, hi->y);@@ -281,9 +252,7 @@ double alpha;  /* make a linear combination of two vectors and return the result. */ /* result = (a * ascl) + (b * bscl) */-Vector3 *V3Combine (a, b, result, ascl, bscl) -Vector3 *a, *b, *result;-double ascl, bscl;+Vector3 *V3Combine (Vector3 *a, Vector3 *b, Vector3 *result, double ascl, double bscl)  { 	result->x = (ascl * a->x) + (bscl * b->x); 	result->y = (ascl * a->y) + (bscl * b->y);@@ -293,8 +262,7 @@ double ascl, bscl;   /* multiply two vectors together component-wise and return the result */-Vector3 *V3Mul (a, b, result) -Vector3 *a, *b, *result;+Vector3 *V3Mul (Vector3 *a, Vector3 *b, Vector3 *result)  { 	result->x = a->x * b->x; 	result->y = a->y * b->y;@@ -303,8 +271,7 @@ Vector3 *a, *b, *result; 	}  /* return the distance between two points */-double V3DistanceBetween2Points(a, b)-Point3 *a, *b;+double V3DistanceBetween2Points(Point3 *a, Point3 *b) { double dx = a->x - b->x; double dy = a->y - b->y;@@ -313,8 +280,7 @@ double dz = a->z - b->z; 	}  /* return the cross product c = a cross b */-Vector3 *V3Cross(a, b, c)-Vector3 *a, *b, *c;+Vector3 *V3Cross(Vector3 *a, Vector3 *b, Vector3 *c) { 	c->x = (a->y*b->z) - (a->z*b->y); 	c->y = (a->z*b->x) - (a->x*b->z);@@ -323,8 +289,7 @@ Vector3 *a, *b, *c; 	}  /* create, initialize, and return a new vector */-Vector3 *V3New(x, y, z)-double x, y, z;+Vector3 *V3New(double x, double y, double z) { Vector3 *v = NEWTYPE(Vector3); 	v->x = x;  v->y = y;  v->z = z;@@ -332,8 +297,7 @@ Vector3 *v = NEWTYPE(Vector3); 	}  /* create, initialize, and return a duplicate vector */-Vector3 *V3Duplicate(a)-Vector3 *a;+Vector3 *V3Duplicate(Vector3 *a) { Vector3 *v = NEWTYPE(Vector3); 	v->x = a->x;  v->y = a->y;  v->z = a->z;@@ -342,9 +306,7 @@ Vector3 *v = NEWTYPE(Vector3);  	 /* multiply a point by a matrix and return the transformed point */-Point3 *V3MulPointByMatrix(p, m)-Point3 *p;-Matrix4 *m;+Point3 *V3MulPointByMatrix(Point3 *p, Matrix4 *m) { double w; Point3 ptmp;@@ -363,9 +325,7 @@ Point3 ptmp;  /* multiply together matrices c = ab */ /* note that c must not point to either of the input matrices */-Matrix4 *V3MatMul(a, b, c)-Matrix4 *a, *b, *c;-{+Matrix4 *V3MatMul(Matrix4 *a, Matrix4 *b, Matrix4 *c) { int i, j, k; 	for (i=0; i<4; i++) { 		for (j=0; j<4; j++) {@@ -375,12 +335,11 @@ int i, j, k; 			} 		} 	return(c);-	}+}  /* binary greatest common divisor by Silver and Terzian.  See Knuth */ /* both inputs must be >= 0 */-int gcd(u, v)-int u, v;+int gcd(int u, int v) { int t, f; 	if ((u<0) || (v<0)) return(1); /* error if u<0 or v<0 */@@ -403,16 +362,15 @@ int t, f;  /* return roots of ax^2+bx+c */ /* stable algebra derived from Numerical Recipes by Press et al.*/-int quadraticRoots(a, b, c, roots)-double a, b, c, *roots;+int quadraticRoots(double a, double b, double c, double *roots) { double d, q; int count = 0; 	d = (b*b)-(4*a*c);-	if (d < 0.0) { *roots = *(roots+1) = 0.0;  return(0); }+	if (d < 0.0) { roots[0] = roots[1] = 0.0;  return(0); } 	q =  -0.5 * (b + (SGN(b)*sqrt(d)));-	if (a != 0.0)  { *roots++ = q/a; count++; }-	if (q != 0.0) { *roots++ = c/q; count++; }+	if (a != 0.0)  { roots[count++] = q/a; }+	if (q != 0.0) { roots[count++] = c/q; } 	return(count); 	} @@ -420,21 +378,19 @@ int count = 0; /* generic 1d regula-falsi step.  f is function to evaluate */ /* interval known to contain root is given in left, right */ /* returns new estimate */-double RegulaFalsi(f, left, right)-double (*f)(), left, right;+double RegulaFalsi(double (*f)(double), double left, double right) {-double d = (*f)(right) - (*f)(left);-	if (d != 0.0) return (right - (*f)(right)*(right-left)/d);+double d = f(right) - f(left);+	if (d != 0.0) return (right - f(right)*(right-left)/d); 	return((left+right)/2.0); 	}  /* generic 1d Newton-Raphson step. f is function, df is derivative */ /* x is current best guess for root location. Returns new estimate */-double NewtonRaphson(f, df, x)-double (*f)(), (*df)(), x;+double NewtonRaphson(double (*f)(double), double (*df)(double), double x) {-double d = (*df)(x);-	if (d != 0.0) return (x-((*f)(x)/d));+double d = df(x);+	if (d != 0.0) return (x-(f(x)/d)); 	return(x-1.0); 	} @@ -443,17 +399,15 @@ double d = (*df)(x); /* input function f and its derivative df, an interval */ /* left, right known to contain the root, and an error tolerance */ /* Based on Blinn */-double findroot(left, right, tolerance, f, df)-double left, right, tolerance;-double (*f)(), (*df)();+double findroot(double left, double right, double tolerance, double (*f)(double), double (*df)(double)) { double newx = left;-	while (ABS((*f)(newx)) > tolerance) {+	while (ABS(f(newx)) > tolerance) { 		newx = NewtonRaphson(f, df, newx); 		if (newx < left || newx > right)  			newx = RegulaFalsi(f, left, right);-		if ((*f)(newx) * (*f)(left) <= 0.0) right = newx;  +		if (f(newx) * f(left) <= 0.0) right = newx;   			else left = newx; 		} 	return(newx);-	} +	}diff --git a/libbirdgems/GraphicsGems.h b/libbirdgems/GraphicsGems.hindex 7928654..334a73f 100644--- a/libbirdgems/GraphicsGems.h+++ b/libbirdgems/GraphicsGems.h@@ -148,23 +148,23 @@ if (!(x)) fprintf(stderr," Assert failed: x\n"); typedef int boolean;			/* boolean data type */ typedef boolean flag;			/* flag data type */ -extern double V2SquaredLength(), V2Length();-extern double V2Dot(), V2DistanceBetween2Points(); -extern Vector2 *V2Negate(), *V2Normalize(), *V2Scale(), *V2Add(), *V2Sub();-extern Vector2 *V2Lerp(), *V2Combine(), *V2Mul(), *V2MakePerpendicular();-extern Vector2 *V2New(), *V2Duplicate();-extern Point2 *V2MulPointByMatrix();-extern Matrix3 *V2MatMul();--extern double V3SquaredLength(), V3Length();-extern double V3Dot(), V3DistanceBetween2Points();-extern Vector3 *V3Normalize(), *V3Scale(), *V3Add(), *V3Sub();-extern Vector3 *V3Lerp(), *V3Combine(), *V3Mul(), *V3Cross();-extern Vector3 *V3New(), *V3Duplicate();-extern Point3 *V3MulPointByMatrix();-extern Matrix4 *V3MatMul();--extern double RegulaFalsi(), NewtonRaphson(), findroot();+extern double V2SquaredLength(Vector2 *a), V2Length(Vector2 *a);+extern double V2Dot(Vector2 *a, Vector2 *b), V2DistanceBetween2Points(Point2 *a, Point2 *b);+extern Vector2 *V2Negate(Vector2 *v), *V2Normalize(Vector2 *v), *V2Scale(Vector2 *v, double newlen), *V2Add(Vector2 *a, Vector2 *b, Vector2 *c), *V2Sub(Vector2 *a, Vector2 *b, Vector2 *c);+extern Vector2 *V2Lerp(Vector2 *lo, Vector2 *hi, double alpha, Vector2 *result), *V2Combine(Vector2 *a, Vector2 *b, Vector2 *result, double ascl, double bscl), *V2Mul(Vector2 *a, Vector2 *b, Vector2 *result), *V2MakePerpendicular(Vector2 *a, Vector2 *ap);+extern Vector2 *V2New(double x, double y), *V2Duplicate(Vector2 *a);+extern Point2 *V2MulPointByMatrix(Point2 *p, Matrix3 *m);+extern Matrix3 *V2MatMul(Matrix3 *a, Matrix3 *b, Matrix3 *c);++extern double V3SquaredLength(Vector3 *a), V3Length(Vector3 *a);+extern double V3Dot(Vector3 *a, Vector3 *b), V3DistanceBetween2Points(Point3 *a, Point3 *b);+extern Vector3 *V3Normalize(Vector3 *v), *V3Scale(Vector3 *v, double newlen), *V3Add(Vector3 *a, Vector3 *b, Vector3 *c), *V3Sub(Vector3 *a, Vector3 *b, Vector3 *c);+extern Vector3 *V3Lerp(Vector3 *lo, Vector3 *hi, double alpha, Vector3 *result), *V3Combine(Vector3 *a, Vector3 *b, Vector3 *result, double ascl, double bscl), *V3Mul(Vector3 *a, Vector3 *b, Vector3 *result), *V3Cross(Vector3 *a, Vector3 *b, Vector3 *c);+extern Vector3 *V3New(double x, double y, double z), *V3Duplicate(Vector3 *a);+extern Point3 *V3MulPointByMatrix(Point3 *p, Matrix4 *m);+extern Matrix4 *V3MatMul(Matrix4 *a, Matrix4 *b, Matrix4 *c);++extern double RegulaFalsi(double (*f)(double), double left, double right), NewtonRaphson(double (*f)(double), double (*df)(double), double x), findroot(double left, double right, double tolerance, double (*f)(double), double (*df)(double));  #endif diff --git a/libbirdgems/fit_cubic.c b/libbirdgems/fit_cubic.cindex cda61f7..61172a9 100644--- a/libbirdgems/fit_cubic.c+++ b/libbirdgems/fit_cubic.c@@ -22,43 +22,46 @@ Adapted to BirdFont by Johan Mattsson 2015  #include "GraphicsGems.h" -#ifdef MAC-#include <malloc/malloc.h>-#else+#ifdef __linux__ #include <malloc.h>+#else+#include <stdlib.h> #endif  #include <math.h> #include <stdio.h> #include <glib.h> +typedef struct {+	int simplified_path_buffer_size ;+	int simplified_path_size;+	double* simplified_path;+} Buffer;  typedef Point2 *BezierCurve; -/* Forward declarations */-void		FitCurve();-static	void		FitCubic();-static	double		*Reparameterize();-static	double		NewtonRaphsonRootFind();-static	Point2		BezierII();-static	double 		B0(), B1(), B2(), B3();-static	Vector2		ComputeLeftTangent();-static	Vector2		ComputeRightTangent();-static	Vector2		ComputeCenterTangent();-static	double		ComputeMaxError();-static	double		*ChordLengthParameterize();-static	BezierCurve	GenerateBezier();-static	Vector2		V2AddII();-static	Vector2		V2ScaleIII();-static	Vector2		V2SubII();+/* Function declarations */+void FitCurve(Buffer* buffer, Point2* d, int nPts, double error);+static void FitCubic(Buffer* buffer, Point2* d, int first, int last, Vector2 tHat1, Vector2 tHat2, double error, int iterations);+static BezierCurve GenerateBezier(Point2* d, int first, int last, double* uPrime, Vector2 tHat1, Vector2 tHat2);+static double* Reparameterize(Point2* d, int first, int last, double* u, BezierCurve bezCurve);+static double NewtonRaphsonRootFind(BezierCurve Q, Point2 P, double u);+static Point2 BezierII(int degree, Point2* V, double t);+static double B0(double u);+static double B1(double u);+static double B2(double u);+static double B3(double u);+static Vector2 ComputeLeftTangent(Point2* d, int end);+static Vector2 ComputeRightTangent(Point2* d, int end);+static Vector2 ComputeCenterTangent(Point2* d, int center);+static double* ChordLengthParameterize(Point2* d, int first, int last);+static double ComputeMaxError(Point2* d, int first, int last, BezierCurve bezCurve, double* u, int* splitPoint);+static Vector2 V2AddII(Vector2 a, Vector2 b);+static Vector2 V2ScaleIII(Vector2 v, double s);+static Vector2 V2SubII(Vector2 a, Vector2 b);  #define MAXPOINTS	1000		/* The most points you can have */ -typedef struct {-	int simplified_path_buffer_size ;-	int simplified_path_size;-	double* simplified_path;-} Buffer;  Buffer* gems_buffer_new (int buffer_size, double* simplified_path) { 	Buffer* b = (Buffer*) malloc (sizeof (Buffer));@@ -86,6 +89,8 @@ void fit_bezier_curve_to_line ( 	Point2* points; 	int npoints; +	// FIXME: DELETE g_warning ("lines_size: %d\n", lines_size);+ 	if (lines_size % 2 != 0) { 		fprintf (stderr, "Odd number of coordinates in fit_bezier_curve_to_line.");		 		return;@@ -116,7 +121,7 @@ void fit_bezier_curve_to_line ( 		j += 2; 	} 	-	int buffer_size = 8 * lines_size;+	int buffer_size = 8 * (lines_size + 10); 	double* simplified_path = malloc (buffer_size * sizeof (double)); 	Buffer* buffer = gems_buffer_new (buffer_size, simplified_path); 	@@ -163,11 +168,7 @@ void DrawBezierCurve(Buffer* buffer, int n, Point2* curve)  *  FitCurve :  *  	Fit a Bezier curve to a set of digitized points   */-void FitCurve(buffer, d, nPts, error)-    Buffer* buffer;-    Point2	*d;			/*  Array of digitized points	*/-    int		nPts;		/*  Number of digitized points	*/-    double	error;		/*  User-defined error squared	*/+void FitCurve(Buffer* buffer, Point2* d, int nPts, double error) {     Vector2	tHat1, tHat2;	/*  Unit tangent vectors at endpoints */ @@ -179,14 +180,14 @@ void FitCurve(buffer, d, nPts, error) /*  *  FitCubic :  *  	Fit a Bezier curve to a (sub)set of digitized points+ *      Buffer* buffer;+ *      Point2	*d;			    Array of digitized points+ *      int		first, last;	Indices of first and last pts in region*+ *      Vector2	tHat1, tHat2;	Unit tangent vectors at endpoints + *      double	error;			User-defined error squared+ *      int iterations;  */-static void FitCubic(buffer, d, first, last, tHat1, tHat2, error, iterations)-    Buffer* buffer;-    Point2	*d;			/*  Array of digitized points */-    int		first, last;	/* Indices of first and last pts in region */-    Vector2	tHat1, tHat2;	/* Unit tangent vectors at endpoints */-    double	error;		/*  User-defined error squared	   */-    int iterations;+static void FitCubic(Buffer* buffer, Point2* d, int first, int last, Vector2 tHat1, Vector2 tHat2, double error, int iterations) {     BezierCurve	bezCurve; /*Control points of fitted Bezier curve*/     double	*u;		/*  Parameter values for point  */@@ -199,7 +200,7 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error, iterations)     Vector2	tHatCenter;   	/* Unit tangent vector at splitPoint */     int		i;		 -	if (iterations > 2000) {+	if (iterations > 500) { 		g_warning("Too many iterations."); 		return; 	}@@ -208,6 +209,8 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error, iterations)     iterationError = error * error;     nPts = last - first + 1; +	// g_warning ("FitCubic iterations: %d nPts: %d first: %d last: %d x: %f y: %f\n", iterations, nPts, first, last, tHat1.x, tHat1.y);+ 	if (nPts <= 1) { 		g_warning("nPts <= 1"); 		return;@@ -253,16 +256,17 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error, iterations) 	    	bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2); 	    	maxError = ComputeMaxError(d, first, last, 				       bezCurve, uPrime, &splitPoint);+					    	    	if (maxError < error) {-			DrawBezierCurve(buffer, 3, bezCurve);+				DrawBezierCurve(buffer, 3, bezCurve);+				free((void *)u);+				free((void *)bezCurve);+				free((void *)uPrime);+				return;+			} 			free((void *)u);-			free((void *)bezCurve);-			free((void *)uPrime);-			return;-	    }-	    free((void *)u);-	    u = uPrime;-	}+			u = uPrime;+		}     }      /* Fitting failed -- split at max error point and fit recursively */@@ -278,13 +282,12 @@ static void FitCubic(buffer, d, first, last, tHat1, tHat2, error, iterations) /*  *  GenerateBezier :  *  Use least-squares method to find Bezier control points for region.- *+ *      Point2	*d;			  	Array of digitized points+ *      int		first, last;	Indices defining region	+ *      double	*uPrime;		Parameter values for region + *      Vector2	tHat1, tHat2;	Unit tangents at endpoints	  */-static BezierCurve  GenerateBezier(d, first, last, uPrime, tHat1, tHat2)-    Point2	*d;			/*  Array of digitized points	*/-    int		first, last;		/*  Indices defining region	*/-    double	*uPrime;		/*  Parameter values for region */-    Vector2	tHat1, tHat2;	/*  Unit tangents at endpoints	*/+static BezierCurve GenerateBezier(Point2* d, int first, int last, double* uPrime, Vector2 tHat1, Vector2 tHat2) {     int 	i;     Vector2 	A[MAXPOINTS][2];	/* Precomputed rhs for eqn	*/@@ -385,12 +388,12 @@ static BezierCurve  GenerateBezier(d, first, last, uPrime, tHat1, tHat2)  *	Given set of points and their parameterization, try to find  *   a better parameterization.  *+ *     Point2	*d;			 	 Array of digitized points+ *     int		first, last;	 Indices defining region+ *     double	*u;				 Current parameter values+ *     BezierCurve	bezCurve;	 Current fitted curve  */-static double *Reparameterize(d, first, last, u, bezCurve)-    Point2	*d;			/*  Array of digitized points	*/-    int		first, last;		/*  Indices defining region	*/-    double	*u;			/*  Current parameter values	*/-    BezierCurve	bezCurve;	/*  Current fitted curve	*/+static double* Reparameterize(Point2* d, int first, int last, double* u, BezierCurve bezCurve) {     int 	nPts = last-first+1;	     int 	i;@@ -410,10 +413,10 @@ static double *Reparameterize(d, first, last, u, bezCurve)  *  NewtonRaphsonRootFind :  *	Use Newton-Raphson iteration to find better root.  */-static double NewtonRaphsonRootFind(Q, P, u)-    BezierCurve	Q;			/*  Current fitted curve	*/-    Point2 		P;		/*  Digitized point		*/-    double 		u;		/*  Parameter value for "P"	*/+// BezierCurve	Q;			/*  Current fitted curve	*/+// Point2 		P;		/*  Digitized point		*/+// double 		u;		/*  Parameter value for "P"	*/+static double NewtonRaphsonRootFind(BezierCurve Q, Point2 P, double u) {     double 		numerator, denominator;     Point2 		Q1[3], Q2[2];	/*  Q' and Q''			*/@@ -458,10 +461,10 @@ static double NewtonRaphsonRootFind(Q, P, u)  *  	Evaluate a Bezier curve at a particular parameter value  *   */-static Point2 BezierII(degree, V, t)-    int		degree;		/* The degree of the bezier curve	*/-    Point2 	*V;		/* Array of control points		*/-    double 	t;		/* Parametric value to find point for	*/+ // int		degree;		/* The degree of the bezier curve	*/+ // Point2 	*V;		/* Array of control points		*/+ // double 	t;		/* Parametric value to find point for	*/+static Point2 BezierII(int degree, Point2 *V, double t) {     int 	i, j;		     Point2 	Q;	        /* Point on curve at parameter t	*/@@ -492,30 +495,26 @@ static Point2 BezierII(degree, V, t)  *  B0, B1, B2, B3 :  *	Bezier multipliers  */-static double B0(u)-    double	u;+static double B0(double u) {     double tmp = 1.0 - u;     return (tmp * tmp * tmp); }  -static double B1(u)-    double	u;+static double B1(double u) {     double tmp = 1.0 - u;     return (3 * u * (tmp * tmp)); } -static double B2(u)-    double	u;+static double B2(double u) {     double tmp = 1.0 - u;     return (3 * u * u * tmp); } -static double B3(u)-    double	u;+static double B3(double u) {     return (u * u * u); }@@ -526,9 +525,7 @@ static double B3(u)  * ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent :  *Approximate unit tangents at endpoints and "center" of digitized curve  */-static Vector2 ComputeLeftTangent(d, end)-    Point2	*d;			/*  Digitized points*/-    int		end;		/*  Index to "left" end of region */+static Vector2 ComputeLeftTangent(Point2* d, int end) {     Vector2	tHat1;     tHat1 = V2SubII(d[end+1], d[end]);@@ -536,9 +533,7 @@ static Vector2 ComputeLeftTangent(d, end)     return tHat1; } -static Vector2 ComputeRightTangent(d, end)-    Point2	*d;			/*  Digitized points		*/-    int		end;		/*  Index to "right" end of region */+static Vector2 ComputeRightTangent(Point2* d, int end) {     Vector2	tHat2;     tHat2 = V2SubII(d[end-1], d[end]);@@ -547,9 +542,7 @@ static Vector2 ComputeRightTangent(d, end) }  -static Vector2 ComputeCenterTangent(d, center)-    Point2	*d;			/*  Digitized points			*/-    int		center;		/*  Index to point inside region	*/+static Vector2 ComputeCenterTangent(Point2* d, int center) {     Vector2	V1, V2, tHatCenter; @@ -567,9 +560,7 @@ static Vector2 ComputeCenterTangent(d, center)  *	Assign parameter values to digitized points   *	using relative distances between points.  */-static double *ChordLengthParameterize(d, first, last)-    Point2	*d;			/* Array of digitized points */-    int		first, last;		/*  Indices defining region	*/+static double* ChordLengthParameterize(Point2* d, int first, int last) {     int		i;	     double	*u;			/*  Parameterization		*/@@ -599,20 +590,17 @@ static double *ChordLengthParameterize(d, first, last)     return(u); } --- /*  *  ComputeMaxError :  *	Find the maximum squared distance of digitized points  *	to fitted curve. */-static double ComputeMaxError(d, first, last, bezCurve, u, splitPoint)-    Point2	*d;			/*  Array of digitized points	*/-    int		first, last;		/*  Indices defining region	*/-    BezierCurve	bezCurve;		/*  Fitted Bezier curve		*/-    double	*u;			/*  Parameterization of points	*/-    int		*splitPoint;		/*  Point of maximum error	*/+// Point2	*d;			/*  Array of digitized points	*/+// int		first, last;		/*  Indices defining region	*/+// BezierCurve	bezCurve;		/*  Fitted Bezier curve		*/+// double	*u;			/*  Parameterization of points	*/+// int		*splitPoint;		/*  Point of maximum error	*/+static double ComputeMaxError(Point2* d, int first, int last, BezierCurve bezCurve, double* u, int* splitPoint) {     int		i;     double	maxDist;		/*  Maximum error		*/@@ -633,27 +621,22 @@ static double ComputeMaxError(d, first, last, bezCurve, u, splitPoint)     }     return (maxDist); }-static Vector2 V2AddII(a, b)-    Vector2 a, b;+static Vector2 V2AddII(Vector2 a, Vector2 b) {     Vector2	c;     c.x = a.x + b.x;  c.y = a.y + b.y;     return (c); }-static Vector2 V2ScaleIII(v, s)-    Vector2	v;-    double	s;+static Vector2 V2ScaleIII(Vector2 v, double s) {     Vector2 result;     result.x = v.x * s; result.y = v.y * s;     return (result); } -static Vector2 V2SubII(a, b)-    Vector2	a, b;+static Vector2 V2SubII(Vector2 a, Vector2 b) {     Vector2	c;     c.x = a.x - b.x; c.y = a.y - b.y;     return (c); }-

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112