平滑曲线算法:HotPoints方法

在计算机图形学中,平滑曲线的生成是一个常见且重要的任务。传统的平滑曲线方法包括使用插值或逼近技术,如NURBS、样条曲线、Cattmull-Rom、Chaikin或贝塞尔曲线,以及一些过滤技术。本文介绍的HotPoints方法是一种基于不同逻辑的近似方法,其输出结果与Chaikin方法非常相似。

HotPoints方法的核心逻辑可以通过逐步插图来解释。如果重复执行这些步骤至少3次迭代循环,将得到一个平滑的曲线。这种方法的算法质量非常满意。

如所见,主要问题或有趣的点在于如何找到绿色点的坐标。如何计算它们?现在,让回到大学时代,回忆一些几何主题,如直线、圆、椭圆等。

实际上,Q点可以沿着对角线移动,但当F点和Q点垂直时,可以得到最佳结果。

经过一些数学运算和消除后,最终可以使用以下公式计算Q点的笛卡尔坐标:

F := 1.0; // F: 0.0 .. 2.0 dx := p2.X - p1.X; dy := p2.Y - p1.Y; // a: 主轴,b: 副轴 a := dx / 2.82843; // 2*2^0.5 = 2.82843 b := dy / 2.82843; // O: 中/中心点 Ox := (P1.X + P2.X) / 2.0; Oy := (P1.Y + P2.Y) / 2.0; Q1.X := Ox - F * a / 1.41421; // sqrt(2) = 1.41421 Q1.y := Oy - F * b / 1.41421; Q2.X := Ox + F * a / 1.41421; Q2.y := Oy + F * b / 1.41421;

使用代码

让用代码来引导!

////////////////////////////////////////// // HotPoints近似 //////////////////////////////////////////// // 计算热点 for i:=0 to nItera-1 do begin k := 0; for j:=0 to nPoints-1 do begin j0 := (j+0 + nPoints) mod nPoints; // 循环形式 j1 := (j+1 + nPoints) mod nPoints; p1.X := trunc(pinn[j0].X + 0.5); p1.Y := trunc(pinn[j0].Y + 0.5); p2.X := trunc(pinn[j1].X + 0.5); p2.Y := trunc(pinn[j1].Y + 0.5); dx := p2.X - p1.X; dy := p2.Y - p1.Y; radiX := dx / 2.82843; // 2 * 2^0.5 = 2.82843 radiY := dy / 2.82843; // Ox := (P1.X + P2.X) / 2.0; Oy := (P1.Y + P2.Y) / 2.0; Q1.X := Ox - F * radiX / 1.41421; // sqrt(2) = 1.41421 Q1.y := Oy - F * radiY / 1.41421; pout[k] := Q1; k := k + 1; Q2.X := Ox + F * radiX / 1.41421; Q2.y := Oy + F * radiY / 1.41421; pout[k] := Q2; k := k + 1; end; // j nPoints := k; for k:=0 to nPoints-1 do pinn[k] := pout[k]; // !!! end; // 迭代,i // 绘制曲线 for k:=0 to nPoints-1 do begin X := trunc(pout[k].X + 0.5); Y := trunc(pout[k].Y + 0.5); if (k = 0) then imgDraw.Canvas.MoveTo(X, Y) else imgDraw.Canvas.LineTo(X, Y); end;

这是描述步骤的中间运行状态:

比较

为了比较,请参阅下面的Chaikin和HotPoints的结果。它们看起来几乎相同。

注:原始测试点是从上述(*)文章中借用的。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485