亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

OpenCASCADE Conic to BSpline Curves-Parabola

系統(tǒng) 1984 0

OpenCASCADE Conic to BSpline Curves-Parabola

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. Parabola curve is the most simple conic curve, that the parabola does not require rational functions. Let’s begin from the simplest one...?

Key Words. OpenCASCADE, Convert, Parabola, BSplineCurve, Conic Curve?

1. Introduction

圓錐截線(Conic或稱為二次曲線)和圓在CAD/CAM中有著廣泛應用。毫無疑問NURBS的一個最大優(yōu)點就是既能精確表示圓錐截線和圓,也能精確表示自由曲線曲面。這個優(yōu)點的意義是方便編程,使所有的曲線可以采用統(tǒng)一的數(shù)據(jù)結(jié)構(gòu)來表示。通過有理的方式可以精確來表示這些二次曲線,那么給定一個二次曲線的相關(guān)參數(shù)(如圓的圓心和半徑等),如何構(gòu)造出對應的NURBS曲線呢??

在圓錐截線中,拋物線(Parabola)是不需要用有理函數(shù)來表示的,所以是形式最簡單的二次曲線。先從簡單的著手,來學習如何將一個拋物線從隱式方程的形式轉(zhuǎn)換成NURBS曲線形式。?

先簡要回顧一下高中數(shù)學中關(guān)于拋物線的相關(guān)知識點,如下圖所示為我上高中時數(shù)學課本中的關(guān)于拋物線方程及焦點坐標(focus)和準線(directrix)方程一個圖表:?

wps_clip_image-23523

Figure 1.1 Parabola Fuction?

OpenCASCADE中對應拋物線的隱式方程表示的類是gp_Parab/gp_Parab2d。本文主要介紹OpenCASCADE中如何將gp_Parab2d轉(zhuǎn)換為NURBS曲線。?

2. Parametric Representations

在CAD/CAM的應用中,圓錐截線有兩種重要的參數(shù)表示形式:有理形式和最大內(nèi)接面積形式(Rational and maximum inscribed area forms)。表示拋物線的這兩種形式是相同的,如下所示:?

wps_clip_image-28078

圓錐截線的有些有理參數(shù)表示形式可能是有相當差的參數(shù)化,即均勻分布的參數(shù)值對應于曲線上分布很不均勻的點。利用線性有理函數(shù)對有理曲線進行重新參數(shù)化可以改變(因而可能改善)其參數(shù)化。?

假設(shè)C(u)=(x(u), y(u))是一條在標準位置的圓錐截線的參數(shù)表示。現(xiàn)在我們對拋物線給出的參數(shù)方程也是上式,它是一個好的參數(shù)化:對于任意給定的整數(shù)n和參數(shù)邊界a與b,取n個等間隔分布的參數(shù):?

wps_clip_image-14708

點C(u1),C(u2), ..., C(un)形成曲線上n-1邊多邊形,它的閉合多邊形具有最大的內(nèi)接面積。?

根據(jù)最大內(nèi)接面積表示法可以求出節(jié)點矢量。?

3. Conversion Algorithm

將隱式表示的拋物線方程轉(zhuǎn)換為NURBS(有理Bezier是NURBS的特例)曲線需要確定NURBS的以下信息:節(jié)點矢量,權(quán)因子,次數(shù),控制頂點。?

因為拋物線是二次曲線,所以對應的NURBS曲線的次數(shù)也為2。因為是用有理的Bezier曲線來表示的,所以需要的控制頂點數(shù)為3。?

其中節(jié)點矢量可由最大內(nèi)接面積表示法來確定。下面來確定剩余的所需數(shù)據(jù)。由有理Bezier曲線的公式得二次有理Bezier曲線弧的表示形式為:?

wps_clip_image-7907

稱k為形狀不變因子,公式如下所示:?

wps_clip_image-28613

可以證明同一組控制頂點選取不同 的權(quán)因子,只要形狀因子k相等,則由它們決定的二次有理Bezier曲線是同一條曲線段,不同的權(quán)因?qū)煌膮?shù)化,而且可以根據(jù)形狀不變因子對二次曲線進行分類:?

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

v K∈[0,1];? 表示雙曲線;?

v K=1;?????? 表示拋物線;?

v K∈[1, +∞]; 表示橢圓;?

v K=+∞;???? 表示連接P0和P2的直線段;?

習慣上我們選擇ω0=ω2=1稱為標準參數(shù)化。此時由形狀因子k公式得拋物線的ω1=1。所以拋物線的權(quán)因子也因此而確定,即ω0=ω1=ω2=1。?

wps_clip_image-10048

Figure 3.1 不同的權(quán)因子ω1 定義的圓錐截線?

由二次有理Bezier曲線公式可知,當u=0和u=1時,C(0)=P0, C(1)=P2,即曲線通過特征多邊形的首末頂點。由此可確定拋物線的兩個控制頂點P0和P2,現(xiàn)在只剩下最后一個P1頂點未確定。?

P1點可以由二次有理Bezier曲線的公式列方程計算得出,但這并不是一個方便的方法。一種更方便的方法是:在這條曲線上指定第三個點,該點對應于某個特定的參數(shù),例如u=1/2。點S=C(1/2)稱為圓錐截線的肩點(shoulder point),如圖3.1所示。將u=1/2代入二次有理Bezier公式得:?

wps_clip_image-14682

其中M是弦P0P2的中點。肩點S=C(1/2)。所以由上式可確定P1點。下面將各個控制頂點的計算列出如下所示:?

設(shè)拋物線的起止區(qū)間為[UF,UL],則因為曲線通過特征多邊形的頂點,所以通過首點P0=(X0,Y0)=(X0,UF)。又由拋物線的參數(shù)方程可知:?

wps_clip_image-29846

同理可計算出通過末點P2的坐標,將他們分別列出如下:?

wps_clip_image-23736

由計算肩點S的公式,將Sy=Y(jié)1=C(u1)=(UF+UL)/2代入可得:?

wps_clip_image-19329

所以P1點的坐標為:?

wps_clip_image-27527

至此,拋物線的三個控制頂點P0,P1,P2都已計算出來了。即拋物線的NURBS表示所需的數(shù)據(jù)都已經(jīng)得到了。下面看看OpenCASCADE中的實現(xiàn)代碼。?

4. Code Analysis

OpenCASCADE的Math工具集中有個包Covert用來將圓錐曲線曲面轉(zhuǎn)換為NURBS曲線曲面。其中轉(zhuǎn)換拋物線的類為:Convert_ParabolaToBSplineCurve,實現(xiàn)代碼如下所示:?

      
        //
      
      
        =======================================================================


      
      
        //
      
      
        function : Convert_ParabolaToBSplineCurve


      
      
        //
      
      
        purpose  : 


      
      
        //
      
      
        =======================================================================
      
      
        Convert_ParabolaToBSplineCurve::Convert_ParabolaToBSplineCurve 

  (
      
      
        const
      
       gp_Parab2d&
      
           Prb,

   
      
      
        const
      
      
         Standard_Real U1 ,

   
      
      
        const
      
      
         Standard_Real U2  )

: Convert_ConicToBSplineCurve (MaxNbPoles, MaxNbKnots, TheDegree) 

{

  Standard_DomainError_Raise_if( Abs(U2 
      
      - U1) < Epsilon(
      
        0
      
      
        .),

                
      
      
        "
      
      
        Convert_ParabolaToBSplineCurve
      
      
        "
      
      
        );



  Standard_Real UF 
      
      =
      
         Min (U1, U2);

  Standard_Real UL 
      
      =
      
         Max( U1, U2);

  Standard_Real p 
      
      =
      
         Prb.Parameter();



  nbPoles 
      
      = 
      
        3
      
      
        ;

  nbKnots 
      
      = 
      
        2
      
      
        ;

  isperiodic 
      
      =
      
         Standard_False;

  knots
      
      ->ChangeArray1()(
      
        1
      
      ) = UF;  mults->ChangeArray1()(
      
        1
      
      ) = 
      
        3
      
      
        ;

  knots
      
      ->ChangeArray1()(
      
        2
      
      ) = UL;  mults->ChangeArray1()(
      
        2
      
      ) = 
      
        3
      
      
        ;



 weights
      
      ->ChangeArray1()(
      
        1
      
      ) = 
      
        1
      
      
        .;

 weights
      
      ->ChangeArray1()(
      
        2
      
      ) = 
      
        1
      
      
        .;

 weights
      
      ->ChangeArray1()(
      
        3
      
      ) = 
      
        1
      
      
        .;



  gp_Dir2d Ox 
      
      =
      
         Prb.Axis().XDirection();

  gp_Dir2d Oy 
      
      =
      
         Prb.Axis().YDirection();

  Standard_Real S 
      
      = ( Ox.X() * Oy.Y() - Ox.Y() * Oy.X() > 
      
        0
      
      .) ?  
      
        1
      
       : -
      
        1
      
      
        ;



  
      
      
        //
      
      
         poles expressed in the reference mark
      
      

  poles->ChangeArray1()(
      
        1
      
      ) =
      
         

    gp_Pnt2d( ( UF 
      
      * UF) / ( 
      
        2
      
      . * p), S *
      
           UF            );

  poles
      
      ->ChangeArray1()(
      
        2
      
      ) =
      
         

    gp_Pnt2d( ( UF 
      
      * UL) / ( 
      
        2
      
      . * p), S * ( UF + UL) / 
      
        2
      
      
        . );

  poles
      
      ->ChangeArray1()(
      
        3
      
      ) =
      
         

    gp_Pnt2d( ( UL 
      
      * UL) / ( 
      
        2
      
      . * p), S *
      
           UL            );



  
      
      
        //
      
      
         replace the bspline in the mark of the parabola
      
      
          gp_Trsf2d Trsf;

  Trsf.SetTransformation( Prb.Axis().XAxis(), gp::OX2d());

  poles
      
      ->ChangeArray1()(
      
        1
      
      
        ).Transform( Trsf);

  poles
      
      ->ChangeArray1()(
      
        2
      
      
        ).Transform( Trsf);

  poles
      
      ->ChangeArray1()(
      
        3
      
      
        ).Transform( Trsf);

}
      
    

由上面的代碼可知,先設(shè)置曲線次數(shù)為2,再設(shè)置節(jié)點矢量為[UF,UF,UF,UL,UL,UL],即首參數(shù)UF和末參數(shù)UL的重數(shù)皆為3,由節(jié)點矢量可知轉(zhuǎn)換后的NURBS曲線為Bezier曲線。?

三個控制頂點對應的權(quán)因也都設(shè)置為1。三個控制頂點計算方法按上一節(jié)中所述。關(guān)鍵是P1點的計算。上面的計算方法僅為個人觀點,歡迎討論交流。?

最后根據(jù)有理Bezier曲線的仿射不變性:對有理Bezier曲線進行旋轉(zhuǎn)、平移和縮放變換,其表達式不變,只是控制點發(fā)生了改變。新的控制點可以通過對原控制點作變換得到。即要對有理Bezier曲線進行仿射變換,只需對其控制點作變換即可。?

圓錐截線的轉(zhuǎn)換類的使用是很簡單的,且計算都是在構(gòu)造函數(shù)中完成。下面給出一個將拋物線轉(zhuǎn)換為NURBS曲線的具體示例來說明其用法。?

      
        /*
      
      
        

*    Copyright (c) 2014 eryar All Rights Reserved.

*

*        File    : Main.cpp

*        Author  : eryar@163.com

*        Date    : 2014-10-02 20:46

*        Version : 1.0v

*

*    Description : OpenCASCADE conic to BSpline curve-Parabola.

*

*      Key words : OpenCascade, Parabola, BSpline Curve, Convert


      
      
        */
      
      
        #define
      
       HAVE_CONFIG_H
      
        



#include 
      
      <gp_Parab2d.hxx>
      
        



#include 
      
      <Convert_ParabolaToBSplineCurve.hxx>




      
        void
      
       DumpConvertorInfo(
      
        const
      
       Convert_ConicToBSplineCurve &
      
        theConvertor)

{

    Standard_Integer aCounter 
      
      = 
      
        0
      
      
        ;

    

    std::cout 
      
      << 
      
        "
      
      
        Convert Result
      
      
        "
      
       <<
      
         std::endl;

    std::cout 
      
      << 
      
        "
      
      
        Degree: 
      
      
        "
      
       << theConvertor.Degree() <<
      
         std::endl;

    std::cout 
      
      << 
      
        "
      
      
        Periodic: 
      
      
        "
      
       << (theConvertor.IsPeriodic() ? 
      
        "
      
      
        yes
      
      
        "
      
       : 
      
        "
      
      
        no
      
      
        "
      
      ) <<
      
         std::endl;

    

    std::cout 
      
      << 
      
        "
      
      
        Knots: 
      
      
        "
      
       <<
      
         std::endl;

    
      
      
        for
      
       (Standard_Integer i = 
      
        1
      
      ;i <= theConvertor.NbKnots(); ++
      
        i)

    {

        
      
      
        for
      
       (Standard_Integer j = 
      
        1
      
      ; j <= theConvertor.Multiplicity(i); ++
      
        j)

        {

            std::cout 
      
      << ++aCounter << 
      
        "
      
      
        : 
      
      
        "
      
       << theConvertor.Knot(i) <<
      
         std::endl;

        }

    }

    

    std::cout 
      
      << 
      
        "
      
      
        Poles(Weight): 
      
      
        "
      
       <<
      
         std::endl;

    
      
      
        for
      
       (Standard_Integer i = 
      
        1
      
      ; i <= theConvertor.NbPoles(); ++
      
        i)

    {

        gp_Pnt2d aPole 
      
      =
      
         theConvertor.Pole(i);

        

        std::cout 
      
      << i << 
      
        "
      
      
        : 
      
      
        "
      
       << aPole.X() << 
      
        "
      
      
        , 
      
      
        "
      
       <<
      
         aPole.Y() 

        
      
      << 
      
        "
      
      
         W(
      
      
        "
      
       << theConvertor.Weight(i) << 
      
        "
      
      
        )
      
      
        "
      
       <<
      
         std::endl;

    }

}




      
      
        void
      
       TestParabolaConversion(
      
        void
      
      
        )

{

    gp_Parab2d aParabola(gp::OX2d(), 
      
      
        1.0
      
      
        );

    

    Convert_ParabolaToBSplineCurve aConvertor(aParabola, 
      
      
        1.0
      
      
        , M_PI);

    

    DumpConvertorInfo(aConvertor);

}




      
      
        int
      
       main(
      
        int
      
       argc, 
      
        char
      
       **
      
        argv)

{

    TestParabolaConversion();

    

    
      
      
        return
      
      
        0
      
      
        ;

}
      
    

程序開始部分需要定義HAVE_CONFIG_H,這與在Windows中編程定義WNT有所不同。程序輸出結(jié)果如下圖所示:?

wps_clip_image-24708

Figure 4.1 Convert Parabola to BSpline Curve Result?

5. Conclusion

NURBS的一個優(yōu)勢就是統(tǒng)一了曲線曲面的表示方法,即不僅可以表示自由曲線曲面,還可精確表示圓錐曲線曲面。其中拋物線是最簡單的圓錐截線,從簡單的拋物線轉(zhuǎn)換成NURBS曲線著手,學習NURBS是如何來表示圓錐截線的。?

第一次使用Debian系統(tǒng)來編程,選用了一個輕量級的IDE開發(fā)工具Codelite,用法與Visual Studio類似。期間也遇到包含引用目錄及程序運行時找不到動態(tài)庫的問題。其中在Codelite中添加引用庫路徑的方法如下圖所示:?

wps_clip_image-29650

Figure 5.1 Set Library Path and Add Libraries in Codelite?

添加上述引用庫后,解決了鏈接錯誤,但是直接運行程序,發(fā)現(xiàn)也有與在Windows中類似的問題,即缺少依賴的動態(tài)庫,如下圖所示為使用lld命令檢查程序的依賴項。最后通過向ld.so.conf中添加動態(tài)庫所在的目錄解決了問題。相關(guān)命令如下所示:

#?cat? / etc / ld.so.conf?
include?ld.so.conf.d /* .conf?
#?echo?"/home/eryar/opencascade-6.7.1/lib"?>>?/etc/ld.so.conf?
#?ldconfig?

注:以上命令需要有root權(quán)限。?

wps_clip_image-20163

Figure 5.2 Use lld command to check depends?

通過解決以上的問題,來適應在Debian中使用Codelite開發(fā)程序。?

6. References

1. 人民教育出版社中學數(shù)學室. 數(shù)學第二冊(上). 人民教育出版社. 2000?

2. 趙罡,穆國旺,王拉柱譯. 非均勻有理B樣條. 清華大學出版社. 2010?

3. 王仁宏,李崇君,朱春鋼. 計算幾何教程. 科學出版社. 2008

OpenCASCADE Conic to BSpline Curves-Parabola


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品视频在线免费观看 | 日韩va亚洲va欧美va浪潮 | 日韩欧国产精品一区综合无码 | 亚拍精品一区二区三区 | 青草青青在线视频 | 国产成人啪精品 | 国产美女在线观看 | 91色综合久久| 久久精品中文字幕一区 | a在线观看免费 | 97久久人人| 久久福利一区二区三区 | 99精品国产高清自在线看超 | 狠狠干天天爽 | 国产成人精品s8sp视频 | 久久99久久99精品免观看不卡 | 成人网18免费视频 | 日本亚洲成高清一区二区三区 | 91精品国产露脸在线 | 天天操中文字幕 | 精品国产乱码一区二区三区麻豆 | 四虎2020 | 久久99国产精品久久99无号码 | 色综合中文字幕天天在线 | 成人亚洲欧美日韩在线观看 | 四虎精品视频在线永久免费观看 | 老司机免费福利视频无毒午夜 | 中文日韩字幕 | 香蕉视频免费看 | 亚洲国产欧美日韩 | 四虎免费在线播放 | 色婷婷色综合缴情在线 | 一区亚洲 | 国产视频一区二 | 成人国产欧美精品一区二区 | 久久精品国产亚洲麻豆 | 中文字幕无线码中文字幕免费 | 久久久久综合中文字幕 | 免费福利视频网站 | 免费 高清 日本1在线观看 | 伊人不卡久久大香线蕉综合影院 |