NURBSCircle.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/NURBSCurve.h>
  9. // The algorithm for representing a circle as a NURBS curve or a sphere as a
  10. // NURBS surface is described in
  11. // https://www.geometrictools.com/Documentation/NURBSCircleSphere.pdf
  12. // The implementations are related to the documents as shown next.
  13. // NURBSQuarterCircleDegree2 implements equation (9)
  14. // NURBSQuarterCircleDegree4 implements equation (10)
  15. // NURBSHalfCircleDegree3 implements equation (12)
  16. // NURBSFullCircleDegree3 implements Section 2.3
  17. namespace WwiseGTE
  18. {
  19. template <typename Real>
  20. class NURBSQuarterCircleDegree2 : public NURBSCurve<2, Real>
  21. {
  22. public:
  23. // Construction. The quarter circle is x^2 + y^2 = 1 for x >= 0
  24. // and y >= 0. The direction of traversal is counterclockwise as
  25. // u increase from 0 to 1.
  26. NURBSQuarterCircleDegree2()
  27. :
  28. NURBSCurve<2, Real>(BasisFunctionInput<Real>(3, 2), nullptr, nullptr)
  29. {
  30. Real const sqrt2 = std::sqrt((Real)2);
  31. this->mWeights[0] = sqrt2;
  32. this->mWeights[1] = (Real)1;
  33. this->mWeights[2] = sqrt2;
  34. this->mControls[0] = { (Real)1, (Real)0 };
  35. this->mControls[1] = { (Real)1, (Real)1 };
  36. this->mControls[2] = { (Real)0, (Real)1 };
  37. }
  38. };
  39. template <typename Real>
  40. class NURBSQuarterCircleDegree4 : public NURBSCurve<2, Real>
  41. {
  42. public:
  43. // Construction. The quarter circle is x^2 + y^2 = 1 for x >= 0
  44. // and y >= 0. The direction of traversal is counterclockwise as
  45. // u increases from 0 to 1.
  46. NURBSQuarterCircleDegree4()
  47. :
  48. NURBSCurve<2, Real>(BasisFunctionInput<Real>(5, 4), nullptr, nullptr)
  49. {
  50. Real const sqrt2 = std::sqrt((Real)2);
  51. this->mWeights[0] = (Real)1;
  52. this->mWeights[1] = (Real)1;
  53. this->mWeights[2] = (Real)2 * sqrt2 / (Real)3;
  54. this->mWeights[3] = (Real)1;
  55. this->mWeights[4] = (Real)1;
  56. Real const x1 = (Real)1;
  57. Real const y1 = (Real)0.5 / sqrt2;
  58. Real const x2 = (Real)1 - sqrt2 / (Real)8;
  59. this->mControls[0] = { (Real)1, (Real)0 };
  60. this->mControls[1] = { x1, y1 };
  61. this->mControls[2] = { x2, x2 };
  62. this->mControls[3] = { y1, x1 };
  63. this->mControls[4] = { (Real)0, (Real)1 };
  64. }
  65. };
  66. template <typename Real>
  67. class NURBSHalfCircleDegree3 : public NURBSCurve<2, Real>
  68. {
  69. public:
  70. // Construction. The half circle is x^2 + y^2 = 1 for x >= 0. The
  71. // direction of traversal is counterclockwise as u increases from
  72. // 0 to 1.
  73. NURBSHalfCircleDegree3()
  74. :
  75. NURBSCurve<2, Real>(BasisFunctionInput<Real>(4, 3), nullptr, nullptr)
  76. {
  77. Real const oneThird = (Real)1 / (Real)3;
  78. this->mWeights[0] = (Real)1;
  79. this->mWeights[1] = oneThird;
  80. this->mWeights[2] = oneThird;
  81. this->mWeights[3] = (Real)1;
  82. this->mControls[0] = { (Real)1, (Real)0 };
  83. this->mControls[1] = { (Real)1, (Real)2 };
  84. this->mControls[2] = { (Real)-1, (Real)2 };
  85. this->mControls[3] = { (Real)-1, (Real)0 };
  86. }
  87. };
  88. template <typename Real>
  89. class NURBSFullCircleDegree3 : public NURBSCurve<2, Real>
  90. {
  91. public:
  92. // Construction. The full circle is x^2 + y^2 = 1. The direction of
  93. // traversal is counterclockwise as u increases from 0 to 1.
  94. NURBSFullCircleDegree3()
  95. :
  96. NURBSCurve<2, Real>(CreateBasisFunctionInput(), nullptr, nullptr)
  97. {
  98. Real const oneThird = (Real)1 / (Real)3;
  99. this->mWeights[0] = (Real)1;
  100. this->mWeights[1] = oneThird;
  101. this->mWeights[2] = oneThird;
  102. this->mWeights[3] = (Real)1;
  103. this->mWeights[4] = oneThird;
  104. this->mWeights[5] = oneThird;
  105. this->mWeights[6] = (Real)1;
  106. this->mControls[0] = { (Real)1, (Real)0 };
  107. this->mControls[1] = { (Real)1, (Real)2 };
  108. this->mControls[2] = { (Real)-1, (Real)2 };
  109. this->mControls[3] = { (Real)-1, (Real)0 };
  110. this->mControls[4] = { (Real)-1, (Real)-2 };
  111. this->mControls[5] = { (Real)1, (Real)-2 };
  112. this->mControls[6] = { (Real)1, (Real)0 };
  113. }
  114. private:
  115. static BasisFunctionInput<Real> CreateBasisFunctionInput()
  116. {
  117. // We need knots (0,0,0,0,1/2,1/2,1/2,1,1,1,1).
  118. BasisFunctionInput<Real> input;
  119. input.numControls = 7;
  120. input.degree = 3;
  121. input.uniform = true;
  122. input.periodic = false;
  123. input.numUniqueKnots = 3;
  124. input.uniqueKnots.resize(input.numUniqueKnots);
  125. input.uniqueKnots[0] = { (Real)0, 4 };
  126. input.uniqueKnots[1] = { (Real)0.5, 3 };
  127. input.uniqueKnots[2] = { (Real)1, 4 };
  128. return input;
  129. }
  130. };
  131. }