由给定的点计算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);


}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
从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: De Casteljau算法是一种用于绘制Bezier曲线的算法。该算法通过递归地将Bezier曲线分割成更小的曲线段,直到达到所需的精度。具体步骤如下: 1. 给定Bezier曲线的控制P,P1,P2,...,Pn。 2. 将曲线分割成两个子曲线,其中第一个子曲线由控制P,P1,...,Pn-1定义,第二个子曲线由控制P1,P2,...,Pn定义。 3. 对于每个子曲线计算其上的Q(t),其中t是参数值,范围为到1。 4. 重复步骤2和3,直到达到所需的精度。 5. 最终,将所有子曲线连接起来,形成Bezier曲线。 De Casteljau算法是一种简单而有效的方法,可用于绘制各种形状的Bezier曲线。 ### 回答2: de Casteljau算法是一种用来绘制Bezier曲线的方法。这个算法首先将Bezier曲线的控制分割成两部分,然后用分割后的控制来绘制两个新的Bezier曲线。这个过程一直重复,直到只剩下一个为止。 假设我们有一个二次Bezier曲线,它有3个控制P0、P1、P2。要用de Casteljau算法绘制这个曲线,我们需要先将它分割成两个小曲线。我们可以将它分割成P0、Q0、R0三个图形: ![image.png](https://cdn.nlark.com/yuque/0/2022/png/234131/1642565190637-19a7dff5-4c48-4cbb-94c5-744e03edf7e9.png) 然后我们可以用这三个绘制一条新的曲线,并将其分割成两个更小的曲线。我们可以将这些新的标记为S0和T0: ![image.png](https://cdn.nlark.com/yuque/0/2022/png/234131/1642565205969-4f4e41d8-fd09-49e3-a0cc-c24e4df17c48.png) 我们可以继续这个过程,分割剩余的两个曲线,得到更小的曲线,最终得到只剩下一个曲线。这个就是Bezier曲线的终。 de Casteljau算法的优是它只需要计算一小部分的曲线,然后将它们组合在一起。这个方法不仅用于绘制二次Bezier曲线,也可以用于其他阶数的Bezier曲线。通过绘制分割后的曲线,我们可以轻松地将Bezier曲线分割成任意数量的曲线段。 总结来说,de Casteljau算法是一种简单易懂的Bezier曲线绘制方法,它可以将一个曲线分割成多个小曲线,从而减少了计算量和绘制时间。 ### 回答3: De Casteljau方法是一种用来绘制贝塞尔曲线的算法。 贝塞尔曲线是一种数学上的曲线,它由多个与控制权值组合构成,被广泛应用于图形学、计算机辅助设计等领域中。 De Casteljau算法的核心思想是将贝塞尔曲线依次分解为多条小曲线,每条小曲线都是由相邻的和中间的控制所构成。 具体的步骤如下: 1. 将所有的按照参数t依次重复,其中参数t的值从0开始,每次加上0.1或0.01或0.001或0.0001或其他看实际需要。 2. 将相邻两个的坐标之间的连线所得到的线段作为临时的曲线的一部分。其中,起和终都是原始的贝塞尔曲线上的。 3. 对相邻的线段进行插值操作,得到新的作为中间控制,并再次进行插值操作,得到两条曲线,继续进行拆分。 4. 递归上述操作,直到所有的线段都被划分成很小的部分为止。此时,用相邻曲线的交来连接这些小曲线,得到最终的贝塞尔曲线。 De Casteljau算法通过递归的方式将曲线切分成多个小的曲线段,从而更好地控制贝塞尔曲线的形状和起伏,在计算机制图等领域中使用非常广泛。在实际应用中,通过改变控制的位置和权值,可以产生非常多种不同的贝塞尔曲线,从而制作出精细的图形。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值