OpenCASCADE Conic to BSpline Curves-Hyperbola

eryar@163.com

Abstract. Rational Bezier Curve can represent conic curves such as circle, ellipse, hyperbola, .etc. But how to convert a conic curve to BSpline curve is still question, i.e. Represent a conic curve in BSpline form. The key point of Hyperbola conversion is to calculate the 2nd pole and its weight factor. The paper focus on the hyperbola convert to the BSpline curves.

Key Words. OpenCASCADE, Convert, Hyperbola, BSplineCurve, Conic Curve

1. Introduction

圆锥截线(Conic或称为二次曲线)和圆在CAD/CAM中有着广泛应用。毫无疑问NURBS的一个最大优点就是既能精确表示圆锥截线和圆,也能精确表示自由曲线曲面。这个优点的意义是方便编程,使所有的曲线可以采用统一的数据结构来表示。通过有理的方式可以精确来表示这些二次曲线,那么给定一个二次曲线的相关参数(如圆的圆心和半径等),如何构造出对应的NURBS曲线呢?

圆锥截线(Conic curves)是一个平面与一个圆锥相交产生的曲线集合。平面与圆锥相交的角度不同产生不同的截线。如下图所示:

Figure 1.1 Conic Sections

OpenCASCADE中对应双曲线的隐式方程表示的类是gp_Hypr/gp_Hypr2d。本文主要介绍OpenCASCADE中如何使用包Convert将gp_Parab2d转换为NURBS曲线。

2. Parametric Representations

在CAD/CAM的应用中,圆锥截线有两种重要的参数表示形式:有理形式和最大内接面积形式(Rational and maximum inscribed area forms)。表示双曲线的最大内接面积形式,如下所示:

其中chu和shu为双曲函数:

圆锥截线的有些有理参数表示形式可能是有相当差的参数化,即均匀分布的参数值对应于曲线上分布很不均匀的点。利用线性有理函数对有理曲线进行重新参数化可以改变(因而可能改善)其参数化。

假设C(u)=(x(u), y(u))是一条在标准位置的圆锥截线的参数表示。现在我们对双曲线给出的参数方程也是上式,它是一个好的参数化:对于任意给定的整数n和参数边界a与b,取n个等间隔分布的参数:

点C(u1),C(u2), ..., C(un)形成曲线上n-1边多边形,它的闭合多边形具有最大的内接面积。

3. Conversion Algorithm

将隐式表示的双曲线方程转换为NURBS(有理Bezier是NURBS的特例)曲线需要确定NURBS的以下信息:节点矢量,权因子,次数,控制顶点。

圆锥截线是二次曲线,所以次数为2。根据参数方程的最大内接面积表示法可以求出节点矢量。所以转换的关键是计算控制第二个顶点及其权因子。由有理Bezier曲线的公式得二次有理Bezier曲线弧的表示形式为:

称k为形状不变因子,公式如下所示:

可以证明同一组控制顶点选取不同 的权因子,只要形状因子k相等,则由它们决定的二次有理Bezier曲线是同一条曲线段,不同的权因对应不同的参数化,而且可以根据形状不变因子对二次曲线进行分类:

v K=0;       表示退化的二次曲线:一对直线段P0P1和P1P2;

v K∈[0,1];  表示双曲线;

v K=1;       表示抛物线;

v K∈[1, +∞]; 表示椭圆;

v K=+∞;     表示连接P0和P2的直线段;

习惯上我们选择ω0=ω2=1称为标准参数化。此时只剩下控制顶点P1的权因子ω1。

Figure 3.1 不同的权因子ω1 定义的圆锥截线

由二次有理Bezier曲线公式可知,当u=0和u=1时,C(0)=P0, C(1)=P2,即曲线通过特征多边形的首末顶点。由此可确定抛物线的两个控制顶点P0和P2,现在只剩下最后一个P1顶点未确定。

由端点处的切矢公式可知,控制多边形通过首末端点且第二个控制顶点P1是通过两端点的切线的交点。根据直接线点向式可以列出直线方程来求出交点即P1点的坐标。

计算得交点P1的坐标如下所示:

根据双曲线的参数方程得:

将上述值代入交点坐标公式得交点P1的坐标与参数u的关系式为:

根据肩点公式及点P1,可计算出权因子的ω1值,公式如下所示:

求得P1点对应的权因子ω1的值为:

至此,双曲线的三个控制顶点P0,P1,P2都已计算出来了。即双曲线的NURBS表示所需的数据都已经得到了。下面看看OpenCASCADE中的实现代码。

4. Code Analysis

OpenCASCADE的Math工具集中有个包Covert用来将圆锥曲线曲面转换为NURBS曲线曲面。其中转换双曲线的类为:Convert_HyperbolaToBSplineCurve,实现代码如下所示:

  1. //=======================================================================
  2. //function : Convert_HyperbolaToBSplineCurve
  3. //purpose :
  4. //=======================================================================
  5.  
  6. Convert_HyperbolaToBSplineCurve::Convert_HyperbolaToBSplineCurve
  7. (const gp_Hypr2d& H ,
  8. const Standard_Real U1,
  9. const Standard_Real U2 )
  10.  
  11. : Convert_ConicToBSplineCurve (MaxNbPoles, MaxNbKnots, TheDegree)
  12. {
  13. Standard_DomainError_Raise_if( Abs(U2 - U1) < Epsilon(.),
  14. "Convert_ParabolaToBSplineCurve");
  15.  
  16. Standard_Real UF = Min (U1, U2);
  17. Standard_Real UL = Max( U1, U2);
  18.  
  19. nbPoles = ;
  20. nbKnots = ;
  21. isperiodic = Standard_False;
  22. knots->ChangeArray1()() = UF; mults->ChangeArray1()() = ;
  23. knots->ChangeArray1()() = UL; mults->ChangeArray1()() = ;
  24.  
  25. // construction of hyperbola in the reference xOy.
  26.  
  27. Standard_Real R = H.MajorRadius();
  28. Standard_Real r = H.MinorRadius();
  29. gp_Dir2d Ox = H.Axis().XDirection();
  30. gp_Dir2d Oy = H.Axis().YDirection();
  31. Standard_Real S = ( Ox.X() * Oy.Y() - Ox.Y() * Oy.X() > .) ? : -;
  32.  
  33. // poles expressed in the reference mark
  34. // the 2nd pole is at the intersection of 2 tangents to the curve
  35. // at points P(UF), P(UL)
  36. // the weight of this pole is equal to : Cosh((UL-UF)/2)
  37.  
  38. weights->ChangeArray1()() = .;
  39. weights->ChangeArray1()() = Cosh((UL-UF)/);
  40. weights->ChangeArray1()() = .;
  41.  
  42. Standard_Real delta = Sinh(UL-UF);
  43. Standard_Real x = R * ( Sinh(UL) - Sinh(UF)) / delta;
  44. Standard_Real y = S * r * ( Cosh(UL) - Cosh(UF)) / delta;
  45. poles->ChangeArray1()() = gp_Pnt2d( R * Cosh(UF), S * r * Sinh(UF));
  46. poles->ChangeArray1()() = gp_Pnt2d( x, y);
  47. poles->ChangeArray1()() = gp_Pnt2d( R * Cosh(UL), S * r * Sinh(UL));
  48.  
  49. // replace the bspline in the mark of the hyperbola
  50. gp_Trsf2d Trsf;
  51. Trsf.SetTransformation( H.Axis().XAxis(), gp::OX2d());
  52. poles->ChangeArray1()().Transform( Trsf);
  53. poles->ChangeArray1()().Transform( Trsf);
  54. poles->ChangeArray1()().Transform( Trsf);
  55. }

由上面的代码可知,先设置曲线次数为2,再设置节点矢量为[UF,UF,UF,UL,UL,UL],即首参数UF和末参数UL的重数皆为3,由节点矢量可知转换后的NURBS曲线为Bezier曲线。(抛出异常的提示信息还没改过来,还是抛物线的。)

设置三个控制顶点及其对应的权因子,计算主要涉及到第二个控制顶点P1的权因子。

最后根据有理Bezier曲线的仿射不变性:对有理Bezier曲线进行旋转、平移和缩放变换,其表达式不变,只是控制点发生了改变。新的控制点可以通过对原控制点作变换得到。即要对有理Bezier曲线进行仿射变换,只需对其控制点作变换即可。

圆锥截线的转换类的使用是很简单的,且计算都是在构造函数中完成。下面给出一个将双曲线转换为NURBS曲线的具体示例来说明其用法。

  1. /*
  2. * Copyright (c) 2014 eryar All Rights Reserved.
  3. *
  4. * File : Main.cpp
  5. * Author : eryar@163.com
  6. * Date : 2014-10-06 20:46
  7. * Version : 1.0v
  8. *
  9. * Description : OpenCASCADE conic to BSpline curve-Hyperbola.
  10. *
  11. * Key words : OpenCascade, Hyperbola, BSpline Curve, Convert
  12. */
  13.  
  14. #define WNT
  15. #include <gp_Hypr2d.hxx>
  16.  
  17. #include <Convert_HyperbolaToBSplineCurve.hxx>
  18.  
  19. #pragma comment(lib, "TKernel.lib")
  20. #pragma comment(lib, "TKMath.lib")
  21.  
  22. void DumpConvertorInfo(const Convert_ConicToBSplineCurve &theConvertor)
  23. {
  24. std::cout << "Degree: " << theConvertor.Degree() << std::endl;
  25.  
  26. std::cout << "Poles/Weights: " << std::endl;
  27. for (Standard_Integer i = ; i <= theConvertor.NbPoles(); ++i)
  28. {
  29. const gp_Pnt2d &aPole = theConvertor.Pole(i);
  30.  
  31. std::cout << i << ": " << aPole.X() << ", " << aPole.Y() << " w(" << theConvertor.Weight(i) << ")" << std::endl;
  32. }
  33.  
  34. std::cout << "Knots: " << std::endl;
  35. for (Standard_Integer j = , m = ; j <= theConvertor.NbKnots(); ++j)
  36. {
  37. for (Standard_Integer k = ; k <= theConvertor.Multiplicity(j); ++k)
  38. {
  39. std::cout << ++m << ": " << theConvertor.Knot(j) << std::endl;
  40. }
  41. }
  42.  
  43. std::cout << "==========================================" << std::endl;
  44. }
  45.  
  46. void TestHyperbolaConvert(void)
  47. {
  48. gp_Hypr2d aHyperbola;
  49.  
  50. aHyperbola.SetMajorRadius(2.0);
  51. aHyperbola.SetMinorRadius(1.0);
  52.  
  53. Convert_HyperbolaToBSplineCurve aConvertor(aHyperbola, 1.0, M_PI);
  54.  
  55. std::cout << "Convert Hyperbola to BSpline Curve: " << std::endl;
  56. DumpConvertorInfo(aConvertor);
  57. }
  58.  
  59. int main(int argc, char* argv[])
  60. {
  61. TestHyperbolaConvert();
  62.  
  63. return ;
  64. }

程序输出结果如下所示:

Figure 4.1 Convert Hyperbola to BSpline Curve result

5. Conclusion

NURBS的一个优势就是统一了曲线曲面的表示方法,即不仅可以表示自由曲线曲面,还可精确表示圆锥曲线曲面。本文详细介绍了OpenCASCADE中将双曲线转换为NURBS的算法:即根据二次有理Bezier曲线的端点性质,求出过两个端点切线的交点来计算出第二个控制顶点P1进而计算出对应的权因子。

计算中大量使用到了双曲函数shx和chx的一些性质,相关公式可参考《数学手册》。

6. References

1. 人民教育出版社中学数学室. 数学第二册(上). 人民教育出版社. 2000

2. 数学手册编写组. 数学手册. 高等教育出版社. 1979

3. 赵罡,穆国旺,王拉柱译. 非均匀有理B样条. 清华大学出版社. 2010

4. 王仁宏,李崇君,朱春钢. 计算几何教程. 科学出版社. 2008

OpenCASCADE Conic to BSpline Curves-Hyperbola的更多相关文章

  1. OpenCASCADE Conic to BSpline Curves-Parabola

    OpenCASCADE Conic to BSpline Curves-Parabola eryar@163.com Abstract. Rational Bezier Curve can repre ...

  2. OpenCASCADE Conic to BSpline Curves-Circle

    OpenCASCADE Conic to BSpline Curves-Circle eryar@163.com Abstract. The conic sections and circles pl ...

  3. B-spline Curves 学习前言与动机(1)

    B-spline Curves 学习之前言 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. (原来博客网址:http:// ...

  4. B-spline Curves 学习之B样条曲线的移动控制点、修改节点分析(7)

    B-spline Curves: Moving Control Points 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习 ...

  5. B-spline Curves 学习之B样条曲线的系数计算与B样条曲线特例(6)

    B-spline Curves: Computing the Coefficients 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关 ...

  6. B-spline Curves 学习之B样条曲线性质(5)

    B-spline Curves: Important Properties 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. ...

  7. B-spline Curves 学习之B样条曲线定义(4)

    B-spline Curves: Definition 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. (原来博客网址:h ...

  8. B-spline Curves 学习之B样条基函数的定义与性质(2)

    B-spline Basis Functions 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. (原来博客网址:http ...

  9. B-spline Curves 学习之B样条曲线的导数(8)

    Derivatives of a B-spline Curve 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. (原来博客 ...

随机推荐

  1. 【HDU2222】Keywords Search AC自动机

    [HDU2222]Keywords Search Problem Description In the modern time, Search engine came into the life of ...

  2. Android 利用RecyclerView.Adapter刷新列表中的单个view问题

    首先使用RecyclerView的adapter继承:RecyclerView.Adapter public class OrderListAdapter extends RecyclerView.A ...

  3. PHP_SELF、 SCRIPT_NAME、 REQUEST_URI区别

    $_SERVER[PHP_SELF], $_SERVER[SCRIPT_NAME], $_SERVER['REQUEST_URI'] 在用法上是非常相似的,他们返回的都是与当前正在使用的页面地址有关的 ...

  4. RDLC报表数据工具栏关闭后打开方法

    显示方法为:Ctrl + Alt + D 快捷键 只做自己记录用

  5. json相关的一些用法

    一. json可以表示3种类型的值:   简单值 . 对象. 数组    表示对象时:>1. 没有变量的概念 ,所以不用申明变量                    >2. 没有末尾结束 ...

  6. 【转】零基础学习Fiddler抓包改包

    看到一篇讲关于Fiddler抓包工具的讲解,个人感觉写得很仔细,但是作者说禁止转载,那就放个链接Mark一下 http://tmq.qq.com/2016/12/fiddler_packet_capt ...

  7. Daily Scrum02 12.13

    之前由于编译的第二次审查,大家又紧张地忙了一阵,调Bug的调Bug,换文法的换文法,双十二的会议也停了一次,给大家完成数据库大作业留一个缓冲的时间.但是我们的进度还要继续抓紧啊!! Member 任务 ...

  8. ZK 样式使用

    控件: <textbox id="usernameTb" sclass="login-user-input" placeholder="账号&q ...

  9. 比achartengine更加强大的Android图表控件。

    比achartengine更加强大的图表控件MPAndroidChart. 详细使用及demo:http://www.see-source.com/androidwidget/detail.html? ...

  10. eclipse插件开发入门

    2016-09-09 17:11:50 1. 概述 1.1 SWT/JFace 是Eclipse 的基础,Eclipse 的 Workbench 就是建立在 SWT/JFace 之上的.另外,JFac ...