样条之贝塞尔(Bezier) -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

     我曾经发过两篇关于贝塞尔的文章:数学图形(1.47)贝塞尔(Bézier)曲线,数学图形之贝塞尔(Bézier)曲面,

样条之贝塞尔(Bezier)

。那是使用我自己定义的脚本语言生成贝塞尔图形。由于我自己定义的脚本语法功能有限,所以最多只能支持5次贝塞尔函数,而这里将实现N次。

    N阶贝塞尔曲线可如下推断:

    给定点P0、P1、…、Pn,其贝塞尔曲线即

    \mathbf{B}(t)=\sum_{i=0}^n {n\choose i}\mathbf{P}_i(1-t)^{n-i}t^i ={n\choose 0}\mathbf{P}_0(1-t)^nt^{0}+{n\choose 1}\mathbf{P}_1(1-t)^{n-1}t^{1}+\cdots+{n\choose n-1}\mathbf{P}_{n-1}(1-t)^{1}t^{n-1}+{n\choose n}\mathbf{P}_n(1-t)^{0}t^n \mbox{ , } t \in [0,1]

    看其公式需要先为之生成一套杨辉三角形数组。

    关于插值与样条的介绍请看:http://www.cnblogs.com/WhyEngine/p/4020294.html

    .h文件

    复制代码

    1 /****************************************************************

    2

    3 File name : YcBezierSpline.h

    4 Author   : 叶峰

    5 Version  : 2.0

    6 Create Date : 2014/08/18

    7 Description : Bezier样条

    8

    9 *****************************************************************/

    10

    11 #ifndef __YcBezierSpline_H__

    12 #define __YcBezierSpline_H__

    13

    14 // INCLUDES -----------------------------------------------------------------------------

    15

    16 #include "YicSpline.h"

    17

    18 // --------------------------------------------------------------------------------------

    19

    20 #define YD_MAX_BEZIER_CONTROL_VALUE 33

    21

    22 // --------------------------------------------------------------------------------------

    23

    24 class YcBezierSpline : public YicSpline

    25 {

    26 public:

    27  YcBezierSpline();

    28

    29  ~YcBezierSpline();

    30

    31  // 设置输出样条值的数目

    32  void  SetSplineValuesCount(Yuint count);

    33

    34  // 获得输出样条值的数目

    35  Yuint GetSplineValuesCount() const;

    36

    37  // 计算样条数值

    38  bool  BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount,

    39    void* splineValuesPtr, Yuint splineStride) const;

    40

    41 protected:

    42  void  ClearPowT();

    43

    44  void  BuildPowT();

    45

    46  Yreal  GetValueT(Yint t, Yint p) const

    47  {

    48    return m_pow_t[YD_MAX_BEZIER_CONTROL_VALUE*t + p];

    49  }

    50

    51 protected:

    52  Yuint m_valuesCount;

    53  Yreal* m_pow_t;

    54

    55 protected:

    56  static void  BuildYanghuiTriangle();

    57  static Yint m_yanghuiRowIndex[YD_MAX_BEZIER_CONTROL_VALUE];

    58  static Yint m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2];

    59 };

    60

    61 // --------------------------------------------------------------------------------------

    62

    63 #endif

    复制代码

    CPP文件

    复制代码

    1 /****************************************************************

    2

    3 File name : YcBezierSpline.cpp

    4 Author   : 叶峰

    5 Version  : 2.0

    6 Create Date : 2014/08/18

    7 Description :

    8

    9 *****************************************************************/

    10

    11 // INCLUDES -----------------------------------------------------------------------------

    12

    13 #include "..\..\YCommon_h\YSpline\YcBezierSpline.h"

    14 #include

    15

    16 // --------------------------------------------------------------------------------------

    17

    18 Yint  YcBezierSpline::m_yanghuiRowIndex[YD_MAX_BEZIER_CONTROL_VALUE] = {0};

    19 Yint  YcBezierSpline::m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2] = {0};

    20

    21 void  YcBezierSpline::BuildYanghuiTriangle()

    22 {

    23  // 第0行

    24  m_yanghuiRowIndex[0] = 0;

    25  m_yanghuiTriangle[0] = 1;

    26

    27  Yint index = 1;

    28  Yint t0,t1;

    29  Yint* lastRow;

    30  for (Yint i = 1; i < YD_MAX_BEZIER_CONTROL_VALUE; i++)

    31  {

    32    m_yanghuiRowIndex[i] = index;

    33    m_yanghuiTriangle[index] = 1;

    34    index++;

    35

    36    for (Yint j = 1; j <= i; j++)

    37    {

    38      lastRow = m_yanghuiTriangle + m_yanghuiRowIndex[i-1];

    39      t0 = lastRow[j - 1];

    40      t1 = (j < i) ? lastRow[j] : 0;

    41

    42      m_yanghuiTriangle[index] = t0 + t1;

    43      index++;

    44    }

    45  }

    46

    47  assert(index == (YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2);

    48 }

    49

    50 // --------------------------------------------------------------------------------------

    51

    52 YcBezierSpline::YcBezierSpline()

    53 {

    54  if (m_yanghuiTriangle[0] == 0)

    55  {

    56    BuildYanghuiTriangle();

    57  }

    58

    59  m_valuesCount = 0;

    60  m_pow_t = NULL;

    61

    62  SetSplineValuesCount(100);

    63 }

    64

    65 YcBezierSpline::~YcBezierSpline()

    66 {

    67  ClearPowT();

    68 }

    69

    70 // 设置输出样条值的数目

    71 void YcBezierSpline::SetSplineValuesCount(Yuint count)

    72 {

    73  if (count < 2)

    74  {

    75    count = 2;

    76  }

    77

    78  if (count == m_valuesCount)

    79  {

    80    return;

    81  }

    82  m_valuesCount = count;

    83  BuildPowT();

    84 }

    85

    86 // 获得输出样条值的数目

    87 Yuint YcBezierSpline::GetSplineValuesCount() const

    88 {

    89  return m_valuesCount;

    90 }

    91

    92 void  YcBezierSpline::ClearPowT()

    93 {

    94  if (m_pow_t)

    95  {

    96    free(m_pow_t);

    97    m_pow_t = NULL;

    98  }

    99 }

    100

    101 void  YcBezierSpline::BuildPowT()

    102 {

    103  ClearPowT();

    104

    105  m_pow_t = (Yreal*)malloc(m_valuesCount*YD_MAX_BEZIER_CONTROL_VALUE*sizeof(Yreal));

    106  Yreal t;

    107  for (Yuint i = 0; i < m_valuesCount; i++)

    108  {

    109    t = i/(m_valuesCount - 1.0f);

    110

    111    m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE] = 1.0f;

    112    for (Yint j = 1; j < YD_MAX_BEZIER_CONTROL_VALUE; j++)

    113    {

    114      m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE + j] = m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE + j - 1]*t;

    115    }

    116  }

    117 }

    118

    119 // 计算样条数值

    120 bool  YcBezierSpline::BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount,

    121  void* splineValuesPtr, Yuint splineStride) const

    122 {

    123  if (ctrlCount < 2 || ctrlCount > YD_MAX_BEZIER_CONTROL_VALUE)

    124  {

    125    return false;

    126  }

    127

    128  Yreal* destValue;

    129  Yreal* srcValue;

    130  Yreal v;

    131  const Yint* yanghuiRow = m_yanghuiTriangle + m_yanghuiRowIndex[ctrlCount - 1];

    132

    133  for (Yuint i = 0; i < m_valuesCount; i++)

    134  {

    135    v = 0.0f;

    136    for (Yuint j = 0; j < ctrlCount; j++)

    137    {

    138      srcValue = (Yreal*)((char*)ctrlValuesPtr + ctrlStride*j);

    139      v += yanghuiRow[j] * (*srcValue) * GetValueT(i, j) * GetValueT(m_valuesCount - 1 - i, ctrlCount - 1 - j);

    140    }

    141

    142    destValue = (Yreal*)((char*)splineValuesPtr + splineStride*i);

    143    *destValue = v;

    144  }

    145

    146  return true;

    147 }

    148

    149 // --------------------------------------------------------------------------------------

最新文章