123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- // David Eberly, Geometric Tools, Redmond WA 98052
- // Copyright (c) 1998-2020
- // Distributed under the Boost Software License, Version 1.0.
- // https://www.boost.org/LICENSE_1_0.txt
- // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
- // Version: 4.0.2019.08.13
- #pragma once
- #include <Mathematics/NURBSCurve.h>
- // The algorithm for representing a circle as a NURBS curve or a sphere as a
- // NURBS surface is described in
- // https://www.geometrictools.com/Documentation/NURBSCircleSphere.pdf
- // The implementations are related to the documents as shown next.
- // NURBSQuarterCircleDegree2 implements equation (9)
- // NURBSQuarterCircleDegree4 implements equation (10)
- // NURBSHalfCircleDegree3 implements equation (12)
- // NURBSFullCircleDegree3 implements Section 2.3
- namespace WwiseGTE
- {
- template <typename Real>
- class NURBSQuarterCircleDegree2 : public NURBSCurve<2, Real>
- {
- public:
- // Construction. The quarter circle is x^2 + y^2 = 1 for x >= 0
- // and y >= 0. The direction of traversal is counterclockwise as
- // u increase from 0 to 1.
- NURBSQuarterCircleDegree2()
- :
- NURBSCurve<2, Real>(BasisFunctionInput<Real>(3, 2), nullptr, nullptr)
- {
- Real const sqrt2 = std::sqrt((Real)2);
- this->mWeights[0] = sqrt2;
- this->mWeights[1] = (Real)1;
- this->mWeights[2] = sqrt2;
- this->mControls[0] = { (Real)1, (Real)0 };
- this->mControls[1] = { (Real)1, (Real)1 };
- this->mControls[2] = { (Real)0, (Real)1 };
- }
- };
- template <typename Real>
- class NURBSQuarterCircleDegree4 : public NURBSCurve<2, Real>
- {
- public:
- // Construction. The quarter circle is x^2 + y^2 = 1 for x >= 0
- // and y >= 0. The direction of traversal is counterclockwise as
- // u increases from 0 to 1.
- NURBSQuarterCircleDegree4()
- :
- NURBSCurve<2, Real>(BasisFunctionInput<Real>(5, 4), nullptr, nullptr)
- {
- Real const sqrt2 = std::sqrt((Real)2);
- this->mWeights[0] = (Real)1;
- this->mWeights[1] = (Real)1;
- this->mWeights[2] = (Real)2 * sqrt2 / (Real)3;
- this->mWeights[3] = (Real)1;
- this->mWeights[4] = (Real)1;
- Real const x1 = (Real)1;
- Real const y1 = (Real)0.5 / sqrt2;
- Real const x2 = (Real)1 - sqrt2 / (Real)8;
- this->mControls[0] = { (Real)1, (Real)0 };
- this->mControls[1] = { x1, y1 };
- this->mControls[2] = { x2, x2 };
- this->mControls[3] = { y1, x1 };
- this->mControls[4] = { (Real)0, (Real)1 };
- }
- };
- template <typename Real>
- class NURBSHalfCircleDegree3 : public NURBSCurve<2, Real>
- {
- public:
- // Construction. The half circle is x^2 + y^2 = 1 for x >= 0. The
- // direction of traversal is counterclockwise as u increases from
- // 0 to 1.
- NURBSHalfCircleDegree3()
- :
- NURBSCurve<2, Real>(BasisFunctionInput<Real>(4, 3), nullptr, nullptr)
- {
- Real const oneThird = (Real)1 / (Real)3;
- this->mWeights[0] = (Real)1;
- this->mWeights[1] = oneThird;
- this->mWeights[2] = oneThird;
- this->mWeights[3] = (Real)1;
- this->mControls[0] = { (Real)1, (Real)0 };
- this->mControls[1] = { (Real)1, (Real)2 };
- this->mControls[2] = { (Real)-1, (Real)2 };
- this->mControls[3] = { (Real)-1, (Real)0 };
- }
- };
- template <typename Real>
- class NURBSFullCircleDegree3 : public NURBSCurve<2, Real>
- {
- public:
- // Construction. The full circle is x^2 + y^2 = 1. The direction of
- // traversal is counterclockwise as u increases from 0 to 1.
- NURBSFullCircleDegree3()
- :
- NURBSCurve<2, Real>(CreateBasisFunctionInput(), nullptr, nullptr)
- {
- Real const oneThird = (Real)1 / (Real)3;
- this->mWeights[0] = (Real)1;
- this->mWeights[1] = oneThird;
- this->mWeights[2] = oneThird;
- this->mWeights[3] = (Real)1;
- this->mWeights[4] = oneThird;
- this->mWeights[5] = oneThird;
- this->mWeights[6] = (Real)1;
- this->mControls[0] = { (Real)1, (Real)0 };
- this->mControls[1] = { (Real)1, (Real)2 };
- this->mControls[2] = { (Real)-1, (Real)2 };
- this->mControls[3] = { (Real)-1, (Real)0 };
- this->mControls[4] = { (Real)-1, (Real)-2 };
- this->mControls[5] = { (Real)1, (Real)-2 };
- this->mControls[6] = { (Real)1, (Real)0 };
- }
- private:
- static BasisFunctionInput<Real> CreateBasisFunctionInput()
- {
- // We need knots (0,0,0,0,1/2,1/2,1/2,1,1,1,1).
- BasisFunctionInput<Real> input;
- input.numControls = 7;
- input.degree = 3;
- input.uniform = true;
- input.periodic = false;
- input.numUniqueKnots = 3;
- input.uniqueKnots.resize(input.numUniqueKnots);
- input.uniqueKnots[0] = { (Real)0, 4 };
- input.uniqueKnots[1] = { (Real)0.5, 3 };
- input.uniqueKnots[2] = { (Real)1, 4 };
- return input;
- }
- };
- }
|