在 Pocket PC 上绘制三次贝塞尔样条






3.50/5 (6投票s)
用于在 Pocket PC 上绘制贝塞尔曲线的函数。因为它们在 Pocket PC 的 GDI 中缺失。
引言
当我开始为 Pocket PC 编写 CAD 应用程序时,我很快发现 Pocket PC 上的 GDI 与普通的 Windows GDI 相比有所限制。我需要绘制样条曲线。因此,我尝试在网上找到一个简单易用的算法,但没有找到有用的东西。
我查找了有关贝塞尔曲线的信息,因为 Windows 上的 GDI 使用的是贝塞尔曲线,我想要一个替代函数。在阅读了 Donald Hern 和 M. Pauline baker 的书 计算机图形学 之后,我理解了贝塞尔曲线的工作原理。
那么它是如何工作的?
提供的代码使用三次贝塞尔曲线,它接受四个控制点,并使用四个混合函数生成曲线
- f1(u) = (1 - u)³
- f2(u) = 3u(1 - u)²
- f3(u) = 3u²(1 - u)
- f4(u) = u³
其中 0 <= u <= 1
下面显示了计算曲线上点的函数。fPoint
只是一个 struct
,包含两个 float
类型的数据 x
和 y
。将混合函数与控制点相乘,然后加到 pDstPoint
上。
void BezierComputePoint(float fU, fPoint* pDstPoint, CPoint* pSrcPoints) { // // Add up all the blending functions multiplied with the control points // float fBlend; float f1subu = 1.0f - fU; // // First blending function (1-u)^3 // fBlend = f1subu * f1subu * f1subu; pDstPoint->x = fBlend * pSrcPoints[0].x; pDstPoint->y = fBlend * pSrcPoints[0].y; // // Second blending function 3u(1-u)^2 // fBlend = 3 * fU * f1subu * f1subu; pDstPoint->x += fBlend * pSrcPoints[1].x; pDstPoint->y += fBlend * pSrcPoints[1].y; // // Third blending function 3u^2 * (1-u) // fBlend = 3 * fU * fU * f1subu; pDstPoint->x += fBlend * pSrcPoints[2].x; pDstPoint->y += fBlend * pSrcPoints[2].y; // // Fourth blending function u^3 // fBlend = fU * fU * fU; pDstPoint->x += fBlend * pSrcPoints[3].x; pDstPoint->y += fBlend * pSrcPoints[3].y; }
下一个代码片段显示了 DrawBezier
函数。它接受一个 CDC
指针作为输入,四个控制点以及样条曲线应被分割成的段数。您使用的段数越多,结果越好,但这会花费更多的时间。因此,最好进行实验以获得最佳结果。
遍历所有段,生成曲线上一个点。在先前点和计算出的点之间绘制一条线。最后,绘制一条线到终点。
void DrawBezier(CDC *pDC, CPoint *pPoints, int nSegments) { pDC->MoveTo(pPoints[0]); fPoint fPointBezier; for(int i = 0; i < nSegments; i++) { BezierComputePoint(i / (float)nSegments, &fPointBezier, pPoints); pDC->LineTo(ROUND(fPointBezier.x), ROUND(fPointBezier.y)); } pDC->LineTo(pPoints[3]); }
使用代码
在您的项目中包含 Bezier.h 并调用这些函数。请查看示例项目以获取提示。我使用 PPC 2003 进行测试,但它不应该与旧的 PPC SDK 存在问题。
就这样!希望对您有所帮助。欢迎提出评论和建设性的批评。
历史
2005-03-15 - 首次发布。