贝塞尔曲线绘制

时间:2022-05-12 05:48:47

 

  

#include <math.h>
//计算阶乘
double Cal_Factorial(int n)
{
  double fFactorial = 1;
  for(int i=2; i<=n; i++)
    fFactorial *= i;
  return fFactorial;
}

//贝塞尔实现
BOOL _PolyBezier(HDC hDC, //目标DC
  const POINT* lpPoints, int nCount, //曲线控制点
  LPPOINT ptOrg=NULL) //DC原始坐标
{
  int i, n = nCount - 1;
  double *fNi = new double[nCount];

  //(n i) = n!/(i!*(n-i)!)
  for(i=0; i<nCount; i++)
  {
    fNi[i] = Cal_Factorial(n) / Cal_Factorial(i) / Cal_Factorial(n - i);
  }

  MoveToEx(hDC, lpPoints[0].x, lpPoints[0].y, ptOrg);

  for(double t=0; t <= 1.0; t+=1E-3)
  {
    double fx = 0, fy=0;
    for(i=0; i<nCount; i++)
    {
      double fRate = fNi[i] * pow(t, i) * pow(1-t, n-i);
      fx += fRate * lpPoints[i].x;
      fy += fRate * lpPoints[i].y;
    }

    LineTo(hDC, (int)fx, (int)fy);
    Sleep(1);
  }

  delete []fNi;

  return TRUE;
}


//测试代码

  case WM_PAINT:
    {
      HDC hdc;
      PAINTSTRUCT ps;
      hdc=::BeginPaint(hwnd,&ps);

      const POINT ptArray[] = { {100, 100}, {200, 500}, {370, 50}, {400, 500}  };
      for(int i=0; i<_countof(ptArray); i++)
      {
        MoveToEx(hdc, ptArray[i].x-5, ptArray[i].y, NULL);
        LineTo(hdc, ptArray[i].x+5, ptArray[i].y);
        MoveToEx(hdc, ptArray[i].x, ptArray[i].y-5, NULL);
        LineTo(hdc, ptArray[i].x, ptArray[i].y+5);
      }
      _PolyBezier(hdc, ptArray, _countof(ptArray));

      ::EndPaint(hwnd,&ps);
      return 0;
    }

 

输出结果
贝塞尔曲线绘制