draw bezier bug

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply

Is this really a bug with IM bezier curves?

yes
1
100%
no
0
No votes
don't know
0
No votes
 
Total votes: 1

User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Post by magick »

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);
}
Post Reply