由给定的点计算Bezier曲线

 

//计算 Bezier curve
//cpt 端点及控制点
//cn cpt的数量
//st 准备计算多少步
//pXY, X,Y的坐标输出
BOOL CalBezier(POINT cpt[], int cn, int st, POINT *pXY)
{
  int r,i,k;
  double t, t1;
  double coeffx[20], coeffy[20];

  int n = min(cn, 20);

  for(k=0; k<st; k++)
  {
    t= k/(st - 1.0);  t1 = 1-t;
    
    for(i=0;i<n;i++)
    {
      coeffx[i] = cpt[i].x;
      coeffy[i] = cpt[i].y;
    }

    for(r=1;r<n;r++)
    {
      for(i=0;i<n-r;i++)
      {
        coeffx[i]= t1*coeffx[i] + t*coeffx[i+1];
        coeffy[i]= t1*coeffy[i] + t*coeffy[i+1];      
      }
    }

    pXY[k].x = (LONG)coeffx[0];
    pXY[k].y = (LONG)coeffy[0];
  }

  return (TRUE);
}

 

void CSDIView::OnDraw(CDC* pDC)
{
  CSDIDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);
  if (!pDoc)
    return;

  CPen pen(PS_SOLID, 3, RGB(255, 0, 0));
  CPen *pOldPen = pDC->SelectObject(&pen);

  POINT cpt[] = 
  {{50, 400},  {140, 20},  {400, 40},  {600, 400} };
  
  //按3000步计算
  int k = 3000;
  POINT *pxy = new POINT[k];  
  CalBezier(cpt, 4, k, pxy);
  for(int i=0; i<k;i++)
  {
    if(i==0)
      pDC->MoveTo(pxy[i]);
    else
      pDC->LineTo(pxy[i]);
  }
  delete [] pxy;

  //使用GDIPolyBezier绘制对比
  CPen pen2(PS_SOLID, 1, RGB(0, 255, 0));
  pDC->SelectObject(&pen2);
  pDC->PolyBezier(cpt, 4);
  
  pDC->SelectObject(pOldPen);


}

从2阶到7阶的贝赛尔曲线 private static final int MAX_COUNT = 7; // 贝塞尔曲线最大阶数 private static final int REGION_WIDTH = 30; // 合法区域宽度 private static final int FINGER_RECT_SIZE = 60; // 矩形尺寸 private static final int BEZIER_WIDTH = 10; // 贝塞尔曲线线宽 private static final int TANGENT_WIDTH = 6; // 切线线宽 private static final int CONTROL_WIDTH = 12; // 控制连线线宽 private static final int CONTROL_RADIUS = 12; // 控制半径 private static final int TEXT_SIZE = 40; // 文字画笔尺寸 private static final int TEXT_HEIGHT = 60; // 文本高度 private static final int RATE = 10; // 移动速率 private static final int HANDLER_WHAT = 100; private static final int FRAME = 1000; // 1000帧 private static final String[] TANGENT_COLORS = {"#7fff00", "#7a67ee", "#ee82ee", "#ffd700", "#1c86ee", "#8b8b00"}; // 切线颜色 private static final int STATE_READY = 0x0001; private static final int STATE_RUNNING = 0x0002; private static final int STATE_STOP = 0x0004; private static final int STATE_TOUCH = 0x0010; private Path mBezierPath = null; // 贝塞尔曲线路径 private Paint mBezierPaint = null; // 贝塞尔曲线画笔 private Paint mMovingPaint = null; // 移动画笔 private Paint mControlPaint = null; // 控制画笔 private Paint mTangentPaint = null; // 切线画笔 private Paint mLinePaint = null; // 固定线画笔 private Paint mTextPointPaint = null; // 画笔 private Paint mTextPaint = null; // 文字画笔 private ArrayList mBezierPoints = null; // 贝塞尔曲线集 private PointF mBezierPoint = null; // 贝塞尔曲线移动 private ArrayList mControlPoints = null; // 控制集 private ArrayList<ArrayList<ArrayList>> mTangentPoints; // 切线集 private ArrayList<ArrayList> mInstantTangentPoints; private int mR = 0; // 移动速率 private int mRate = RATE; // 速率 private int mState; // 状态 private boolean mLoop = false; // 设置是否循环 private boolean mTangent = true; // 设置是否显示切线 private int mWidth = 0, mHe
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值