TexGen
InterpolationCubic.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2006 Martin Sherburn
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18=============================================================================*/
19
20#include "PrecompiledHeaders.h"
21#include "InterpolationCubic.h"
22#include "Matrix.h"
23using namespace TexGen;
24
25CInterpolationCubic::CInterpolationCubic(bool bPeriodic, bool bForceInPlaneTangent, bool bForceMasterNodeTangent)
26: CInterpolation(bPeriodic, bForceInPlaneTangent, bForceMasterNodeTangent)
27{
28}
29
31{
32}
33
35: CInterpolation(Element)
36{
37 // TODO: IMPLEMENT ME
38}
39
40/*
41void CInterpolationCubic::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
42{
43}*/
44
45CSlaveNode CInterpolationCubic::GetNode(const vector<CNode> &MasterNodes, int iIndex, double t) const
46{
47 assert(iIndex >= 0 && iIndex < int(MasterNodes.size()-1));
48 // Errors may occur here if the Initialise function was not called before
49 // calling this function. For performance reasons it is necessary to call
50 // initialise once at the start before making calls to this function
51 assert(m_XCubics.size() == MasterNodes.size()-1);
52 assert(m_YCubics.size() == MasterNodes.size()-1);
53 assert(m_ZCubics.size() == MasterNodes.size()-1);
54
55 XYZ Pos, Tangent;
56
57 Pos.x = m_XCubics[iIndex].Evaluate(t);
58 Pos.y = m_YCubics[iIndex].Evaluate(t);
59 Pos.z = m_ZCubics[iIndex].Evaluate(t);
60
61 Tangent.x = m_XCubics[iIndex].EvaluateDerivative(t);
62 Tangent.y = m_YCubics[iIndex].EvaluateDerivative(t);
63 Tangent.z = m_ZCubics[iIndex].EvaluateDerivative(t);
64
66 Tangent.z = 0;
67
68 Normalise(Tangent);
69
70 CSlaveNode NewNode(Pos, Tangent);
71
72 InterpolateUp(MasterNodes[iIndex], MasterNodes[iIndex+1], NewNode, t);
73 InterpolateAngle(MasterNodes[iIndex], MasterNodes[iIndex+1], NewNode, t);
74
75 NewNode.SetIndex(iIndex);
76 NewNode.SetT(t);
77
78 return NewNode;
79}
80
81void CInterpolationCubic::Initialise(const vector<CNode> &MasterNodes) const
82{
83 vector<double> X;
84 vector<double> Y;
85 vector<double> Z;
86 vector<CNode>::const_iterator itNode;
87 for (itNode = MasterNodes.begin(); itNode != MasterNodes.end(); ++itNode)
88 {
89 X.push_back(itNode->GetPosition().x);
90 Y.push_back(itNode->GetPosition().y);
91 Z.push_back(itNode->GetPosition().z);
92 }
93 if (m_bPeriodic)
94 {
98 }
99 else
100 {
104 }
105}
106
107void CInterpolationCubic::GetPeriodicCubicSplines(const vector<double> &Knots, vector<CUBICEQUATION> &Cubics)
108{
109/*
110 We solve the equation
111 [4 1 1] [ D[0] ] [ 3((x[1] - x[0])+(x[n]-x[n-1])) ]
112 |1 4 1 | | D[1] | | 3(x[2] - x[0]) |
113 | 1 4 1 | | . | = | . |
114 | ..... | | . | | . |
115 | 1 4 1| | . | | 3(x[n-1] - x[n-3]) |
116 [1 1 4] [D[n-1]] [ 3(x[n] - x[n-2]) ]
117
118 Where x is the knots and D is the derivatives at the knots
119 Adapted from: http://www.cse.unsw.edu.au/~lambert/splines/NatCubicClosed.java
120
121 Also see http://mathworld.wolfram.com/CubicSpline.html
122*/
123 Cubics.clear();
124
125 int n = int(Knots.size()-1);
126
127 if (n <= 0)
128 return;
129
130 CMatrix Left(n, n);
131 CMatrix Right(n, 1);
132 CMatrix D;
133
134 int i;
135
136 // Populate Left Matrix as shown above
137 for (i=0; i<n; ++i)
138 {
139 Left(i, i) = 4;
140 if (i < n-1)
141 {
142 Left(i+1, i) = 1;
143 Left(i, i+1) = 1;
144 }
145 }
146 Left(n-1, 0) += 1;
147 Left(0, n-1) += 1;
148
149 // Populate the Right Matrix as shown above
150 Right(0, 0) = 3*((Knots[1] - Knots[0])+(Knots[n] - Knots[n-1]));
151 for (i=1; i<n; ++i)
152 {
153 Right(i, 0) = 3*(Knots[i+1] - Knots[i-1]);
154 }
155
156 // Get the Inverse of the left matrix
157 CMatrix LeftInverse;
158 Left.GetInverse(LeftInverse);
159 D.EqualsMultiple(LeftInverse, Right);
160
161 // D now contains the derivatives at the knots
162
163 double a, b, c, d;
164
165 // Calculate the coefficients of the cubics
166 for (i=0; i<n-1; ++i)
167 {
168 a = Knots[i];
169 b = D(i, 0);
170 c = 3*(Knots[i+1] - Knots[i]) - 2*D(i, 0) - D(i+1, 0);
171 d = 2*(Knots[i] - Knots[i+1]) + D(i, 0) + D(i+1, 0);
172
173 Cubics.push_back(CUBICEQUATION(a, b, c, d));
174 }
175 a = Knots[n-1];
176 b = D(n-1, 0);
177 c = 3*(Knots[n] - Knots[n-1]) - 2*D(n-1, 0) - D(0, 0);
178 d = 2*(Knots[n-1] - Knots[n]) + D(n-1, 0) + D(0, 0);
179
180 Cubics.push_back(CUBICEQUATION(a, b, c, d));
181}
182
183void CInterpolationCubic::GetNaturalCubicSplines(const vector<double> &Knots, vector<CUBICEQUATION> &Cubics)
184{
185/*
186 We solve the equation
187 [2 1 ] [ D[0] ] [ 3(x[1] - x[0]) ]
188 |1 4 1 | | D[1] | | 3(x[2] - x[0]) |
189 | 1 4 1 | | . | = | . |
190 | ..... | | . | | . |
191 | 1 4 1| | . | |3(x[n-1] - x[n-3])|
192 [ 1 2] [D[n-1]] [3(x[n-1] - x[n-2])]
193
194 Where x is the knots and D is the derivatives at the knots
195 Adapted from: http://www.cse.unsw.edu.au/~lambert/splines/NatCubic.java
196
197 Also see http://mathworld.wolfram.com/CubicSpline.html
198*/
199 Cubics.clear();
200
201 int n = int(Knots.size());
202
203 if (n <= 0)
204 return;
205
206 CMatrix Left(n, n);
207 CMatrix Right(n, 1);
208 CMatrix D;
209
210 int i;
211
212 // Populate Left Matrix as shown above
213 for (i=0; i<n-1; ++i)
214 {
215 Left(i, i) = 4;
216 Left(i+1, i) = 1;
217 Left(i, i+1) = 1;
218 }
219 Left(0, 0) = 2;
220 Left(n-1, n-1) = 2;
221
222 // Populate the Right Matrix as shown above
223 Right(0, 0) = 3*((Knots[1] - Knots[0]));
224 for (i=1; i<n-1; ++i)
225 {
226 Right(i, 0) = 3*(Knots[i+1] - Knots[i-1]);
227 }
228 Right(n-1, 0) = 3*(Knots[n-1] - Knots[n-2]);
229
230 // Get the Inverse of the left matrix
231 CMatrix LeftInverse;
232 Left.GetInverse(LeftInverse);
233 D.EqualsMultiple(LeftInverse, Right);
234
235 // D now contains the derivatives at the knots
236
237 double a, b, c, d;
238
239 // Calculate the coefficients of the cubics
240 for (i=0; i<n-1; ++i)
241 {
242 a = Knots[i];
243 b = D(i, 0);
244 c = 3*(Knots[i+1] - Knots[i]) - 2*D(i, 0) - D(i+1, 0);
245 d = 2*(Knots[i] - Knots[i+1]) + D(i, 0) + D(i+1, 0);
246
247 Cubics.push_back(CUBICEQUATION(a, b, c, d));
248 }
249}
250
251
252
253
254
255
CSlaveNode GetNode(const vector< CNode > &MasterNodes, int iIndex, double t) const
Get a node from parametric function where t is specified.
vector< CUBICEQUATION > m_XCubics
static void GetPeriodicCubicSplines(const vector< double > &Knots, vector< CUBICEQUATION > &Cubics)
CInterpolationCubic(bool bPeriodic=true, bool bForceInPlaneTangent=false, bool bForceMasterNodeTangent=false)
vector< CUBICEQUATION > m_YCubics
void Initialise(const vector< CNode > &MasterNodes) const
Create the spline cubic equations and store them in m_?Cubics.
static void GetNaturalCubicSplines(const vector< double > &Knots, vector< CUBICEQUATION > &Cubics)
vector< CUBICEQUATION > m_ZCubics
Abstract base class for describing the yarn path interpolations.
Definition: Interpolation.h:33
static void InterpolateUp(const CNode &Node1, const CNode &Node2, CSlaveNode &SlaveNode, double t)
static void InterpolateAngle(const CNode &Node1, const CNode &Node2, CSlaveNode &SlaveNode, double t)
Class to represent a matrix and perform various operations on it.
Definition: Matrix.h:33
double GetInverse(CMatrix &Inverse) const
Definition: Matrix.h:544
CMatrix & EqualsMultiple(const CMatrix &LeftMatrix, const CMatrix &RightMatrix)
This function multiplies the left matrix with the right matrix.
Definition: Matrix.h:293
A derivation of the CNode class which contains data specific to slave nodes such as sections.
Definition: SlaveNode.h:30
void SetT(double t)
Definition: SlaveNode.h:71
void SetIndex(int iIndex)
Definition: SlaveNode.h:73
Namespace containing a series of customised math operations not found in the standard c++ library.
WXYZ & Normalise(WXYZ &Quaternion)
Normalise the quaternion and return it.
Definition: mymath.h:609
Struct to represent a cubic equation.
Struct for representing points in 3D space.
Definition: mymath.h:56
double z
Definition: mymath.h:57
double x
Definition: mymath.h:57
double y
Definition: mymath.h:57