1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-08 18:40:55 +03:00
occt/src/AppParCurves/AppParCurves.cxx

243 lines
6.1 KiB
C++

// Copyright (c) 1995-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#include <AppParCurves.hxx>
#include <BSplCLib.hxx>
#include <math_Matrix.hxx>
#include <TColStd_Array1OfReal.hxx>
void AppParCurves::BernsteinMatrix(const Standard_Integer NbPoles,
const math_Vector& U,
math_Matrix& A) {
Standard_Integer i, j, id;
Standard_Real u0, u1, y0, y1, xs;
Standard_Integer first = U.Lower(), last = U.Upper();
math_Vector B(1, NbPoles-1);
for (i = first; i <= last; i++) {
B(1) = 1;
u0 = U(i);
u1 = 1.-u0;
for (id = 2; id <= NbPoles-1; id++) {
y0 = B(1);
y1 = u0*y0;
B(1) = y0-y1;
for (j = 2; j <= id-1; j++) {
xs = y1;
y0 = B(j);
y1 = u0*y0;
B(j) = y0-y1+xs;
}
B(id) = y1;
}
A(i, 1) = u1*B(1);
A(i, NbPoles) = u0*B(NbPoles-1);
for (j = 2; j <= NbPoles-1; j++) {
A(i, j) = u1*B(j)+u0*B(j-1);
}
}
}
void AppParCurves::Bernstein(const Standard_Integer NbPoles,
const math_Vector& U,
math_Matrix& A,
math_Matrix& DA) {
Standard_Integer i, j, id, Ndeg = NbPoles-1;
Standard_Real u0, u1, y0, y1, xs, bj, bj1;
Standard_Integer first = U.Lower(), last = U.Upper();
math_Vector B(1, NbPoles-1);
for (i = first; i <= last; i++) {
B(1) = 1;
u0 = U(i);
u1 = 1.-u0;
for (id = 2; id <= NbPoles-1; id++) {
y0 = B(1);
y1 = u0*y0;
B(1) = y0-y1;
for (j = 2; j <= id-1; j++) {
xs = y1;
y0 = B(j);
y1 = u0*y0;
B(j) = y0-y1+xs;
}
B(id) = y1;
}
DA(i, 1) = -Ndeg*B(1);
DA(i, NbPoles) = Ndeg*B(NbPoles-1);
A(i, 1) = u1*B(1);
A(i, NbPoles) = u0*B(NbPoles-1);
for (j = 2; j <= NbPoles-1; j++) {
bj = B(j); bj1 = B(j-1);
DA(i,j) = Ndeg*(bj1-bj);
A(i, j) = u1*bj+u0*bj1;
}
}
}
void AppParCurves::SecondDerivativeBernstein(const Standard_Real U,
math_Vector& DDA) {
// Standard_Real U1 = 1-U, Y0, Y1, Xs;
Standard_Real Y0, Y1, Xs;
Standard_Integer NbPoles = DDA.Length();
Standard_Integer id, j, N4, deg = NbPoles-1;
N4 = deg*(deg-1);
math_Vector B(1, deg-1);
B(1) = 1.;
// Cas particulier si degre = 1:
if (deg == 1) {
DDA(1) = 0.0;
DDA(2) = 0.0;
}
else if (deg == 2) {
DDA(1) = 2.0;
DDA(2) = -4.0;
DDA(3) = 2.0;
}
else {
for (id = 2; id <= deg-1; id++) {
Y0 = B(1);
Y1 = U*Y0;
B(1) = Y0-Y1;
for (j = 2; j <= id-1; j++) {
Xs = Y1;
Y0 = B(j);
Y1 = U*Y0;
B(j) = Y0 - Y1 +Xs;
}
B(id) = Y1;
}
DDA(1) = N4*B(1);
DDA(2) = N4*(-2*B(1) + B(2));
DDA(deg) = N4*(B(deg-2) - 2*B(deg-1));
DDA(deg+1) = N4*B(deg-1);
for(j = 2; j <= deg-2; j++) {
DDA(j+1) = N4*(B(j-1)-2*B(j)+B(j+1));
}
}
}
void AppParCurves::SplineFunction(const Standard_Integer nbpoles,
const Standard_Integer deg,
const math_Vector& Parameters,
const math_Vector& flatknots,
math_Matrix& A,
math_Matrix& DA,
math_IntegerVector& index)
{
// Standard_Real U, NewU, co, diff, t1, t2;
Standard_Real U, NewU;
// gp_Pnt2d Pt, P0;
// gp_Vec2d V1;
// Standard_Integer i, j, k, iter, in, ik, deg1 = deg+1;
Standard_Integer i, j, deg1 = deg+1;
// Standard_Integer oldkindex, kindex, theindex, ttindex;
Standard_Integer oldkindex, kindex, theindex;
math_Vector locpoles(1 , deg1);
math_Vector locdpoles(1 , deg1);
Standard_Integer firstp = Parameters.Lower(), lastp = Parameters.Upper();
TColStd_Array1OfReal Aflatknots(flatknots.Lower(), flatknots.Upper());
for (i = flatknots.Lower(); i <= flatknots.Upper(); i++) {
Aflatknots(i) = flatknots(i);
}
oldkindex = 1;
Standard_Integer pp, qq;
Standard_Real Saved, Inverse, LocalInverse, locqq, locdqq, val;
for (i = firstp; i <= lastp; i++) {
U = Parameters(i);
NewU = U;
kindex = oldkindex;
BSplCLib::LocateParameter(deg, Aflatknots, U, Standard_False,
deg1, nbpoles+1, kindex, NewU);
oldkindex = kindex;
// On stocke les index:
index(i) = kindex - deg-1;
locpoles(1) = 1.0;
for (qq = 2; qq <= deg; qq++) {
locpoles(qq) = 0.0;
for (pp = 1; pp <= qq-1; pp++) {
Inverse = 1.0 / (flatknots(kindex + pp) - flatknots(kindex - qq + pp + 1)) ;
Saved = (U - flatknots(kindex - qq + pp + 1)) * Inverse * locpoles(pp);
locpoles(pp) *= (flatknots(kindex + pp) - U) * Inverse ;
locpoles(pp) += locpoles(qq) ;
locpoles(qq) = Saved ;
}
}
qq = deg+1;
for (pp = 1; pp <= deg; pp++) {
locdpoles(pp)= locpoles(pp);
}
locqq = 0.0;
locdqq = 0.0;
for (pp = 1; pp <= deg; pp++) {
Inverse = 1.0 / (flatknots(kindex + pp) - flatknots(kindex - qq + pp + 1));
Saved = (U - flatknots(kindex - qq + pp + 1)) * Inverse * locpoles(pp);
locpoles(pp) *= (flatknots(kindex + pp) - U) * Inverse;
locpoles(pp) += locqq;
locqq = Saved ;
LocalInverse = (Standard_Real) (deg) * Inverse;
Saved = LocalInverse * locdpoles(pp);
locdpoles(pp) *= - LocalInverse ;
locdpoles(pp) += locdqq;
locdqq = Saved ;
}
locpoles(qq) = locqq;
locdpoles(qq) = locdqq;
for (j = 1; j <= deg1; j++) {
val = locpoles(j);
theindex = j+oldkindex-deg1;
A(i, theindex) = val;
DA(i, theindex) = locdpoles(j);
}
for (j = 1; j < oldkindex-deg; j++)
A(i, j) = DA(i, j) = 0.0;
for (j = oldkindex+1; j <= nbpoles; j++)
A(i, j) = DA(i, j) = 0.0;
}
}