Posted: 2006-04-17T15:56:24-07:00
Below is code to generate the bezier curves as short-segmented polys. Take a look and let us know if you spot any bugs:
Code: Select all
static inline MagickRealType Permutate(const long n,const long k)
{
MagickRealType
r;
register long
i;
r=1.0;
for (i=k+1; i <= n; i++)
r*=i;
for (i=1; i <= (n-k); i++)
r/=i;
return(r);
}
static void TraceBezier(PrimitiveInfo *primitive_info,
const unsigned long number_coordinates)
{
MagickRealType
alpha,
*coefficients,
weight;
PointInfo
end,
point,
*points;
register long
i,
j;
register PrimitiveInfo
*p;
unsigned long
control_points,
quantum;
/*
Allocate coeficients.
*/
quantum=number_coordinates;
for (i=0; i < (long) number_coordinates; i++)
{
for (j=i+1; j < (long) number_coordinates; j++)
{
alpha=fabs(primitive_info[j].point.x-primitive_info[i].point.x);
if (alpha > (MagickRealType) quantum)
quantum=(unsigned long) alpha;
alpha=fabs(primitive_info[j].point.y-primitive_info[i].point.y);
if (alpha > (MagickRealType) quantum)
quantum=(unsigned long) alpha;
}
}
quantum=Min(quantum/number_coordinates,BezierQuantum);
control_points=quantum*number_coordinates;
coefficients=(MagickRealType *)
AcquireMagickMemory((size_t) number_coordinates*sizeof(*coefficients));
points=(PointInfo *)
AcquireMagickMemory((size_t) control_points*sizeof(*points));
if ((coefficients == (MagickRealType *) NULL) ||
(points == (PointInfo *) NULL))
{
char
*message;
message=GetExceptionMessage(errno);
ThrowMagickFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",message);
message=(char *) RelinquishMagickMemory(message);
}
/*
Compute bezier points.
*/
end=primitive_info[number_coordinates-1].point;
weight=0.0;
for (i=0; i < (long) number_coordinates; i++)
coefficients[i]=Permutate((long) number_coordinates-1,i);
for (i=0; i < (long) control_points; i++)
{
p=primitive_info;
point.x=0.0;
point.y=0.0;
alpha=pow((double) (1.0-weight),(double) number_coordinates-1);
for (j=0; j < (long) number_coordinates; j++)
{
point.x+=alpha*coefficients[j]*p->point.x;
point.y+=alpha*coefficients[j]*p->point.y;
alpha*=weight/(1.0-weight);
p++;
}
points[i]=point;
weight+=1.0/quantum/number_coordinates;
}
/*
Bezier curves are just short segmented polys.
*/
p=primitive_info;
for (i=0; i < (long) control_points; i++)
{
TracePoint(p,points[i]);
p+=p->coordinates;
}
TracePoint(p,end);
p+=p->coordinates;
primitive_info->coordinates=(unsigned long) (p-primitive_info);
for (i=0; i < (long) primitive_info->coordinates; i++)
{
p->primitive=primitive_info->primitive;
p--;
}
points=(PointInfo *) RelinquishMagickMemory(points);
coefficients=(MagickRealType *) RelinquishMagickMemory(coefficients);
}