#endif
}
-static int Q3PatchTesselation(float largestsquared2xcurvearea, float tolerance)
+static int Q3PatchTesselation(float largestsquared3xcurvearea, float tolerance)
{
float f;
// f is actually a squared 2x curve area... so the formula had to be adjusted to give roughly the same subdivisions
- f = pow(largestsquared2xcurvearea / 64.0, 0.25) / tolerance;
+ f = pow(largestsquared3xcurvearea / 64.0, 0.25) / tolerance;
//if(f < 0.25) // VERY flat patches
if(f < 0.0001) // TOTALLY flat patches
return 0;
// maps [4..8[ to 4
}
-float Squared2xCurveArea(const float *a, const float *control, const float *b, int components)
+float Squared3xCurveArea(const float *a, const float *control, const float *b, int components)
{
#if 0
// mimicing the old behaviour with the new code...
// but as this is hard to calculate, let's calculate an upper bound of it:
// the area of the triangle a->control->b->a.
//
+ // one can prove that the area of a quadratic spline = 2/3 * the area of
+ // the triangle of its control points!
+ // to do it, first prove it for the spline through (0,0), (1,1), (2,0)
+ // (which is a parabola) and then note that moving the control point
+ // left/right is just shearing and keeps the area of both the spline and
+ // the triangle invariant.
+ //
// why are we going for the spline area anyway?
// we know that:
//
//
// also, on circle-like or parabola-like curves, you easily get that the
// double amount of line approximation segments reduces the error to its quarter
+ // (also, easy to prove for splines by doing it for one specific one, and using
+ // affine transforms to get all other splines)
//
// so...
//
bb += xb * xb;
}
// area is 0.5 * sqrt(aa*bb - ab*ab)
- // 2x area is sqrt(aa*bb - ab*ab)
+ // 2x TRIANGLE area is sqrt(aa*bb - ab*ab)
+ // 3x CURVE area is sqrt(aa*bb - ab*ab)
return aa * bb - ab * ab;
#endif
}
{
int x, y;
const float *patch;
- float squared2xcurvearea, largestsquared2xcurvearea;
- largestsquared2xcurvearea = 0;
+ float squared3xcurvearea, largestsquared3xcurvearea;
+ largestsquared3xcurvearea = 0;
for (y = 0;y < patchheight;y++)
{
for (x = 0;x < patchwidth-1;x += 2)
{
patch = in + ((y * patchwidth) + x) * components;
- squared2xcurvearea = Squared2xCurveArea(&patch[0], &patch[components], &patch[2*components], components);
- if (largestsquared2xcurvearea < squared2xcurvearea)
- largestsquared2xcurvearea = squared2xcurvearea;
+ squared3xcurvearea = Squared3xCurveArea(&patch[0], &patch[components], &patch[2*components], components);
+ if (largestsquared3xcurvearea < squared3xcurvearea)
+ largestsquared3xcurvearea = squared3xcurvearea;
}
}
- return Q3PatchTesselation(largestsquared2xcurvearea, tolerance);
+ return Q3PatchTesselation(largestsquared3xcurvearea, tolerance);
}
// returns how much tesselation of each segment is needed to remain under tolerance
{
int x, y;
const float *patch;
- float squared2xcurvearea, largestsquared2xcurvearea;
- largestsquared2xcurvearea = 0;
+ float squared3xcurvearea, largestsquared3xcurvearea;
+ largestsquared3xcurvearea = 0;
for (y = 0;y < patchheight-1;y += 2)
{
for (x = 0;x < patchwidth;x++)
{
patch = in + ((y * patchwidth) + x) * components;
- squared2xcurvearea = Squared2xCurveArea(&patch[0], &patch[patchwidth*components], &patch[2*patchwidth*components], components);
- if (largestsquared2xcurvearea < squared2xcurvearea)
- largestsquared2xcurvearea = squared2xcurvearea;
+ squared3xcurvearea = Squared3xCurveArea(&patch[0], &patch[patchwidth*components], &patch[2*patchwidth*components], components);
+ if (largestsquared3xcurvearea < squared3xcurvearea)
+ largestsquared3xcurvearea = squared3xcurvearea;
}
}
- return Q3PatchTesselation(largestsquared2xcurvearea, tolerance);
+ return Q3PatchTesselation(largestsquared3xcurvearea, tolerance);
}
// Find an equal vertex in array. Check only vertices with odd X and Y