溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

AGG第十八課 agg::trans_affine仿射變換

發(fā)布時(shí)間:2020-06-27 02:54:11 來源:網(wǎng)絡(luò) 閱讀:987 作者:fengyuzaitu 欄目:系統(tǒng)運(yùn)維

1 affine仿射變換概念

在幾何上定義為兩個(gè)向量空間之間的一個(gè)仿射變換或者仿射映射(來自拉丁語,affinis,"和。..相關(guān)")由一個(gè)線性變換接上一個(gè)平移組成。

2  agg::trans_affine成員函數(shù)說明

2.1 縮放

inline const trans_affine&trans_affine::scale(double x, double y)

參數(shù)一對(duì)x橫坐標(biāo)的縮放系數(shù),參數(shù)二對(duì)y縱坐標(biāo)的縮放系數(shù)

這里有一個(gè)問題:就是圖形的縮放之后,并不是在原有的位置上,進(jìn)行縮放,而是整體的縮放,比如最明顯的是圓形,圓心的位置發(fā)生了改變,所以需要進(jìn)行平移,恢復(fù)到以前的圓心。

2.2 旋轉(zhuǎn)

inline const trans_affine&trans_affine::rotate(double a)

參數(shù)對(duì)圖形進(jìn)行旋轉(zhuǎn),旋轉(zhuǎn)的圓心是坐標(biāo)的原點(diǎn)(0,0,也就是顯示界面的左上角,和一般的笛卡爾坐標(biāo)不一樣的地方,Y軸的縱坐標(biāo)進(jìn)行了翻轉(zhuǎn),Y軸向下逐漸增大。

應(yīng)用注意事項(xiàng):參數(shù)采用的是弧度的形式,至于弧度(radians)和角度(degrees)之間的區(qū)別,請(qǐng)參考其他的章節(jié),不再贅述。所以該參數(shù)的范圍是[-pi,pi].pi = 3.141592653.正值表示順時(shí)針旋轉(zhuǎn),負(fù)值逆時(shí)針旋轉(zhuǎn),旋轉(zhuǎn)的中心對(duì)稱點(diǎn)是(0,0),切記??!很可能會(huì)旋轉(zhuǎn)到界面之外。

Tips:角度轉(zhuǎn)弧度agg::deg2rad(doubledegrees)

2.3 平移

inline const trans_affine&trans_affine::translate(double x, double y)

 參數(shù)一,X軸平移量,參數(shù)二,Y軸平移量

關(guān)于仿射變換的數(shù)學(xué)知識(shí)

本文不打算描述trans_affine仿射變換的基本原理,其中的代碼在agg_trans_affine.h文件中定義,涉及到的六個(gè)仿射變量如下:

double sx, shy, shx, sy, tx, ty;

可以搜索仿射變換的基本原理。

一些測(cè)試實(shí)例

4.1 旋轉(zhuǎn)出界面

實(shí)例代碼如下:

   ras.reset();

   agg::ellipse ell(400,400,20,70);

   //坐標(biāo)轉(zhuǎn)換

   agg::trans_affine mtx;

   //mtx.scale(0.5,1); //x軸縮小到原來的一半

   mtx.rotate(agg::deg2rad(30));//旋轉(zhuǎn)30

   //mtx.translate(200,200);//XY坐標(biāo)分別平移100

   typedef agg::conv_transform<agg::ellipse> ell_ct_type;

   ell_ct_type ctell(ell,mtx); //矩陣變換

   ras.add_path(ctell);

   agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));

   ras.reset();

 

這是網(wǎng)上最經(jīng)典的一個(gè)使用例子,但是并沒有說明旋轉(zhuǎn)是如何實(shí)現(xiàn)的,稍微修改了一下代碼:

  mtx.rotate(agg::deg2rad(60));//旋轉(zhuǎn)60

結(jié)果:發(fā)現(xiàn)界面上什么也沒有,橢圓不見了??!

原因:順時(shí)針旋轉(zhuǎn)出界面。

 

4.2 通過滑動(dòng)條查看旋轉(zhuǎn)的過程

 void RotateEclipse()

  {

//關(guān)于agg::slider_ctrl<agg::rgba8>的基本使用,請(qǐng)參考其他的章節(jié)

   int value = m_slider1.value();//取值

   agg::rendering_buffer &rbuf = rbuf_window();

   agg::pixfmt_bgr24 pixf(rbuf);

   typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type;

   renderer_base_type renb(pixf);

 

 

   agg::rasterizer_scanline_aa<> ras;

   agg::scanline_u8 sl;

    ren_bas.clear(agg::rgba8(255,255,255));

   agg::trans_affine mtx;

   //mtx.scale(0.5,0.5); //x軸縮小到原來的一半

   mtx.rotate(agg::deg2rad(value));//旋轉(zhuǎn)30

   //mtx.translate(100 ,100);//XY坐標(biāo)分別平移100

 

   agg::ellipse ell(900,900,20,30);

   typedef agg::conv_transform<agg::ellipse> ell_ct_type;

   ell_ct_type ctell(ell,mtx); //矩陣變換

 

   ras.reset();

   ras.add_path(ctell);

   agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));

   agg::render_ctrl(ras, sl, renb, m_slider1);

 

  }

 

5版本差異以及具體應(yīng)用

1AGG2.3版本

目前已經(jīng)很難下載到,早期的項(xiàng)目有應(yīng)用到,沒有繼續(xù)更新??!

如下代碼對(duì)矩形進(jìn)行縮放:

 ras.reset();

 agg::path_storage ps;

 ps.move_to(30,30);

 ps.line_to(50,30);

 ps.line_to(50,50);

 ps.line_to(30,50);

 ps.line_to(30,30);

 

 agg::trans_affine mtx;

  //橫坐標(biāo)放大2倍,縱坐標(biāo)放大3

  mtx*= agg::trans_affine_scaling(2, 3);

  //橫坐標(biāo)平移100,縱坐標(biāo)平移300,正數(shù)向右,負(fù)數(shù)向左

  mtx*=agg::trans_affine_translation(100,100);

 typedefagg::conv_transform<agg::path_storage> ell_ct_type;

 ell_ct_type ctell(ps,mtx); //矩陣變換

 

 typedef agg::conv_stroke<ell_ct_type>ell_cc_cs_type;

  ell_cc_cs_typecsccell(ctell);

 ras.add_path(ctell);

2AGG2.4/2.5版本

   agg::trans_affine mtx;

   mtx.scale(0.5,0.5); //x軸縮小到原來的一半

   mtx.rotate(agg::deg2rad(40));//旋轉(zhuǎn)30

   mtx.translate(100 ,100);//X,Y坐標(biāo)分別平移100

   typedefagg::conv_transform<agg::path_storage> ell_ct_type;

   ell_ct_type ctell(ps,mtx); //矩陣變換

 

   typedef agg::conv_stroke<ell_ct_type>ell_cc_cs_type;

   ell_cc_cs_type csccell(ctell);

   ras.add_path(csccell);

摘自agg_trans_affine.h的翻譯

在笛卡爾坐標(biāo)系中(Cartesian coordinates)仿射轉(zhuǎn)換(affine transformation)是一種線性的轉(zhuǎn)換(在一開始的時(shí)候就設(shè)定了)。她們可以自由的旋轉(zhuǎn)(rotation,縮放(scaling,平移(translation)和剪切變換(skewing.經(jīng)過任意的仿射變換,線段仍然是線段,她永遠(yuǎn)不可能編程一根曲線。

一言以蔽之,任何的矩陣變換都可以用一系列的離散變換實(shí)現(xiàn)。

原文如下:

  //============================================================trans_affine

   //

   // See Implementation agg_trans_affine.cpp

   //

   // Affine transformation are lineartransformations in Cartesiancoordinates

   // (strictly speaking not only inCartesian, but for the beginning wewill

   // think so). They are rotation, scaling,translation and skewing.

   // After any affine transformation a linesegment remains a line segment

   // and it will never become a curve.

   //

   // There will be no math about matrixcalculations, since it has been

   // described many times. Ask yourself avery simple question:

   // "why do we need to understand anduse some matrix stuff insteadof just

   // rotating, scaling and so on". Theanswers are:

   //

   // 1. Any combination of transformationscan be done by only 4multiplications

   //   and 4 additions in floatingpoint.

   // 2. One matrix transformation isequivalent to the number ofconsecutive

   //   discrete transformations,i.e. the matrix "accumulates" alltransformations

   //   in the order of theirsettings. Suppose we have 4 transformations:

   //      * rotate by 30 degrees,

   //      * scale X to 2.0,

   //      * scale Y to 1.5,

   //      * move to (100, 100).

   //   The result will depend on theorder of these transformations,

   //   and the advantage of matrixis that the sequence of discret calls:

   //   rotate(30), scaleX(2.0),scaleY(1.5), move(100,100)

   //   will have exactly the sameresult as the following matrixtransformations:

   // 

   //   affine_matrix m;

   //   m *= rotate_matrix(30);

   //   m *= scaleX_matrix(2.0);

   //   m *= scaleY_matrix(1.5);

   //   m *= move_matrix(100,100);

   //

   //  m.transform_my_point_at_last(x, y);

   //

   // What is the good of it? In real life wewill set-up the matrix onlyonce

   // and then transform many points, letalone the convenience to set any

   // combination of transformations.

   //

   // So, how to use it? Very easy - literallyas it's shown above. Notquite,

   // let us write a correct example:

   //

   // agg::trans_affine m;

   // m *= agg::trans_affine_rotation(30.0 *3.1415926 / 180.0);

   // m *= agg::trans_affine_scaling(2.0,1.5);

   // m *=agg::trans_affine_translation(100.0, 100.0);

   // m.transform(&x, &y);

   //

   // The affine matrix is all you need toperform any lineartransformation,

   // but all transformations have originpoint (0,0). It means that we needto

   // use 2 translations if we want to rotatesometing around (100,100):

   //

   // m *= agg::trans_affine_translation(-100.0,-100.0);         // move to (0,0)

   // m *= agg::trans_affine_rotation(30.0 *3.1415926 / 180.0);  // rotate

   // m *=agg::trans_affine_translation(100.0, 100.0);           // move back to (100,100)

   //----------------------------------------------------------------------

 


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI