<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      <泛> C++3D數學庫設計詳解 向量篇

      // 注:本內容為作者原創,禁止在其他網站復述內容以及用于商業盈利,如需引用,請標明出處:http://www.rzrgm.cn/lv_anchoret/

       

      Preface

        為了支持光線追蹤的學習,決定寫一個3D泛型數學庫。

        我采用的是windows平臺以及C++Template技術

        

        我的庫文件組織目錄如下

        --lvgm

        ----test

        ------testVec.cpp

        ----type_vec

        ------lv_vec2.h

        ------lv_vec3.h

        ------type_vec.h

        ------vec_inout.h

        ----lv_precision.h

        ----lvgm.h

      Ready

        這一篇,需要您了解C++Template的基本語法

            需要您了解向量的運算

        該向量庫文件解釋:

            二維向量模板類

            三維向量模板類

            數據精度設定

            本庫提供的向量相關的默認輸出形式設置文件

        該向量庫文件暫時沒有四元組lv_vec4,我將在之后添加并單獨寫一篇進行陳述

        該向量庫能為您提供的功能:

            對向量內部數據方便自由地調取和設定

            向量的正負

            向量的加減乘除

            向量的自增自減

            向量的索引

            向量判等

            向量的賦值以及復合運算賦值

            向量的范數

            向量的范數平方

            向量的自身單位化

            返回該向量的高精度單位化向量

            向量的內積和外積運算(·、×)

            向量判空

      Design

        由于二維和三維的設計相仿,故此處以三維為例進行描述

      <1>類型相關

      本類中公開定義數據值類型為模板參T,范數精度類型為經外部宏設定的類型——precision, 默認為double

        設計問題:一開始我們可能想到在模板類里面利用宏控制數據存儲精度,但你可能會遇到問題。例如:

      #    ifdef HIGHPRECISION        //set the high precision 
      using norm_t = long double;
      
      #    elif(defined LOWPRECISION)    //set the low preciion
      using norm_t = float;
      
      #    else
      using norm_t = double;                //default precision
      
      #    endif                        //set precision

      假設我現在有一個int的三維向量,我想要返回一個實數精度(norm_t)的單位化向量,于是我們寫了一個成員函數vec3<norm_t> ret_unit()const,我們在主函數中需要創建一個vec3去接收ret_unit的返回值

      那么,我們兩手一攤,無可奈何你可能這樣做:

          vec3<??> normal = intV.ret_unit();

      你可能做不到,??可能是vec3::norm_t 嗎,顯然不是,vec3是一個模板,只能先將vec3<T>中的T特化。突然覺得,模板類中公開公布了精度類型norm_t,但是卻用不上??

        解決方案

      綜合考量到其他類可能也需要精度設定,所以干脆把這設置部分代碼單獨出來,然后將norm_t 改名為precision,于是問題就解決了

      模板類中只需要提前預處理precision文件即可進行如下簡單定義:

              using norm_t = precision;

      而主函數中也方便多了

          vec3<precision> normal = intV.ret_unit();

       

      <2>參數類型

      我看過glm數學庫的源碼有一類函數是這么實現的

      template <typename T, precision P>
      template <typename U>
          GLM_FUNC_QUALIFIER tvec3<T, P> & tvec3<T, P>::operator+=(tvec3<U, P> const & v)
          {
              this->x += static_cast<T>(v.x);
              this->y += static_cast<T>(v.y);
              this->z += static_cast<T>(v.z);
              return *this;
          }

      其實,意思就是它允許+=另外一種類型的向量,然后我都強轉到自身類型T之后進行運算

        解決方案

      個人有一拙見,我是下面這樣實現的,如果有什么漏洞請郵件或者評論留言。

      我可以通過“重載”static_cast,或者進行一些操作使得vec3模板類能夠實現類似內置整型之間的隱式自動類型轉換

      那么,我就不需要設定多個模板參在內部static_cast了。

      好,我們這么做就可以了:

              template<typename E>
              vec3(const vec3<E>& vec);        //static_cast

       

      我在定義構造函數的時候支持其他類型的vec3,哪里需要vec3值傳遞,我就調用它。

       

      <3>對數據進行方便自由的操作

      很多數學庫貌似可以直接v.x  v.y ,很多C-struct設計,但作為C++黨,用C++語言寫代碼,要嚴格遵守數據隱藏,在不失語言原則的情況下做到最方便。

      1)很多庫支持 v.x = 3;

      于是我定義:

              inline T& x()        { return _x; }

      但我還是重載了常量版本

              inline const T& x()const    { return _x; }

      我希望對內部數據的修改的禁止令可以通過參數來實現,比如:

      template<typename T>
              inline vec3<T> operator/(const vec3<T>& v1, const vec3<T>& v2)
                  {
                  //the operator of / ,example 3 * 5 -> 15 , (1,2,3) * (2,3,4) -> (1/2,2/3,3/4)
                  assert(v2.isnull());
                  return operator/<T, T> (v1, v2);
                  }

      所以,我僅僅去重載v.x()的const版本,而不去禁止x()可修改

       

      2)GLSL中還支持這種騷操作:v.rgb = v.gbr; or v.rg = v1.rg

      我看了glm庫,它暫時沒有實現上述的操作支持

      而GLSL庫我還沒研讀

      所以,憑著自身粗淺的技術,只能實現獲取數據元組,而不能實現修改:

      inline vec2<T> xy() { return vec2<T>{_x, _y}; }

       

      <4>運算符設計

      按照C++operator普遍的設計原則,依舊是將單目和(復合)賦值運算符重載定義為成員函數,而將雙目運算符定義為友元或者外部函數,在本庫中采用STL設計原則,定義為命名空間內的類外函數,為了不破壞C++類的封裝性

      ++、--等單目運算符請參見我的另外一篇專門解說運算符重載的文章

      此處,我只陳述與vec3類相關的設計細節

       

      關于加減法,從數學角度講,一個向量加減一個標量是非法的,所以,本庫中不支持向量和標量的加減法,對于將每一個元素加同一個值,請用偏移向量進行。


      而乘法和除法則支持與標量進行運算,因為一個標量乘以一個向量,只是把向量長度延伸了,在數學上也是合法的。

       

      除此之外,考慮到兩個vec3對象進行乘除法,如果this是int其他是另外一個是實數的話,我覺得還是進行精度提升的好,所以有專門的重載,且應用了C++11的自動追蹤返回值類型技術

       

      關于%以及%=,從數學角度講,實數并不支持%運算,只有integer才有,而在圖形運算過程中,大多是實數,盡管本庫不全應用于圖形計算,但是%合法運算在工程項目中占得也并不多,所以,如果需要,請自行將每一個元素進行%,庫設計中不會因為極小部分的應用而使庫變得臃腫

       

      向量范數以及單位化(標準化)

      一個類型設計點:利用用戶設定精度類型norm_t定義范數的值類型以及返回的標準化向量模板參。

      關于向量單位化,我寫了兩個,一個是自身單位化,此時遵循本身類型進行,意思就是int進行單位化仍然里面的元素是int。

      另一個是返回單位化向量,這個時候是實數向量。

       

      我想陳述的本庫相關的設計原則基本完畢。

       

      TEST

      測試效果:

      △--****************** CONSTRUCTOR TEST ******************
      
       ******* ivec3 test *********
      there are two ivec3s as intV{ 1,-2,3 } and intV2{ 1, }, the value of which as follows
      
      [ 1, -2, 3 ]
      
      [ 1, 0, 0 ]
      
      there is a ivec2 : _2ivec{1,2}, and a integer 7 to construct a ivec3 as follows
      
      the vec2 in front of the integer of 7: [ 1, 2, 7 ]
      
      the number of 7 in front of vec2: [ 7, 1, 2 ]
      
      
      
       ******* fvec3 test **********
      
      there is a fvec3 as fV{ 1.f,2.1f, }, the value of which as follows
      
      [ 1, 2.1, 0 ]
      
      there is a fvec2 : t{1.2f,}, and a value 3 to construct a ivec3 as follows
      
      f2to3 : [ 1.2, 0, 3 ]
      
      △--******************* FUNCTIONS TEST ********************
      
      there is a ivec3{1, -2, 3}
      the operator + or - of ivec3 as follows:
      
      + : [ 1, -2, 3 ]
      - :[ -1, 2, -3 ]
      
      -----------------------------------------------------------
      
      there is a ivec3{1, -2, 3}
      
      ++ivec3:        the val of expression:[ 2, -1, 4 ]      the val of ivec3:[ 2, -1, 4 ]
      
      ivec3++:        the val of expression:[ 1, -2, 3 ]      the val of ivec3:[ 2, -1, 4 ]
      
      the operator of -- is the same as above
      
      -----------------------------------------------------------
      
      the operator[] of ivec3 as follows:
      
      the intV[2] is 4
      -----------------------------------------------------------
      
      there are two ivec3s as intV{ 1,-2,3 } and intV2{ 1, }, the value of which as follows
      
      intV is not equ to intV2
      
      the operator = such that: intV2 = intV; the result as follows:
      intV2 is [ 2, -1, 4 ]
      intV is equ to intV2
      
      
      there are two ivec3s as intV{ 1,-2,3 } and intV2{ 1, }, the value of which as follows
      
      the operator += such that: intV += intV2, the result of which as follows:
      
      intV is: [ 3, -1, 4 ]
      
      the operator -= such that: intV -= intV2, the result of which as follows:
      
      intV is: [ 2, -1, 4 ]
      
      the value of intV is to become the original value
      
      
      there are two ivec3s as intV{ 1,-2,3 } and intV2{ 2,1,3 }, the value of which as follows
      
      the operator *= such that: intV *= intV2, the result of which as follows:
      
      intV is: [ 4, -1, 12 ]
      
      the operator /= such that: intV /= intV2, the result of which as follows:
      
      intV is: [ 2, -1, 4 ]
      
      the value of intV is to become the original value
      
      -----------------------------------------------------------
      
      the operator *= (number)such that: intV *= 5, the result of which as follows:
      
      intV is: [ 10, -5, 20 ]
      
      the operator /= (number) such that: intV /= 5, the result of which as follows:
      
      intV is: [ 2, -1, 4 ]
      
      the value of intV is to become the original value
      
      the operator + 、 -、 * 、/ (ivec3 or number) is the same as above
      
      -----------------------------------------------------------
      
      the operator* between ivec3 and fvec3 as follows:
      
      there is a ivec3: intV{1,-2,3}, there is a fvec3: fV{1.1f,2.3f,3.8f}, and the result of ivec3*fvec3 as follows:
      
      res is: [ 1.1, -4.6, 11.4 ]
      
      the result of * is up to the higher precision of both
      
      the operator* between ivec3 and float as follows:
      
      there is a ivec3: intV{1,-2,3}, there is a float: 3.14, and the result of ivec3*3.14 as follows:
      
      res2 is: [ 3, -6, 9 ]
      
      the type of ivec3 * float is not fvec3 but ivec3, and the factor is just a factor that shouldn't change the vec's precision
      if you need the result's type to become fvec3,you should use static_cast<fvec3>(intV) * float
      
      res3 is: [ 3.14, -6.28, 9.42 ]
      
      the operator/ between different type is the same as above
      
      -----------------------------------------------------------
      
      the normal() test as follows:
      
      there is a ivec3: intV{1,-2,3}
      
      the Norm of intV is: 3.74166
      
      there is a fvec3: fV{ 1.1, 2.3, 3.5}
      
      the Norm of fV is: 4.57602
      
      -----------------------------------------------------------
      
      there is a ivec3: intV{0, 4, 3}
      
      the unitization of intV is: [ 0, 0.8, 0.6 ]
      
      -----------------------------------------------------------
      
      there is a ivec3: intV{1,-2,3}, there is a fvec3: fV{1.1f,2.3f,3.8f}, and the result of ivec3·fvec3 as follows:
      
      the dotval is: 7.9
      
      crossVec is: [ -14.5, -0.5, 4.5 ]
      test result

       

      #define LOWPRECISION        //開啟低精度
      #define VEC3_OUT            //開啟vec3輸出
      
      #include <lvgm\lvgm.h>
      #define stds std::
      #define enter stds endl << stds endl
      
      using lvgm::ivec2;
      using lvgm::ivec3;
      using lvgm::fvec3;
      using lvgm::fvec2;
      
      int main()
      {
          ivec3 intV{ 1,-2,3 }, intV2{ 1, }, null;
          //null.self_unitization();
          ivec3 b;
          ivec2 _2ivec{ 1,2 };
          fvec3 fV{ 1.f,2.1f, };
          stds cout << "△--****************** CONSTRUCTOR TEST ******************" << enter;
          stds cout << " ******* ivec3 test *********" << stds endl;
          stds cout << "there are two ivec3s as intV{ 1,-2,3 } and intV2{ 1, }, the value of which as follows" << enter;
          stds cout << intV << enter;
          stds cout << intV2 << enter;
          stds cout << "there is a ivec2 : _2ivec{1,2}, and a integer 7 to construct a ivec3 as follows" << enter;
          ivec3 _2to3{ _2ivec, 7 };
          stds cout << "the vec2 in front of the integer of 7: " << _2to3 << enter;
          _2to3 = ivec3{ 7, _2ivec };
          stds cout << "the number of 7 in front of vec2: " << _2to3 << enter << enter;
      
          stds cout << " ******* fvec3 test **********" << enter;
          stds cout << "there is a fvec3 as fV{ 1.f,2.1f, }, the value of which as follows" << enter;
          stds cout << fV << enter;
          stds cout << "there is a fvec2 : t{1.2f,}, and a value 3 to construct a ivec3 as follows" << enter;
          fvec2 t{ 1.2f };
          fvec3 f2to3{ t,3 };
          stds cout << "f2to3 : " << f2to3 << enter;
      
          stds cout << "△--******************* FUNCTIONS TEST ********************" << enter;
          stds cout << "there is a ivec3{1, -2, 3}" << stds endl;
          stds cout << "the operator + or - of ivec3 as follows:" << enter;
          intV = +intV;
          stds cout << "+ : " << intV << stds endl;
          intV = -intV;
          stds cout << "- :" << intV << enter;
          intV = -intV;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "there is a ivec3{1, -2, 3}" << enter;
          auto re = ++intV;
          stds cout << "++ivec3:    the val of expression:" << re << "\tthe val of ivec3:" << intV << enter;
          --intV;
          re = intV++;
          stds cout << "ivec3++:    the val of expression:" << re << "\tthe val of ivec3:" << intV << enter;
          stds cout << "the operator of -- is the same as above" << enter;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "the operator[] of ivec3 as follows:" << enter;
          stds cout << "the intV[2] is " << intV[2] << stds endl;
          //stds cout << "the intV[4] is " << intV[4] << stds endl;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "there are two ivec3s as intV{ 1,-2,3 } and intV2{ 1, }, the value of which as follows" << enter;
          if (intV != intV2)stds cout << "intV is not equ to intV2" << enter;
          stds cout << "the operator = such that: intV2 = intV; the result as follows:" << stds endl;
          intV2 = intV;
          stds cout << "intV2 is " << intV2 << stds endl;
          if (intV2 == intV)stds cout << "intV is equ to intV2" << enter;
          stds cout << stds endl << "there are two ivec3s as intV{ 1,-2,3 } and intV2{ 1, }, the value of which as follows" << enter;
          stds cout << "the operator += such that: intV += intV2, the result of which as follows:" << enter;
          intV2 = { 1, };
          intV += intV2;
          stds cout << "intV is: " << intV << enter;
          stds cout << "the operator -= such that: intV -= intV2, the result of which as follows:" << enter;
          intV -= intV2;
          stds cout << "intV is: " << intV << enter;
          stds cout << "the value of intV is to become the original value" << enter;
          stds cout << stds endl << "there are two ivec3s as intV{ 1,-2,3 } and intV2{ 2,1,3 }, the value of which as follows" << enter;
          stds cout << "the operator *= such that: intV *= intV2, the result of which as follows:" << enter;
          intV2 = { 2,1,3 };
          intV *= intV2;
          stds cout << "intV is: " << intV << enter;
          intV /= intV2;
          stds cout << "the operator /= such that: intV /= intV2, the result of which as follows:" << enter;
          stds cout << "intV is: " << intV << enter;
          stds cout << "the value of intV is to become the original value" << enter;
      
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "the operator *= (number)such that: intV *= 5, the result of which as follows:" << enter;
          intV *= 5;
          stds cout << "intV is: " << intV << enter;
          stds cout << "the operator /= (number) such that: intV /= 5, the result of which as follows:" << enter;
          intV /= 5;
          stds cout << "intV is: " << intV << enter;
          stds cout << "the value of intV is to become the original value" << enter;
          stds cout << "the operator + 、 -、 * 、/ (ivec3 or number) is the same as above" << enter;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "the operator* between ivec3 and fvec3 as follows:" << enter;
          stds cout << "there is a ivec3: intV{1,-2,3}, there is a fvec3: fV{1.1f,2.3f,3.8f}, and the result of ivec3*fvec3 as follows:" << enter;
          intV = { 1,-2,3 };
          fV = { 1.1f,2.3f,3.8f };
          auto res = intV*fV;
          stds cout << "res is: " << res << enter;
          stds cout << "the result of * is up to the higher precision of both" << enter;
      
          stds cout << "the operator* between ivec3 and float as follows:" << enter;
          stds cout << "there is a ivec3: intV{1,-2,3}, there is a float: 3.14, and the result of ivec3*3.14 as follows:" << enter;
          intV = { 1,-2,3 };
          auto res2 = intV*3.14;
          stds cout << "res2 is: " << res2 << enter;
          stds cout << "the type of ivec3 * float is not fvec3 but ivec3, and the factor is just a factor that shouldn't change the vec's precision" << stds endl
              << "if you need the result's type to become fvec3,you should use static_cast<fvec3>(intV) * float" << enter;
          intV = { 1,-2,3 };
          auto res3 = (static_cast<fvec3>(intV))*3.14;
          stds cout << "res3 is: " << res3 << enter;
          stds cout << "the operator/ between different type is the same as above" << enter;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "the normal() test as follows: " << enter;
          stds cout << "there is a ivec3: intV{1,-2,3}" << enter;
          stds cout << "the Norm of intV is: " << intV.normal() << enter;
          stds cout << "there is a fvec3: fV{ 1.1, 2.3, 3.5}" << enter;
          stds cout << "the Norm of fV is: " << fV.normal() << enter;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "there is a ivec3: intV{0, 4, 3}" << enter;
          intV = { 0,4,3 };
          lvgm::vec3<lvgm::precision> normal = intV.ret_unitization();
          stds cout << "the unitization of intV is: " << normal << enter;
          stds cout << "-----------------------------------------------------------" << enter;
      
          stds cout << "there is a ivec3: intV{1,-2,3}, there is a fvec3: fV{1.1f,2.3f,3.8f}, and the result of ivec3·fvec3 as follows:" << enter;
          intV = { 1,-2,3 };
          fV = { 1.1f,2.3f,3.8f };
          lvgm::precision dotval = lvgm::dot(intV, fV);
          stds cout << "the dotval is: " << dotval << enter;
          auto crossVec = cross(intV, fV);
          stds cout << "crossVec is: " << crossVec << enter;
      }
      test code

       

      庫文件代碼

      /// lvgm.h
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2018.12 ~ 2018.12
      // [brief ]        include all of the mymath's head files
      // -----------------------------------------------------
      
      #ifndef LVGM_H
      #define LVGM_H
      
      #include <lvgm\type_vec\type_vec.h>
      
      #endif  //LVGM_H
      lvgm.h

       

      /// precision.h
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2018.12 ~ 2018.12
      // [brief ]        control the precision of data
      // -----------------------------------------------------
      
      
      
      #ifndef LV_PRECISION_H
      #define LV_PRECISION_H
      
      
      namespace lvgm
      {
      
      #    ifdef HIGHPRECISION            //set the high precision 
      using precision = long double;
      
      #    elif(defined LOWPRECISION)    //set the low preciion
      using precision = float;
      
      #    else
      using precision = double;        //default precision
      
      #    endif                        //set precision
      
      
      }    //namespace lvgm
      
      #endif        //LV_PRECISION_H
      precision.h

       

      /// myVec2.h
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2018.12 ~ 2018.12
      // [brief ]        the definition of two-dimensional vector 
      // -----------------------------------------------------
      
      
      #ifndef LV_VEC2_H
      #define LV_VEC2_H
      
      
      namespace lvgm
      {
      
      template<typename T>
          class vec2
              {
          public:
              using value_type = T;
      
              using norm_t = precision;
      
          public:
      
              template<typename E>
              vec2(const vec2<E>& vec);        //static_cast
      
              vec2(const T x = T(), const T y = T())noexcept;
      
              vec2(const vec2&);
      
              ~vec2() {  }
      
          public:
              //inline get function
              inline T& x() { return _x; }
      
              inline T& y() { return _y; }
      
              inline T& u() { return _x; }
      
              inline T& v() { return _y; }
      
              inline T& r() { return _x; }
      
              inline T& g() { return _y; }
      
              inline T& s() { return _x; }
      
              inline T& t() { return _y; }
      
              inline vec2 xy() { return vec2<T>{_x, _y}; }
      
              inline vec2 yx() { return vec2<T>{_y, _x}; }
      
              inline vec2 rg() { return vec2<T>{_x, _y}; }
      
              inline vec2 gr() { return vec2<T>{_y, _x}; }
      
              inline vec2 uv() { return vec2<T>{_x, _y}; }
      
              inline vec2 vu() { return vec2<T>{_y, _x}; }
      
              inline vec2 st() { return vec2<T>{_x, _y}; }
      
              inline vec2 ts() { return vec2<T>{_y, _x}; }
      
              inline const T& x()const { return _x; }
      
              inline const T& y()const { return _y; }
      
              inline const T& u()const { return _x; }
      
              inline const T& v()const { return _y; }
      
              inline const T& r()const { return _x; }
      
              inline const T& g()const { return _y; }
      
              inline const T& s()const { return _x; }
      
              inline const T& t()const { return _y; }
      
              //inline operator function
              inline const vec2& operator+()const;
      
              inline vec2 operator-()const;
      
              inline vec2& operator++();
      
              inline vec2& operator--();
      
              inline const vec2 operator++(int);
      
              inline const vec2 operator--(int);
      
              inline const T& operator[](const int index)const;
      
              inline T& operator[](const int index);
      
              inline vec2& operator=(const vec2& rhs);
      
              inline vec2& operator+=(const vec2& rhs);
      
              inline vec2& operator-=(const vec2& rhs);
      
              inline vec2& operator*=(const vec2& rhs);
      
              inline vec2& operator/=(const vec2& rhs);
      
              inline vec2& operator*=(const T factor);
      
              inline vec2& operator/=(const T factor);
      
          public:
              //return the Norm of vec2
              inline norm_t normal()const;
      
              inline norm_t squar()const;
      
              //let self become to the unit vector of vec_type
              inline void self_unitization();
      
              //return a non-integer three-dimensional unit vector [the type is norm_t]
              inline vec2<precision> ret_unitization()const;
      
              inline bool isnull()const;
      
          private:
              T _x, _y;
      
              };
      
      //constructor functions
      
          template<typename T>
              vec2<T>::vec2(const T x, const T y)noexcept
                  :_x(x)
                  , _y(y)
          {    }
      
          template<typename T>
              template<typename E>
              vec2<T>::vec2(const vec2<E>& rhs)
                  :_x(static_cast<T>(rhs.x()))
                  , _y(static_cast<T>(rhs.y()))
          {    }
      
          template<typename T>
              vec2<T>::vec2(const vec2<T>& rhs)
                  : _x(rhs._x)
                  , _y(rhs._y)
          {    }
      
      // Binary operator functions [non-mem]
      
          template<typename T>
              inline vec2<T> operator+(const vec2<T>& v1, const vec2<T>& v2)
                  {
                  return vec2<T>(v1[0] + v2[0], v1[1] + v2[1]);
                  }
      
          template<typename T>
              inline vec2<T> operator-(const vec2<T>& v1, const vec2<T>& v2)
                  {
                  //the operator of - ,example  (5,4) - (2,2) -> (3,2)  
                  return v1 + (-v2);
                  }
      
          template<typename A, typename B>
              inline auto operator*(const vec2<A>& v1, const vec2<B>& v2)
                  {
                  //the operator of * ,example  (1.1, 2.1) * (2, 3) -> (2.2, 6.3)
                  using type = decltype(v1[0] * v2[0]);
                  return vec2<type>((type)v1[0] * v2[0], (type)v1[1] * v2[1]);
                  }
      
          template<typename T>
              inline vec2<T> operator*(const vec2<T>& v1, const vec2<T>& v2)
                  {
                  //the operator of * ,example (1,2) * (2,3) -> (2,6)
                  return vec2<T>(v1[0] * v2[0], v1[1] * v2[1]);
                  }
      
          template<typename T, typename E>
              inline vec2<T> operator*(const vec2<T>& v, const E factor)
                  {
                  return vec2<T>(v.x() * factor, v.y() * factor);
                  }
      
          template<typename T, typename E>
              inline vec2<T> operator*(const E factor, const vec2<T>& v)
                  {
                  return vec2<T>(v.x() * factor, v.y() * factor);
                  }
      
          template<typename A, typename B>
              inline auto operator/(const vec2<A>& v1, const vec2<B>& v2)
                  {
                  //the operator of / ,example  (1.1, 2.1) * (2, 3) -> (0.55, 0.7)
                  assert(v2.isnull());
                  using type = decltype(v1[0] / v2[0]);
                  return vec2<type>((type)v1[0] / v2[0], (type)v1[1] / v2[1]);
                  }
      
          template<typename T>
              inline vec2<T> operator/(const vec2<T>& v1, const vec2<T>& v2)
                  {
                  //the operator of / ,example 3 * 5 -> 15 , (1,2) * (2,3) -> (1/2,2/3)
                  assert(v2.isnull());
                  return operator/<T, T> (v1, v2);
                  }
      
          template<typename T, typename E>
              inline vec2<T> operator/(const vec2<T>& v, const E factor)
                  {
                  assert(factor != 0 && factor != 0.);
                  return vec2<T>(v.x() / factor, v.y() / factor);
                  }
      
          template<typename T>
              inline bool operator==(const vec2<T>& v1, const vec2<T>& v2)
                  {
                  return v1.x() == v2.x() && v1.y() == v2.y();
                  }
      
          template<typename T>
              inline bool operator!=(const vec2<T>& v1, const vec2<T>& v2)
                  {
                  return !(v1 == v2);
                  }
      
          // Unary operator functions [mem]
      
          template<typename T>
              inline const vec2<T>& vec2<T>::operator+() const
                  {
                  //the operator of + ,example 5 -> +5,  +(1,-2) -> (1,-2)
                  return *this;
                  }
      
          template<typename T>
              inline vec2<T> vec2<T>::operator-() const
                  {
                  //the operator of - ,example 5 -> -5,  -(1,-2) -> (-1,2)
                  return vec2<T>(-_x, -_y);
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator++()
                  {
                  ++this->_x;
                  ++this->_y;
                  return *this;
                  }
      
          template<typename T>
              inline const vec2<T> vec2<T>::operator++(int)
                  {
                  vec2<T>ori(*this);
                  ++*this;
                  return ori;
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator--()
                  {
                  --this->_x;
                  --this->_y;
                  return *this;
                  }
      
          template<typename T>
              inline const vec2<T> vec2<T>::operator--(int)
                  {
                  vec2<T>ori(*this);
                  --*this;
                  return ori;
                  }
      
          template<typename T>
              inline const T& vec2<T>::operator[](const int index)const
                  {
                  if (index == 0)return _x;
                  else if (index == 1)return _y;
                  else throw "the index is error";
                  }
      
          template<typename T>
              inline T& vec2<T>::operator[](const int index)
                  {
                  if (index == 0)return _x;
                  else if (index == 1)return _y;
                  else throw "the index is error";
                  }
      
      // member functions
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator=(const vec2<T>& rhs)
                  {
                  if (this != &rhs)
                      {
                      _x = rhs._x;
                      _y = rhs._y;
                      }
                  return *this;
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator+=(const vec2& rhs)
                  {
                  this->_x += rhs._x;
                  this->_y += rhs._y;
                  return *this;
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator-=(const vec2& rhs)
                  {
                  return *this += (-rhs);
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator/=(const vec2<T>& rhs)
                  {
                  assert(!rhs.isnull());
                  this->_x /= rhs._x;
                  this->_y /= rhs._y;
                  return *this;
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator*=(const vec2<T>& rhs)
                  {
                  this->_x *= rhs._x;
                  this->_y *= rhs._y;
                  return *this;
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator*=(const T factor)
                  {
                  this->_x *= factor;
                  this->_y *= factor;
                  return *this;
                  }
      
          template<typename T>
              inline vec2<T>& vec2<T>::operator/=(const T factor)
                  {
                  assert(factor != 0);
                  this->_x /= factor;
                  this->_y /= factor;
                  return *this;
                  }
      
      
          template<typename T>
              inline typename vec2<T>::norm_t vec2<T>::normal()const
                  {
                  return sqrt(squar());
                  }
      
          template<typename T>
              inline typename vec2<T>::norm_t vec2<T>::squar()const
                  {
                  return _x*_x + _y*_y;
                  }
      
          template<typename T>
              inline void vec2<T>::self_unitization()
                  {
                  *this /= normal();
                  }
      
          template<typename T>
              inline vec2<precision> vec2<T>::ret_unitization()const
                  {
                  norm_t div = normal();
                  return vec2<norm_t>{ (norm_t)this->_x / div, (norm_t)this->_y / div, (norm_t)this->_z / div };
                  }
      
          template<typename T, typename E>
              inline auto dot(const vec2<T>& v1, const vec2<E>& v2) //-> decltype(v1.x() * v2.x() + v1.y() * v2.y()
                  {// x1 * x2 + y1 * y2
                  return v1.x() * v2.x() + v1.y() * v2.y();
                  }
      
          template<typename T, typename E>
              inline auto cross(const vec2<T> v1, const vec2<E>& v2)
                  {// v1 × v2
                  return    v1[0] * v2[1] - v1[1] * v2[0];
                  }
      
          template<typename T>
              inline bool vec2<T>::isnull()const
                  {
                  return *this == vec2<T>();
                  }
      
      }    //namespace lvgm
      
      
      #endif    //LV_VEC2_H
      lv_vec2.h

       

      /// myVec3.h
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2018.12 ~ 2018.12
      // [brief ]        the definition of Three-dimensional vector
      // -----------------------------------------------------
      
      #ifndef LV_VEC3_H
      #define LV_VEC3_H
      
      namespace lvgm
      {
      
      template<typename T>
          class vec3
              {
          public:
              using value_type = T;
      
              using norm_t = precision;
      
          public:
      
              template<typename E>
              vec3(const vec3<E>& vec);        //static_cast
      
              vec3(const T e1 = T(), const T e2 = T(), const T e3 = T())noexcept;
      
              explicit vec3(const vec2<T>& v2, const T e3 = T())noexcept;
      
              explicit vec3(const T e1, const vec2<T>& v)noexcept;
      
              explicit vec3(const vec3&);
      
              ~vec3() {  }
      
          public:
      
              inline T& x()        { return _x; }
      
              inline T& y()        { return _y; }
      
              inline T& z()        { return _z; }
      
              inline T& r()        { return _x; }
      
              inline T& g()        { return _y; }
      
              inline T& b()        { return _z; }
      
              inline vec2<T> xy() { return vec2<T>{_x, _y}; }
      
              inline vec2<T> yx()    { return vec2<T>{_y, _x}; }
      
              inline vec2<T> xz()    { return vec2<T>{_x, _z}; }
      
              inline vec2<T> zx()    { return vec2<T>{_z, _x}; }
      
              inline vec2<T> yz()    { return vec2<T>{_y, _z}; }
      
              inline vec2<T> zy()    { return vec2<T>{_z, _y}; }
      
              inline vec2<T> rg()    { return vec2<T>{_x, _y}; }
      
              inline vec2<T> gr()    { return vec2<T>{_y, _x}; }
      
              inline vec2<T> rb()    { return vec2<T>{_x, _z}; }
      
              inline vec2<T> br()    { return vec2<T>{_z, _x}; }
      
              inline vec2<T> gb()    { return vec2<T>{_y, _z}; }
      
              inline vec2<T> bg()    { return vec2<T>{_z, _y}; }
      
              inline vec3 rgb()    { return vec3{_x, _y, _z}; }
      
              inline vec3 rbg()    { return vec3{_x, _z, _y}; }
                  
              inline vec3 gbr()    { return vec3{_y, _z, _x}; }
      
              inline vec3 grb()    { return vec3{_y, _x, _z}; }
      
              inline vec3 bgr()    { return vec3{_z, _y, _x}; }
      
              inline vec3 brg()    { return vec3{_z, _x, _y}; }
      
              inline const T& x()const    { return _x; }
      
              inline const T& y()const    { return _y; }
      
              inline const T& z()const    { return _z; }
      
              inline const T& r()const    { return _x; }
      
              inline const T& g()const    { return _y; }
      
              inline const T& b()const    { return _z; }
      
              //inline oprator function
              inline const vec3& operator+() const;
      
              inline vec3 operator-()const;
      
              inline vec3& operator++();
      
              inline vec3& operator--();
      
              inline const vec3 operator++(int);
      
              inline const vec3 operator--(int);
      
              inline const T& operator[](const int index)const;
      
              inline T& operator[](const int index);
      
              inline vec3& operator=(const vec3& rhs);
      
              inline vec3& operator+=(const vec3& rhs);
      
              inline vec3& operator-=(const vec3& rhs);
      
              inline vec3& operator*=(const vec3& rhs);
      
              inline vec3& operator/=(const vec3& rhs);
      
              inline vec3& operator*=(const T factor);
      
              inline vec3& operator/=(const T factor);
              
          public:
              //return the Norm of vec3
              inline norm_t normal()const;
      
              inline norm_t squar()const;
      
              //let self become to the unit vector of vec_type
              inline void self_unitization();
      
              //return a non-integer three-dimensional unit vector [the type is norm_t]
              inline vec3<precision> ret_unitization()const;
      
              inline bool isnull()const;
      
          private:
              T _x, _y, _z;
      
              };
      
      //constructor functions
      
          template<typename T>
              template<typename E>
              vec3<T>::vec3(const vec3<E>& vec)
                  :_x(static_cast<T>(vec.x()))
                  ,_y(static_cast<T>(vec.y()))
                  ,_z(static_cast<T>(vec.z()))
              {    }
          
          template<typename T>
              vec3<T>::vec3(const T e1, const T e2, const T e3)noexcept
                  :_x{e1}
                  ,_y{e2}
                  ,_z{e3}
              {    }
      
          template<typename T>
              vec3<T>::vec3(const vec2<T>& v, const T e3)noexcept
                  :_x(v.x())
                  ,_y(v.y())
                  ,_z(e3)
              {    }
      
          template<typename T>
              vec3<T>::vec3(const T e, const vec2<T>& v)noexcept
                  :_x(e)
                  ,_y(v.x())
                  ,_z(v.y())
              {    }
      
          template<typename T>
              vec3<T>::vec3(const vec3<T>& rhs)
                  :_x{rhs._x}
                  ,_y{rhs._y}
                  ,_z{rhs._z}
              {    }
      
      // Binary operator functions [non-mem]
          template<typename T>
              vec3<T> operator+(const vec3<T>& v1, const vec3<T>& v2)
                  {
                  //the operator of + ,example  (5,4,3) + (2,-2,1) -> (7,2,4)  
                  return vec3<T>(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
                  }
      
          template<typename T>
              inline vec3<T> operator-(const vec3<T>& v1, const vec3<T>& v2)
                  {
                  //the operator of - ,example  (5,4,3) - (2,2,1) -> (3,2,2)  
                  return v1 + (-v2);
                  }
      
          template<typename A, typename B>
              inline auto operator*(const vec3<A>& v1, const vec3<B>& v2)
                  {
                  //the operator of * ,example  (1.1, 2.1, 3.1) * (2, 3, 4) -> (2.2, 6.3, 12.4)
                  using type = decltype(v1[0] * v2[0]);
                  return vec3<type>((type)v1[0] * v2[0], (type)v1[1] * v2[1], (type)v1[2] * v2[2]);
                  }
      
          template<typename T>
              inline vec3<T> operator*(const vec3<T>& v1, const vec3<T>& v2)
                  {
                  //the operator of * ,example 3 * 5 -> 15 , (1,2,3) * (2,3,4) -> (2,6,12)
                  return vec3<T>(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);
                  }
      
          template<typename T, typename E>
              inline vec3<T> operator*(const vec3<T>& v, const E factor)
                  {
                  return vec3<T>(v.x() * factor, v.y() * factor, v.z() * factor);
                  }
      
          template<typename T, typename E>
              inline vec3<T> operator*(const E factor, const vec3<T>& v)
                  {
                  return vec3<T>(v.x() * factor, v.y() * factor, v.z() * factor);
                  }
      
          template<typename A, typename B>
              inline auto operator/(const vec3<A>& v1, const vec3<B>& v2)
                  {
                  //the operator of / ,example  (1.1, 2.1, 3.2) * (2, 3, 4) -> (0.55, 0.7, 0.8)
                  assert(v2.isnull());
                  using type = decltype(v1[0] / v2[0]);
                  return vec3<type>((type)v1[0] / v2[0], (type)v1[1] / v2[1], (type)v1[2] / v2[2]);
                  }
              
          template<typename T>
              inline vec3<T> operator/(const vec3<T>& v1, const vec3<T>& v2)
                  {
                  //the operator of / ,example 3 * 5 -> 15 , (1,2,3) * (2,3,4) -> (1/2,2/3,3/4)
                  assert(v2.isnull());
                  return operator/<T, T> (v1, v2);
                  }
      
          template<typename T, typename E>
              inline vec3<T> operator/(const vec3<T>& v, const E factor)
                  {
                  assert(factor != 0 && factor != 0.);
                  return vec3<T>(v.x() / factor, v.y() / factor, v.z() / factor);
                  }
      
          template<typename T>
              inline bool operator==(const vec3<T>& v1, const vec3<T>& v2)
                  {
                  return v1.x() == v2.x() && v1.y() == v2.y() && v1.z() == v2.z();
                  }
      
          template<typename T>
              inline bool operator!=(const vec3<T>& v1, vec3<T>& v2)
                  {
                  return !(v1 == v2);
                  }
      
      // Unary operator functions [mem]
          template<typename T>
              inline const vec3<T>& vec3<T>::operator+() const 
                  {
                  //the operator of + ,example 5 -> +5,  +(1,-2,3) -> (1,-2,3)
                  return *this; 
                  }
      
          template<typename T>
              inline vec3<T> vec3<T>::operator-() const
                  {
                  //the operator of - ,example 5 -> -5,  -(1,-2,3) -> (-1,2,-3)
                  return vec3<T>(-_x, -_y, -_z);
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator++()
                  {
                  ++this->_x;
                  ++this->_y;
                  ++this->_z;
                  return *this;
                  }
      
          template<typename T>
              inline const vec3<T> vec3<T>::operator++(int)
                  {
                  vec3<T>ori(*this);
                  ++*this;
                  return ori;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator--()
                  {
                  --this->_x;
                  --this->_y;
                  --this->_z;
                  return *this;
                  }
      
          template<typename T>
              inline const vec3<T> vec3<T>::operator--(int)
                  {
                  vec3<T>ori(*this);
                  --*this;
                  return ori;
                  }
      
          template<typename T>
              inline const T& vec3<T>::operator[](const int index)const
                  {
                  if (index == 0)return _x;
                  else if (index == 1)return _y;
                  else if (index == 2)return _z;
                  else throw "the index is error";
                  }
      
          template<typename T>
              inline T& vec3<T>::operator[](const int index)
                  {
                  if (index == 0)return _x;
                  else if (index == 1)return _y;
                  else if (index == 2)return _z;
                  else throw "the index is error";
                  }
      
      // member functions
          template<typename T>
              inline vec3<T>& vec3<T>::operator=(const vec3<T>& rhs)
                  {
                  if (this != &rhs)
                      {
                      _x = rhs._x;
                      _y = rhs._y;
                      _z = rhs._z;
                      }
                  return *this;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator+=(const vec3& rhs)
                  {
                  this->_x += rhs._x;
                  this->_y += rhs._y;
                  this->_z += rhs._z;
                  return *this;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator-=(const vec3& rhs)
                  {
                  this->_x -= rhs._x;
                  this->_y -= rhs._y;
                  this->_z -= rhs._z;
                  return *this;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator/=(const vec3<T>& rhs)
                  {
                  assert(!rhs.isnull());
                  this->_x /= rhs._x;
                  this->_y /= rhs._y;
                  this->_z /= rhs._z;
                  return *this;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator*=(const vec3<T>& rhs)
                  {
                  this->_x *= rhs._x;
                  this->_y *= rhs._y;
                  this->_z *= rhs._z;
                  return *this;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator*=(const T factor)
                  {
                  this->_x *= factor;
                  this->_y *= factor;
                  this->_z *= factor;
                  return *this;
                  }
      
          template<typename T>
              inline vec3<T>& vec3<T>::operator/=(const T factor)
                  {
                  assert(factor != 0);
                  this->_x /= factor;
                  this->_y /= factor;
                  this->_z /= factor;
                  return *this;
                  }
      
          template<typename T>
              inline typename vec3<T>::norm_t vec3<T>::normal()const
                  {
                  return sqrt(squar());
                  }
      
          template<typename T>
              inline typename vec3<T>::norm_t vec3<T>::squar()const
                  {
                  return _x*_x + _y*_y + _z*_z;
                  }
      
          template<typename T>
              inline void vec3<T>::self_unitization()
                  {
                  *this /= normal();
                  }
      
          template<typename T>
              inline vec3<precision> vec3<T>::ret_unitization()const
                  {
                  norm_t div = normal();
                  return vec3<norm_t>{ (norm_t)this->_x / div,(norm_t)this->_y / div,(norm_t)this->_z / div };
                  }
      
          template<typename T, typename E>
              inline auto dot(const vec3<T>& v1, const vec3<E>& v2) //-> decltype(v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z())
                  {// x1 * x2 + y1 * y2 + z1 * z2
                  return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
                  }
      
          template<typename T, typename E>
              inline auto cross(const vec3<T> v1, const vec3<E>& v2)
                  {// v1 × v2
                  return vec3<decltype(v1[1] * v2[2] - v1[2] * v2[1])>
                      (
                      v1[1] * v2[2] - v1[2] * v2[1],
                      v1[2] * v2[0] - v1[0] * v2[2],
                      v1[0] * v2[1] - v1[1] * v2[0]
                      );
                  }
      
          template<typename T>
              inline bool vec3<T>::isnull()const
                  {
                  return *this == vec3<T>();
                  }
      
      }    //namespace lvgm
      
      #endif    //LV_VEC3_H
      lv_vec3.h

       

      /// all vectors are in here
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2018.12 ~ 2018.12
      // [brief ]        all vectors are in here
      // -----------------------------------------------------
      
      
      #pragma once
      
      #include <iostream>
      #include <cmath>
      #include <cassert>
      #include <lvgm\lv_precision.h>
      
      #include "lv_vec2.h"
      #include "lv_vec3.h"
      #include "vec_inout.h"
      
      namespace lvgm
      {
          template<typename T> class vec2;
      
          template<typename T> class vec3;
      
          template<typename T> class vec4;
      
      
          typedef vec2<bool> bvec2;
      
          typedef vec2<char> cvec2;
      
          typedef vec2<short> svec2;
      
          typedef vec2<int> ivec2;
      
          typedef vec2<float> fvec2;
      
          typedef vec2<double> dvec2;
      
          typedef vec2<long double> ldvec2;
      
      
          typedef vec3<bool> bvec3;
      
          typedef vec3<char> cvec3;
      
          typedef vec3<short> svec3;
      
          typedef vec3<int> ivec3;
      
          typedef vec3<float> fvec3;
      
          typedef vec3<double> dvec3;
      
          typedef vec3<long double> ldvec3;
      
      
          typedef vec4<bool> bvec4;
      
          typedef vec4<char> cvec4;
      
          typedef vec4<short> svec4;
      
          typedef vec4<int> ivec4;
      
          typedef vec4<float> fvec4;
      
          typedef vec4<double> dvec4;
      
          typedef vec4<long double> ldvec4;
      }
      type_vec.h

       

      ///vec_inout.h
      
      // -----------------------------------------------------
      // [author]        lv
      // [ time ]        2018.12 ~ 2018.12
      // [brief ]        control the iostream of vec
      // -----------------------------------------------------
      
      
      #pragma once
      
      
      # ifdef    VEC_OUT
      
          template<typename T>
              std::ostream& operator<<(std::ostream& cout, const lvgm::vec2<T>& v)
                  {
                  cout << "[ " << v.x() << ", " << v.y() << " ]";
                  return cout;
                  }
      
          template<typename T>
              std::ostream& operator<<(std::ostream& cout, const lvgm::vec3<T>& v)
                  {
                  cout << "[ " << v.x() << ", " << v.y() << ", " << v.z() << " ]";
                  return cout;
                  }
      
          template<typename T>
              std::ostream& operator<<(std::ostream& cout, const lvgm::vec4<T>& v)
              {
                  cout << "[ " << v.x() << ", " << v.y() << ", " << v.z() << v.w() << " ]";
                  return cout;
              }
      
      #endif
      
      # ifdef VEC2_OUT 
      
          template<typename T>
              std::ostream& operator<<(std::ostream& cout, const lvgm::vec2<T>& v)
                  {
                  cout << "[ " << v.x() << ", " << v.y() << " ]";
                  return cout;
                  }
      
      #endif
      
      # ifdef VEC3_OUT 
      
          template<typename T>
              std::ostream& operator<<(std::ostream& cout, const lvgm::vec3<T>& v)
                  {
                  cout << "[ " << v.x() << ", " << v.y() << ", " << v.z() << " ]";
                  return cout;
                  }
      
      #endif
      
      # ifdef VEC4_OUT 
      
          template<typename T>
              std::ostream& operator<<(std::ostream& cout, const lvgm::vec4<T>& v)
                  {
                  cout << "[ " << v.x() << ", " << v.y() << ", " << v.z() << v.w() << " ]";
                  return cout;
                  }
      
      #endif
      vec_inout.h

       

      如有什么問題,請于評論區留言或者郵箱(^_^)

       

      感謝您的閱讀,生活愉快`

       

      posted @ 2018-12-23 00:46  林-兮  閱讀(3446)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 无遮高潮国产免费观看| 国产情侣激情在线对白| 亚洲精品av一二三区无码| 国产免费又黄又爽又色毛| 一个人看的www视频免费观看| 色777狠狠狠综合| av在线播放国产一区| 免费无码va一区二区三区 | 武装少女在线观看高清完整版免费| 人妻在线无码一区二区三区| 久久亚洲精品成人av无| 欧美18videosex性欧美tube1080| av天堂久久精品影音先锋 | 孕交videos小孕妇xx| 狠狠色噜噜狠狠狠狠2021| 久久99国产一区二区三区| 久久无码中文字幕免费影院蜜桃| 亚洲av永久无码天堂影院| 久久综合开心激情五月天| 国产三级a三级三级| 无遮挡aaaaa大片免费看| 亚洲国产在一区二区三区| 德清县| 久久人妻精品国产| 亚洲理论电影在线观看| 亚洲一区成人av在线| 毛片亚洲AV无码精品国产午夜| 芳草地社区在线视频| XXXXXHD亚洲日本HD| 久久国产精品免费一区| 亚洲av高清一区二区三| 青青国产揄拍视频| 精品无人码麻豆乱码1区2区| 国产精品亚洲二区在线看| 久9视频这里只有精品试看| 亚洲欧美牲交| 亚洲午夜久久久影院伊人| 国产精一品亚洲二区在线播放| 亚洲国产成人综合精品| 国产久久热这里只有精品| 精品无码国产自产拍在线观看蜜|