00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "PreCompiled.h"
00027 #include <cmath>
00028 #include "routine.h"
00029
00030
00032 #include <boost/numeric/ublas/matrix.hpp>
00033 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00034 #include <boost/numeric/bindings/atlas/clapack.hpp>
00035
00036 using namespace boost::numeric::bindings;
00037 using namespace boost::numeric;
00038
00039
00040
00047 double Routines::TrapezoidIntergration(const std::vector<double> &WithRespectTo, const std::vector<double> &Integral)
00048 {
00049 m_h = 0;
00050 m_result = 0;
00051 m_N = Integral.size();
00052 if (m_N==1)
00053 {
00054 m_result = 0;
00055 return m_result;
00056 }
00057
00058 m_h = WithRespectTo[1] - WithRespectTo[0];
00059 for (int i=1; i< m_N - 1; i++)
00060 m_result = m_result + Integral[i];
00061
00062 m_result = m_h/2 * (Integral[0] + 2*(m_result) + Integral[m_N -1]);
00063 return m_result;
00064 }
00065
00066 std::vector<double> Routines::NewtonStep(std::vector<double> &F,std::vector<std::vector<double> > &DF)
00067 {
00068
00069 int siz = (int) F.size();
00070 std::vector<double> x_new(siz);
00071 std::vector<int> piv(siz);
00072
00073 ublas::matrix<double> A(siz, siz);
00074 ublas::matrix<double> b(1, siz);
00075
00076
00077 for (unsigned int i=0; i<siz; ++i)
00078 {
00079 b(0,i) = -F[i];
00080 for (unsigned int j=0; j<siz; ++j)
00081 {
00082 A(i,j) = DF[i][j];
00083 }
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 atlas::lu_factor(A,piv);
00093 atlas::getrs(A,piv,b);
00094
00095 for (unsigned int i=0; i<siz; ++i)
00096 {
00097 x_new[i] = b(0,i);
00098 }
00099
00100 return x_new;
00101 }
00102
00103
00110 void Routines::CramerSolve(std::vector< std::vector<double> > &RHS1, std::vector<double>& RHS2, std::vector<double> &LHS)
00111 {
00112 double MainMatrixDet = det2(RHS1);
00113 std::vector< std::vector<double> > Temp(2,std::vector<double>(2,0.0));
00114 for (int i = 0; i < 2; i++)
00115 for (int j = 0; j < 2; j++)
00116 Temp[i][j] = RHS1[i][j];
00117
00118
00119 for (int i = 0; i < 2; i++)
00120 Temp[i][0] = RHS2[i];
00121
00122 LHS[0] = det2(Temp) / MainMatrixDet;
00123
00124
00125 for (int i = 0; i < 2; i++)
00126 for (int j = 0; j < 2; j++)
00127 Temp[i][j] = RHS1[i][j];
00128
00129
00130 for (int i = 0; i < 2; i++)
00131 Temp[i][1] = RHS2[i];
00132
00133 LHS[1] = det2(Temp) / MainMatrixDet;
00134 }
00135
00140 double Routines::CalcAngle(Base::Vector3f a,Base::Vector3f b,Base::Vector3f c)
00141 {
00142 Base::Vector3f First = a - b;
00143 Base::Vector3f Second = c - b;
00144 Base::Vector3f Third = c - a;
00145
00146 double UpperTerm = (First.Length() * First.Length()) + (Second.Length() *Second.Length()) - (Third.Length() * Third.Length() );
00147 double LowerTerm = 2 * First.Length() * Second.Length() ;
00148 double ang = acos( UpperTerm / LowerTerm );
00149 return ang;
00150 }
00151
00152
00153
00154
00155
00157 int Routines::FindSpan(int n, int p, double u, std::vector<double> KnotSequence)
00158 {
00159 if (u == KnotSequence[n+1])
00160 return n;
00161 int low, high, mid, i;
00162 i = 0;
00163 low = p;
00164 high = n+1;
00165 mid = (low+high) / 2;
00166 while (u < KnotSequence[mid] || u >= KnotSequence[mid+1])
00167 {
00168 if (u < KnotSequence[mid])
00169 high = mid;
00170 else
00171 low = mid;
00172 mid = (low + high) / 2;
00173 i++;
00174 }
00175
00176 return mid;
00177
00178 }
00179
00180
00182 void Routines::Basisfun(int i, double u, int p, std::vector<double> &KnotSequence, std::vector<double> &output)
00183 {
00184 double temp, saved;
00185 std::vector<double> leftie(p+1, 0.0);
00186 std::vector<double> rightie(p+1, 0.0);
00187 output[0] = 1.0;
00188 for (int j = 1; j <= p; j++)
00189 {
00190 leftie[j] = u - KnotSequence[i+1-j];
00191 rightie[j] = KnotSequence[i+j] - u;
00192 saved = 0.0;
00193 for (int r = 0; r < j; r++)
00194 {
00195 temp = output[r] / (rightie[r+1] + leftie[j-r]);
00196 output[r] = saved + (rightie[r+1]*temp);
00197 saved = leftie[j-r]*temp;
00198 }
00199 output[j] = saved;
00200 }
00201 }
00203 void Routines::DersBasisFuns(int i, double u, int p, int n,
00204 std::vector<double> &KnotSequence, std::vector< std::vector<double> > &Derivate)
00205 {
00206 std::vector< std::vector<double> > ndu(p+1, std::vector<double>(p+1,0.0));
00207 std::vector< std::vector<double> > a(2, std::vector<double>(p+1,0.0));
00208 std::vector<double> leftie(p+1, 0.0);
00209 std::vector<double> rightie(p+1, 0.0);
00210 ndu[0][0] = 1.0;
00211 for (int j = 1; j <= p; j++)
00212 {
00213 leftie[j] = u - KnotSequence[i+1-j];
00214 rightie[j] = KnotSequence[i+j] - u;
00215 double saved = 0.0;
00216 for (int r = 0; r < j; r++)
00217 {
00218 ndu[j][r] = rightie[r+1] + leftie[j-r];
00219 double temp = ndu[r][j-1] / ndu[j][r];
00220
00221 ndu[r][j] = saved + rightie[r+1]*temp;
00222 saved = leftie[j-r]*temp;
00223 }
00224 ndu[j][j] = saved;
00225 }
00226 for (int j = 0; j <= p; j++)
00227 Derivate[0][j] = ndu[j][p];
00228
00229 for (int r = 0; r <= p; r++)
00230 {
00231 int j1, j2;
00232 int s1 = 0;
00233 int s2 = 1;
00234 a[0][0] = 1.0;
00235 for (int k = 1; k <= n; k++)
00236 {
00237 double d = 0.0;
00238 int j;
00239 int rk = r - k;
00240 int pk = p - k;
00241 if (r >= k)
00242 {
00243 a[s2][0] = a[s1][0] / ndu[pk+1][rk];
00244 d += a[s2][0] * ndu[rk][pk];
00245 }
00246
00247 if (rk >= -1)
00248 j1 = 1;
00249 else j1 = -rk;
00250
00251 if (r -1 <= pk)
00252 j2 = k -1;
00253 else j2 = p - r;
00254
00255 for (j = j1; j <= j2; j++)
00256 {
00257 a[s2][j] = (a[s1][j]-a[s1][j-1]) / ndu[pk+1][rk+j];
00258 d += a[s2][j] * ndu[rk+j][pk];
00259 }
00260
00261 if (r <= pk)
00262 {
00263 a[s2][k] = -a[s1][k-1] / ndu[pk+1][r];
00264 d += a[s2][k] * ndu[r][pk];
00265 }
00266
00267 Derivate[k][r] = d;
00268 j = s1;
00269 s1 = s2;
00270 s2 = j;
00271
00272
00273 }
00274 }
00275 int r = p;
00276 for (int k = 1; k <= n; k++)
00277 {
00278 for (int j = 0; j <= p; j++)
00279 Derivate[k][j] *= r;
00280
00281 r*= (p-k);
00282 }
00283
00284
00285 }
00287 void Routines::PointNrbEval(std::vector<double> &p, std::vector<double> &CurPoint, NURBS &MainNurb)
00288 {
00289 if (!p.empty())
00290 p.clear();
00291 int i = 0, j = 0;
00292
00293 std::vector< std::vector<double> > CntrlPoints(((MainNurb.MaxU+1)*3), std::vector<double>((MainNurb.MaxV+1), 0.0));
00294 for (unsigned int a = 0; a < MainNurb.CntrlArray.size(); )
00295 {
00296 CntrlPoints[i][j] = MainNurb.CntrlArray[a];
00297 CntrlPoints[i+1][j] = MainNurb.CntrlArray[a+1];
00298 CntrlPoints[i+2][j] = MainNurb.CntrlArray[a+2];
00299 i += 3;
00300 a += 3;
00301 if (i == ((MainNurb.MaxU+1)*3))
00302 {
00303 i = 0;
00304 j++;
00305 }
00306
00307 }
00308
00309 i = 0;
00310 std::vector<double> Output(CntrlPoints.size(), 0.0);
00311 PointBSPEval(MainNurb.DegreeV, CntrlPoints, MainNurb.KnotV, Output, CurPoint[1]);
00312 std::vector< std::vector<double> > RedoneOutput(3, std::vector<double>(MainNurb.MaxU+1, 0.0));
00313 for (unsigned int a = 0; a < Output.size(); )
00314 {
00315 RedoneOutput[0][i] = Output[a];
00316 RedoneOutput[1][i] = Output[a+1];
00317 RedoneOutput[2][i] = Output[a+2];
00318 a += 3;
00319 i++;
00320 }
00321 std::vector<double> OutVect(4,0.0);
00322 PointBSPEval(MainNurb.DegreeU, RedoneOutput, MainNurb.KnotU, OutVect,CurPoint[0]);
00323 p.push_back(OutVect[0]);
00324 p.push_back(OutVect[1]);
00325 p.push_back(OutVect[2]);
00326
00327
00328 }
00329
00331 void Routines::PointBSPEval(int Degree, std::vector< std::vector<double> > &Cntrl, std::vector<double> &KnotSequence,
00332 std::vector< double > &Output, double CurEvalPoint)
00333 {
00334 std::vector<double> Basis(Degree+1, 0.0);
00335 int s = FindSpan(Cntrl[0].size() - 1,Degree,CurEvalPoint,KnotSequence);
00336 Basisfun(s,CurEvalPoint,Degree,KnotSequence,Basis);
00337 int tmp1 = s - Degree;
00338 for (unsigned int row = 0;row < Cntrl.size();row++)
00339 {
00340 double tmp2 = 0.0;
00341 for (int i = 0; i <= Degree; i++)
00342 tmp2 += Basis[i] *Cntrl[row][tmp1+i];
00343 Output[row] = tmp2;
00344 }
00345
00346 }
00348 void Routines::PointNrbDerivate(NURBS MainNurb, std::vector<NURBS> &OutNurbs)
00349 {
00350 if (!OutNurbs.empty())
00351 OutNurbs.clear();
00352 NURBS Temp;
00353 int i = 0, j = 0, k = 0;
00354 std::vector< std::vector<double> > ControlDerivate;
00355 std::vector<double> KnotDerivate;
00356 std::vector< std::vector<double> > CntrlPoints(((MainNurb.MaxV+1)*3), std::vector<double>((MainNurb.MaxU+1), 0.0));
00357 for (unsigned int a = 0; a < MainNurb.CntrlArray.size(); )
00358 {
00359 CntrlPoints[i][j] = MainNurb.CntrlArray[a];
00360 CntrlPoints[i+1][j] = MainNurb.CntrlArray[a+1];
00361 CntrlPoints[i+2][j] = MainNurb.CntrlArray[a+2];
00362 j++;
00363 a += 3;
00364 i = k*3;
00365 if (j == (MainNurb.MaxU+1))
00366 {
00367 j = 0;
00368 k++;
00369 i = k*3;
00370 }
00371
00372 }
00373
00374
00375 bspderiv(MainNurb.DegreeU, CntrlPoints, MainNurb.KnotU, ControlDerivate, KnotDerivate);
00376 Temp.CntrlArray.resize(ControlDerivate.size() * ControlDerivate[0].size());
00377 i = 0, j = 0, k = 0;
00378 for (unsigned int a = 0; a < Temp.CntrlArray.size(); )
00379 {
00380 Temp.CntrlArray[a] = ControlDerivate[i][j];
00381 Temp.CntrlArray[a+1] = ControlDerivate[i+1][j];
00382 Temp.CntrlArray[a+2] = ControlDerivate[i+2][j];
00383 j++;
00384 a += 3;
00385 i = k*3;
00386 if (j == (int)ControlDerivate[i].size())
00387 {
00388 j = 0;
00389 k++;
00390 i = k*3;
00391 }
00392 }
00393 Temp.KnotU = KnotDerivate;
00394 Temp.KnotV = MainNurb.KnotV;
00395 Temp.MaxKnotU = Temp.KnotU.size();
00396 Temp.MaxKnotV = Temp.KnotV.size();
00397 Temp.MaxU = ControlDerivate[0].size();
00398 Temp.MaxV = ControlDerivate.size() / 3;
00399 Temp.DegreeU = Temp.MaxKnotU - Temp.MaxU - 1;
00400 Temp.DegreeV = Temp.MaxKnotV - Temp.MaxV - 1;
00401 Temp.MaxU--;
00402 Temp.MaxV--;
00403 OutNurbs.push_back(Temp);
00404
00405 i = 0, j = 0, k = 0;
00406 CntrlPoints.clear();
00407 ControlDerivate.clear();
00408 KnotDerivate.clear();
00409 CntrlPoints.resize((MainNurb.MaxU+1)*3);
00410 for (unsigned int a = 0; a < CntrlPoints.size(); a++)
00411 CntrlPoints[a].resize(MainNurb.MaxV+1);
00412
00413 for (unsigned int a = 0; a < MainNurb.CntrlArray.size(); )
00414 {
00415 CntrlPoints[i][j] = MainNurb.CntrlArray[a];
00416 CntrlPoints[i+1][j] = MainNurb.CntrlArray[a+1];
00417 CntrlPoints[i+2][j] = MainNurb.CntrlArray[a+2];
00418 i += 3;
00419 a += 3;
00420 if (i == ((MainNurb.MaxU+1)*3))
00421 {
00422 i = 0;
00423 j++;
00424 }
00425
00426 }
00427
00428 bspderiv(MainNurb.DegreeV, CntrlPoints, MainNurb.KnotV, ControlDerivate, KnotDerivate);
00429 Temp.CntrlArray.resize(ControlDerivate.size() * ControlDerivate[0].size());
00430 i = 0, j = 0, k = 0;
00431 for (unsigned int a = 0; a < Temp.CntrlArray.size(); )
00432 {
00433 Temp.CntrlArray[a] = ControlDerivate[i][j];
00434 Temp.CntrlArray[a+1] = ControlDerivate[i+1][j];
00435 Temp.CntrlArray[a+2] = ControlDerivate[i+2][j];
00436 a += 3;
00437 i += 3;
00438 if (i == (int)ControlDerivate.size())
00439 {
00440 j++;
00441 i = 0;
00442 }
00443 }
00444 Temp.KnotU = MainNurb.KnotU;
00445 Temp.KnotV = KnotDerivate;
00446 Temp.MaxKnotU = Temp.KnotU.size();
00447 Temp.MaxKnotV = Temp.KnotV.size();
00448 Temp.MaxU = ControlDerivate.size() / 3;
00449 Temp.MaxV = ControlDerivate[0].size();
00450 Temp.DegreeU = Temp.MaxKnotU - Temp.MaxU - 1;
00451 Temp.DegreeV = Temp.MaxKnotV - Temp.MaxV - 1;
00452 Temp.MaxU--;
00453 Temp.MaxV--;
00454 OutNurbs.push_back(Temp);
00455 }
00456
00458 void Routines::bspderiv(int d, std::vector< std::vector<double> > &c, std::vector<double> &k,
00459 std::vector< std::vector<double> > &OutputC, std::vector<double> &Outputk)
00460 {
00461 OutputC.resize(c.size());
00462 for (unsigned int i = 0; i < OutputC.size(); i++)
00463 OutputC[i].resize(c[i].size()-1);
00464
00465 double tmp = 0.0;
00466
00467 for (unsigned int i = 0; i < OutputC[0].size(); i++)
00468 {
00469 tmp = d / (k[i+d+1]-k[i+1]);
00470 for (unsigned int j = 0; j < OutputC.size(); j++)
00471 OutputC[j][i] = tmp * (c[j][i+1] - c[j][i]);
00472 }
00473 Outputk.resize(k.size() - 2);
00474 for (unsigned int i = 0; i < Outputk.size(); i++)
00475 Outputk[i] = k[i+1];
00476 }
00477
00479 void Routines::NrbDEval(NURBS &MainNurb, std::vector<NURBS> &DerivNurb, std::vector<double> &Point,
00480 std::vector<double> &EvalPoint, std::vector<std::vector<double> > &jac)
00481 {
00482 if (!EvalPoint.empty())
00483 EvalPoint.clear();
00484 if (!jac.empty())
00485 jac.clear();
00486 std::vector<double> TempoPointDeriv;
00487 PointNrbEval(EvalPoint, Point, MainNurb);
00488 for (unsigned int i = 0; i < DerivNurb.size(); i++)
00489 {
00490 PointNrbEval(TempoPointDeriv, Point, DerivNurb[i]);
00491 jac.push_back(TempoPointDeriv);
00492 TempoPointDeriv.clear();
00493 }
00494 }
00495
00497 void Routines::GenerateUniformKnot(int MaxCntrl, int NurbDegree, std::vector<double> &KnotSequence)
00498 {
00499 if (!KnotSequence.empty())
00500 KnotSequence.clear();
00501
00502 for (int i = 0; i < (MaxCntrl + NurbDegree + 2); i++)
00503 KnotSequence.push_back(0);
00504
00505 for (int i = NurbDegree; i < MaxCntrl; i++)
00506 KnotSequence[i+1] = (double)(i - NurbDegree + 1.0) / (double)(MaxCntrl - NurbDegree + 1.0);
00507
00508 for (unsigned int i = MaxCntrl+1; i < KnotSequence.size(); i++)
00509 KnotSequence[i] = 1;
00510
00511 }
00512
00518 unsigned long Routines::FindCorner(float ParamX, float ParamY, std::vector<unsigned long> &v_neighbour, std::vector <Base::Vector3f> &v_pnts)
00519 {
00520 unsigned int j = 0;
00521 bool change = false;
00522
00523
00524 double distance = sqrt(((ParamX - v_pnts[0][0])*(ParamX - v_pnts[0][0])) +
00525 ((ParamY - v_pnts[0][1])*(ParamY - v_pnts[0][1])));
00526 for (unsigned int k = 1; k < v_neighbour.size(); ++k)
00527 {
00528 double eps= sqrt(((ParamX - v_pnts[k][0])*(ParamX - v_pnts[k][0])) +
00529 ((ParamY - v_pnts[k][1])*(ParamY - v_pnts[k][1])));
00530 if (eps < distance)
00531 {
00532 distance = eps;
00533 j = k;
00534 change = true;
00535 }
00536
00537 }
00538 if (change)
00539 return v_neighbour[j];
00540 else return v_neighbour[0];
00541 }
00542
00545 double Routines::AreaTriangle(Base::Vector3f &a, Base::Vector3f &b, Base::Vector3f &c)
00546 {
00547
00548
00549
00550
00551
00552
00553
00554
00555 Base::Vector3f First = b - a;
00556 Base::Vector3f Second = c - a;
00557 std::vector < std::vector<double> > Matrix(2, std::vector<double>(2));
00558 Matrix[0][0] = First.x;
00559 Matrix[1][0] = First.y;
00560 Matrix[0][1] = Second.x;
00561 Matrix[1][1] = Second.y;
00562 return (0.5 * det2(Matrix));
00563 }
00564
00572 void Routines::ExtendKnot(double ErrPnt, int NurbDegree, int MaxCntrl, std::vector<double> &KnotSequence)
00573 {
00574 double tol_knot = 0.02;
00575 int ind_1 = 0;
00576 double new1 = 0;
00577 int ind_2 = 0;
00578 double new2 = 0;
00579 bool flag = false;
00580
00581 if (KnotSequence.size()>40)
00582 tol_knot = 0.015;
00583
00584 for (unsigned int i = NurbDegree; i < (KnotSequence.size() - NurbDegree); i++)
00585 {
00586 if ((KnotSequence[i] > ErrPnt) && (ErrPnt >= KnotSequence[i-1]))
00587 {
00588 ind_1 = i;
00589 new1 = (KnotSequence[ind_1] + KnotSequence[ind_1-1]) / 2;
00590
00591 }
00592 }
00593
00594 if (!flag)
00595 {
00596 double mid = (double)KnotSequence.size() / 2.0;
00597
00598 if (ind_1 == mid)
00599 {
00600
00601 KnotSequence.resize(KnotSequence.size() + 2);
00602
00603 for (int i = KnotSequence.size() - 1; i > ind_1; i--)
00604 KnotSequence[i] = KnotSequence[i-2];
00605 KnotSequence[ind_1] = KnotSequence[ind_1-1] + ((new1 - KnotSequence[ind_1-1]) / 2.0);
00606 KnotSequence[ind_1+1] = new1 +((new1 - KnotSequence[ind_1-1]) / 2.0);
00607
00608 }
00609 else
00610 {
00611 double temp = mid - ((double)ind_1);
00612 ind_2 = (int)(mid + temp);
00613 new2 = (KnotSequence[ind_2-1] + KnotSequence[ind_2]) / 2.0;
00614 if (ind_1 < ind_2)
00615 Extension(KnotSequence,ind_1,ind_2,new1,new2);
00616 else
00617 Extension(KnotSequence,ind_2,ind_1,new2,new1);
00618 }
00619 }
00620 else
00621 {
00622 if (ind_1 < ind_2)
00623 Extension(KnotSequence,ind_1,ind_2,new1,new2);
00624 else
00625 Extension(KnotSequence,ind_2,ind_1,new2,new1);
00626 }
00627 }
00630 void Routines::Extension(std::vector<double> &KnotSequence, int SmallerIndex, int LargerIndex, double SmallerIndNewValue,
00631 double LargerIndNewValue)
00632 {
00633 KnotSequence.resize(KnotSequence.size() + 1);
00634
00635 for (int i = KnotSequence.size() - 1; i > SmallerIndex; i--)
00636 KnotSequence[i] = KnotSequence[i-1];
00637
00638 KnotSequence[SmallerIndex] = SmallerIndNewValue;
00639
00640 LargerIndex++;
00641 KnotSequence.resize(KnotSequence.size() + 1);
00642
00643 for (int i = KnotSequence.size() - 1; i > LargerIndex; i--)
00644 KnotSequence[i] = KnotSequence[i-1];
00645
00646 KnotSequence[LargerIndex] = LargerIndNewValue;
00647 }
00648