home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gems / gemsiii / beziertr.c < prev    next >
C/C++ Source or Header  |  1992-03-19  |  4KB  |  120 lines

  1. /***************************************************************************
  2.  
  3.   This is C++ code. Given here are skeleton class definitions for the
  4.   control points (ControlPoint), quadratic and cubic Bezier
  5.   triangles (BezierTri2 and BezierTri3, respectively), and for the
  6.   bi-quadratic and bi-cubic Bezier patches (BezierRect2 and BezierRect3).
  7.   The conversion described in the gem takes place in the constructors
  8.   provided for BezierRect2 and BezierRect3, which each take a Bezier
  9.   triangle (of appropriate degree) as an argument.
  10.  
  11.   Note that the ControlPoint does not have to be to be an (x,y,z) triplet.
  12.   For instance, it can be a scalar, an RGB triplet, etc., as long as the
  13.   operators +, *, /, and = (assignment) are provided. If you have a
  14.   class that you wish to use instead of the one given in the code, all
  15.   you have to do is to remove the definitions of the ControlPoint class
  16.   and its operators, and insert instead something like:
  17.  
  18.     #include <my_class.h>
  19.     typedef MyClass ControlPoint;
  20.  
  21. ***************************************************************************/
  22.  
  23. class ControlPoint {
  24.     friend ControlPoint operator+(const ControlPoint&, const ControlPoint&);
  25.     friend ControlPoint operator*(float, const ControlPoint&);
  26.     friend ControlPoint operator/(const ControlPoint&, float);
  27. private:
  28.     float x, y, z;
  29. public:
  30.     ControlPoint() {}
  31.     ControlPoint(float a, float b, float c)    { x = a; y = b; z = c; }
  32. };
  33.  
  34. ControlPoint operator+(const ControlPoint& a, const ControlPoint& b)
  35. {
  36.     return ControlPoint(a.x + b.x, a.y + b.y, a.z + b.z);
  37. }
  38.  
  39. ControlPoint operator*(float c, const ControlPoint& a)
  40. {
  41.     return ControlPoint(c * a.x, c * a.y, c * a.z);
  42. }
  43.  
  44. ControlPoint operator/(const ControlPoint& a, float c)
  45. {
  46.     return ControlPoint(a.x / c, a.y / c, a.z / c);
  47. }
  48.  
  49. class BezierTri2 {
  50. private:
  51.     ControlPoint cp[6];
  52. public:
  53.     const ControlPoint& b(int, int, int) const;
  54. };
  55.  
  56. const ControlPoint& BezierTri2::b(int i, int j, int /* k */) const
  57. {
  58.     static int row_start[3] = {0, 3, 5};
  59.     return cp[row_start[j] + i];
  60. }
  61.  
  62. class BezierTri3 {
  63. private:
  64.     ControlPoint cp[10];
  65. public:
  66.     const ControlPoint& b(int, int, int) const;
  67. };
  68.  
  69. const ControlPoint& BezierTri3::b(int i, int j, int /* k */) const
  70. {
  71.     static int row_start[4] = {0, 4, 7, 9};
  72.     return cp[row_start[j] + i];
  73. }
  74.  
  75. class BezierRect2 {
  76. private:
  77.     ControlPoint cp[3][3];
  78. public:
  79.     BezierRect2(const BezierTri2&);
  80.     ControlPoint& p(int i, int j)       { return cp[i][j]; }
  81. };
  82.  
  83. BezierRect2::BezierRect2(const BezierTri2& bt)
  84. // convert a quadratic triangle into a bi-quadratic patch
  85. {
  86.     p(0,0) = bt.b(0,0,2);
  87.     p(0,1) = bt.b(1,0,1);
  88.     p(0,2) = bt.b(2,0,0);
  89.     p(1,0) = bt.b(0,1,1);
  90.     p(1,1) = (bt.b(0,1,1) + bt.b(1,1,0)) / 2;
  91.     p(1,2) = bt.b(1,1,0);
  92.     p(2,0) = p(2,1) = p(2,2) = bt.b(0,2,0);
  93. }
  94.  
  95. class BezierRect3 {
  96. private:
  97.     ControlPoint cp[4][4];
  98. public:
  99.     BezierRect3(const BezierTri3&);
  100.     ControlPoint& p(int i, int j)       { return cp[i][j]; }
  101. };
  102.  
  103. BezierRect3::BezierRect3(const BezierTri3& bt)
  104. // convert a cubic triangle into a bi-cubic patch
  105. {
  106.     p(0,0) = bt.b(0,0,3);
  107.     p(0,1) = bt.b(1,0,2);
  108.     p(0,2) = bt.b(2,0,1);
  109.     p(0,3) = bt.b(3,0,0);
  110.     p(1,0) = bt.b(0,1,2);
  111.     p(1,1) = (bt.b(0,1,2) + 2*bt.b(1,1,1)) / 3;
  112.     p(1,2) = (bt.b(2,1,0) + 2*bt.b(1,1,1)) / 3;
  113.     p(1,3) = bt.b(2,1,0);
  114.     p(2,0) = bt.b(0,2,1);
  115.     p(2,1) = (bt.b(1,2,0) + 2*bt.b(0,2,1)) / 3;
  116.     p(2,2) = (bt.b(0,2,1) + 2*bt.b(1,2,0)) / 3;
  117.     p(2,3) = bt.b(1,2,0);
  118.     p(3,0) = p(3,1) = p(3,2) = p(3,3) = bt.b(0,3,0);
  119. }
  120.