Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1997-07-18
// Created by: Philippe MANGIN
// Copyright (c) 1997-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.
#include <Convert_CompPolynomialToPoles.hxx>
#include <GeomFill_PolynomialConvertor.hxx>
#include <gp_Mat.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <PLib.hxx>
#include <Standard_Integer.hxx>
#include <StdFail_NotDone.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_Array2.hxx>
#include <math_Vector.hxx>
GeomFill_PolynomialConvertor::GeomFill_PolynomialConvertor()
: Ordre(8),
myinit(false),
BH(1, Ordre, 1, Ordre)
{
}
bool GeomFill_PolynomialConvertor::Initialized() const
{
return myinit;
}
void GeomFill_PolynomialConvertor::Init()
{
if (myinit)
{
return;
}
// BH = B * H where B is the monomial-to-BSpline conversion matrix on [-1,1], degree 7,
// and H is the Hermite coefficients matrix. Both are mathematical constants computed once.
static const math_Matrix THE_BH_MATRIX = []() {
constexpr int anOrdre = 8;
NCollection_Array1<double> aCoeffs(1, anOrdre * anOrdre);
NCollection_Array1<double> anInter(1, 2), aTrueInter(1, 2);
anInter.SetValue(1, -1);
anInter.SetValue(2, 1);
aTrueInter.SetValue(1, -1);
aTrueInter.SetValue(2, 1);
aCoeffs.Init(0);
for (int ii = 1; ii <= anOrdre; ii++)
{
aCoeffs.SetValue(ii + (ii - 1) * anOrdre, 1);
}
Convert_CompPolynomialToPoles aConverter(anOrdre,
anOrdre - 1,
anOrdre - 1,
aCoeffs,
anInter,
aTrueInter);
const NCollection_Array2<double>& aPoles = aConverter.Poles();
math_Matrix aB(1, anOrdre, 1, anOrdre);
for (int jj = 1; jj <= anOrdre; jj++)
{
for (int ii = 1; ii <= anOrdre; ii++)
{
double aTerm = aPoles.Value(ii, jj);
if (std::abs(aTerm - 1) < 1.e-9)
{
aTerm = 1;
}
if (std::abs(aTerm + 1) < 1.e-9)
{
aTerm = -1;
}
aB(ii, jj) = aTerm;
}
}
math_Matrix aH(1, anOrdre, 1, anOrdre);
PLib::HermiteCoefficients(-1, 1, anOrdre / 2 - 1, anOrdre / 2 - 1, aH);
aH.Transpose();
return math_Matrix(aB * aH);
}();
BH = THE_BH_MATRIX;
myinit = true;
}
void GeomFill_PolynomialConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Pnt& Center,
const gp_Vec& Dir,
const double Angle,
NCollection_Array1<gp_Pnt>& Poles) const
{
math_Vector Vx(1, Ordre), Vy(1, Ordre);
math_Vector Px(1, Ordre), Py(1, Ordre);
int ii;
double Cos_b = std::cos(Angle), Sin_b = std::sin(Angle);
double beta, beta2, beta3;
gp_Vec V1(Center, FirstPnt), V2;
V2 = Dir ^ V1;
beta = Angle / 2;
beta2 = beta * beta;
beta3 = beta * beta2;
// Calcul de la transformation
gp_Mat M(V1.X(), V2.X(), 0, V1.Y(), V2.Y(), 0, V1.Z(), V2.Z(), 0);
// Calcul des contraintes -----------
Vx(1) = 1;
Vy(1) = 0;
Vx(2) = 0;
Vy(2) = beta;
Vx(3) = -beta2;
Vy(3) = 0;
Vx(4) = 0;
Vy(4) = -beta3;
Vx(5) = Cos_b;
Vy(5) = Sin_b;
Vx(6) = -beta * Sin_b;
Vy(6) = beta * Cos_b;
Vx(7) = -beta2 * Cos_b;
Vy(7) = -beta2 * Sin_b;
Vx(8) = beta3 * Sin_b;
Vy(8) = -beta3 * Cos_b;
// Calcul des poles
Px = BH * Vx;
Py = BH * Vy;
gp_XYZ pnt;
for (ii = 1; ii <= Ordre; ii++)
{
pnt.SetCoord(Px(ii), Py(ii), 0);
pnt *= M;
pnt += Center.XYZ();
Poles(ii).ChangeCoord() = pnt;
}
}
void GeomFill_PolynomialConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Vec& DFirstPnt,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& Dir,
const gp_Vec& DDir,
const double Angle,
const double DAngle,
NCollection_Array1<gp_Pnt>& Poles,
NCollection_Array1<gp_Vec>& DPoles) const
{
math_Vector Vx(1, Ordre), Vy(1, Ordre), DVx(1, Ordre), DVy(1, Ordre);
math_Vector Px(1, Ordre), Py(1, Ordre), DPx(1, Ordre), DPy(1, Ordre);
int ii;
double Cos_b = std::cos(Angle), Sin_b = std::sin(Angle);
double beta, beta2, beta3, bprim;
gp_Vec V1(Center, FirstPnt), V1Prim, V2;
V2 = Dir ^ V1;
beta = Angle / 2;
bprim = DAngle / 2;
beta2 = beta * beta;
beta3 = beta * beta2;
// Calcul des transformations
gp_Mat M(V1.X(), V2.X(), 0, V1.Y(), V2.Y(), 0, V1.Z(), V2.Z(), 0);
V1Prim = DFirstPnt - DCenter;
V2 = (DDir ^ V1) + (Dir ^ V1Prim);
gp_Mat MPrim(V1Prim.X(), V2.X(), 0, V1Prim.Y(), V2.Y(), 0, V1Prim.Z(), V2.Z(), 0);
// Calcul des contraintes -----------
Vx(1) = 1;
Vy(1) = 0;
Vx(2) = 0;
Vy(2) = beta;
Vx(3) = -beta2;
Vy(3) = 0;
Vx(4) = 0;
Vy(4) = -beta3;
Vx(5) = Cos_b;
Vy(5) = Sin_b;
Vx(6) = -beta * Sin_b;
Vy(6) = beta * Cos_b;
Vx(7) = -beta2 * Cos_b;
Vy(7) = -beta2 * Sin_b;
Vx(8) = beta3 * Sin_b;
Vy(8) = -beta3 * Cos_b;
double b_bprim = bprim * beta, b2_bprim = bprim * beta2;
DVx(1) = 0;
DVy(1) = 0;
DVx(2) = 0;
DVy(2) = bprim;
DVx(3) = -2 * b_bprim;
DVy(3) = 0;
DVx(4) = 0;
DVy(4) = -3 * b2_bprim;
DVx(5) = -2 * bprim * Sin_b;
DVy(5) = 2 * bprim * Cos_b;
DVx(6) = -bprim * Sin_b - 2 * b_bprim * Cos_b;
DVy(6) = bprim * Cos_b - 2 * b_bprim * Sin_b;
DVx(7) = 2 * b_bprim * (-Cos_b + beta * Sin_b);
DVy(7) = -2 * b_bprim * (Sin_b + beta * Cos_b);
DVx(8) = b2_bprim * (3 * Sin_b + 2 * beta * Cos_b);
DVy(8) = b2_bprim * (2 * beta * Sin_b - 3 * Cos_b);
// Calcul des poles
Px = BH * Vx;
Py = BH * Vy;
DPx = BH * DVx;
DPy = BH * DVy;
gp_XYZ P, DP, aux;
for (ii = 1; ii <= Ordre; ii++)
{
P.SetCoord(Px(ii), Py(ii), 0);
Poles(ii).ChangeCoord() = M * P + Center.XYZ();
P *= MPrim;
DP.SetCoord(DPx(ii), DPy(ii), 0);
DP *= M;
aux.SetLinearForm(1, P, 1, DP, DCenter.XYZ());
DPoles(ii).SetXYZ(aux);
}
}
void GeomFill_PolynomialConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Vec& DFirstPnt,
const gp_Vec& D2FirstPnt,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& D2Center,
const gp_Vec& Dir,
const gp_Vec& DDir,
const gp_Vec& D2Dir,
const double Angle,
const double DAngle,
const double D2Angle,
NCollection_Array1<gp_Pnt>& Poles,
NCollection_Array1<gp_Vec>& DPoles,
NCollection_Array1<gp_Vec>& D2Poles) const
{
math_Vector Vx(1, Ordre), Vy(1, Ordre), DVx(1, Ordre), DVy(1, Ordre), D2Vx(1, Ordre),
D2Vy(1, Ordre);
math_Vector Px(1, Ordre), Py(1, Ordre), DPx(1, Ordre), DPy(1, Ordre), D2Px(1, Ordre),
D2Py(1, Ordre);
int ii;
double aux, Cos_b = std::cos(Angle), Sin_b = std::sin(Angle);
double beta, beta2, beta3, bprim, bprim2, bsecn;
gp_Vec V1(Center, FirstPnt), V1Prim, V1Secn, V2;
V2 = Dir ^ V1;
beta = Angle / 2;
bprim = DAngle / 2;
bsecn = D2Angle / 2;
bsecn = D2Angle / 2;
beta2 = beta * beta;
beta3 = beta * beta2;
bprim2 = bprim * bprim;
// Calcul des transformations
gp_Mat M(V1.X(), V2.X(), 0, V1.Y(), V2.Y(), 0, V1.Z(), V2.Z(), 0);
V1Prim = DFirstPnt - DCenter;
V2 = (DDir ^ V1) + (Dir ^ V1Prim);
gp_Mat MPrim(V1Prim.X(), V2.X(), 0, V1Prim.Y(), V2.Y(), 0, V1Prim.Z(), V2.Z(), 0);
V1Secn = D2FirstPnt - D2Center;
V2 = DDir ^ V1Prim;
V2 *= 2;
V2 += (D2Dir ^ V1) + (Dir ^ V1Secn);
gp_Mat MSecn(V1Secn.X(), V2.X(), 0, V1Secn.Y(), V2.Y(), 0, V1Secn.Z(), V2.Z(), 0);
// Calcul des contraintes -----------
Vx(1) = 1;
Vy(1) = 0;
Vx(2) = 0;
Vy(2) = beta;
Vx(3) = -beta2;
Vy(3) = 0;
Vx(4) = 0;
Vy(4) = -beta3;
Vx(5) = Cos_b;
Vy(5) = Sin_b;
Vx(6) = -beta * Sin_b;
Vy(6) = beta * Cos_b;
Vx(7) = -beta2 * Cos_b;
Vy(7) = -beta2 * Sin_b;
Vx(8) = beta3 * Sin_b;
Vy(8) = -beta3 * Cos_b;
double b_bprim = bprim * beta, b2_bprim = bprim * beta2, b_bsecn = bsecn * beta;
DVx(1) = 0;
DVy(1) = 0;
DVx(2) = 0;
DVy(2) = bprim;
DVx(3) = -2 * b_bprim;
DVy(3) = 0;
DVx(4) = 0;
DVy(4) = -3 * b2_bprim;
DVx(5) = -2 * bprim * Sin_b;
DVy(5) = 2 * bprim * Cos_b;
DVx(6) = -bprim * Sin_b - 2 * b_bprim * Cos_b;
DVy(6) = bprim * Cos_b - 2 * b_bprim * Sin_b;
DVx(7) = 2 * b_bprim * (-Cos_b + beta * Sin_b);
DVy(7) = -2 * b_bprim * (Sin_b + beta * Cos_b);
DVx(8) = b2_bprim * (3 * Sin_b + 2 * beta * Cos_b);
DVy(8) = b2_bprim * (2 * beta * Sin_b - 3 * Cos_b);
D2Vx(1) = 0;
D2Vy(1) = 0;
D2Vx(2) = 0;
D2Vy(2) = bsecn;
D2Vx(3) = -2 * (bprim2 + b_bsecn);
D2Vy(3) = 0;
D2Vx(4) = 0;
D2Vy(4) = -3 * beta * (2 * bprim2 + b_bsecn);
D2Vx(5) = -2 * (bsecn * Sin_b + 2 * bprim2 * Cos_b);
D2Vy(5) = 2 * (bsecn * Cos_b - 2 * bprim2 * Sin_b);
D2Vx(6) = (4 * beta * bprim2 - bsecn) * Sin_b - 2 * (2 * bprim2 + b_bsecn) * Cos_b;
D2Vy(6) = (bsecn - 4 * beta * bprim2) * Cos_b - 2 * (b_bsecn + 2 * bprim2) * Sin_b;
aux = 2 * (bprim2 + b_bsecn);
D2Vx(7) = aux * (-Cos_b + beta * Sin_b) + 2 * beta * bprim2 * (2 * beta * Cos_b + 3 * Sin_b);
D2Vy(7) = -aux * (Sin_b + beta * Cos_b) - 2 * beta * bprim2 * (3 * Cos_b - 2 * beta * Sin_b);
aux = beta * (2 * bprim2 + b_bsecn);
D2Vx(8) = aux * (3 * Sin_b + 2 * beta * Cos_b) + 4 * beta2 * bprim2 * (2 * Cos_b - beta * Sin_b);
D2Vy(8) = aux * (2 * beta * Sin_b - 3 * Cos_b) + 4 * beta2 * bprim2 * (2 * Sin_b + beta * Cos_b);
// Calcul des poles
Px = BH * Vx;
Py = BH * Vy;
DPx = BH * DVx;
DPy = BH * DVy;
D2Px = BH * D2Vx;
D2Py = BH * D2Vy;
gp_XYZ P, DP, D2P, auxyz;
for (ii = 1; ii <= Ordre; ii++)
{
P.SetCoord(Px(ii), Py(ii), 0);
DP.SetCoord(DPx(ii), DPy(ii), 0);
D2P.SetCoord(D2Px(ii), D2Py(ii), 0);
Poles(ii).ChangeCoord() = M * P + Center.XYZ();
auxyz.SetLinearForm(1, MPrim * P, 1, M * DP, DCenter.XYZ());
DPoles(ii).SetXYZ(auxyz);
P *= MSecn;
DP *= MPrim;
D2P *= M;
auxyz.SetLinearForm(1, P, 2, DP, 1, D2P, D2Center.XYZ());
D2Poles(ii).SetXYZ(auxyz);
}
}