mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-01 10:26:12 +03:00
305 lines
7.7 KiB
C++
Executable File
305 lines
7.7 KiB
C++
Executable File
// Created on: 1995-10-10
|
|
// Created by: Jacques GOUSSARD
|
|
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
|
|
|
|
#include <Convert_PolynomialCosAndSin.hxx>
|
|
|
|
#include <TColgp_Array1OfPnt2d.hxx>
|
|
#include <gp_Trsf2d.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <gp_XY.hxx>
|
|
|
|
#include <gp.hxx>
|
|
#include <Precision.hxx>
|
|
#include <PLib.hxx>
|
|
#include <BSplCLib.hxx>
|
|
|
|
#include <Standard_ConstructionError.hxx>
|
|
|
|
static Standard_Real Locate(const Standard_Real Angfin,
|
|
const TColgp_Array1OfPnt2d& TPoles,
|
|
const Standard_Real Umin,
|
|
const Standard_Real Umax)
|
|
{
|
|
Standard_Real umin = Umin;
|
|
Standard_Real umax = Umax;
|
|
Standard_Real Ptol = Precision::Angular();
|
|
Standard_Real Utol = Precision::PConfusion();
|
|
while (Abs(umax-umin)>= Utol) {
|
|
Standard_Real ptest = (umax+umin)/2.;
|
|
gp_Pnt2d valP;
|
|
BSplCLib::D0(ptest,TPoles,BSplCLib::NoWeights(),valP);
|
|
Standard_Real theta = ATan2(valP.Y(),valP.X());
|
|
if (theta < 0.) {
|
|
theta +=2.*M_PI;
|
|
}
|
|
if (Abs(theta - Angfin) < Ptol) {
|
|
return ptest;
|
|
}
|
|
if (theta < Angfin) {
|
|
umin = ptest;
|
|
}
|
|
else if (theta > Angfin) {
|
|
umax = ptest;
|
|
}
|
|
}
|
|
return (umin+umax)/2.;
|
|
}
|
|
|
|
|
|
void BuildPolynomialCosAndSin
|
|
(const Standard_Real UFirst,
|
|
const Standard_Real ULast,
|
|
const Standard_Integer num_poles,
|
|
Handle(TColStd_HArray1OfReal)& CosNumeratorPtr,
|
|
Handle(TColStd_HArray1OfReal)& SinNumeratorPtr,
|
|
Handle(TColStd_HArray1OfReal)& DenominatorPtr)
|
|
{
|
|
|
|
Standard_Real Delta,
|
|
locUFirst,
|
|
// locULast,
|
|
// temp_value,
|
|
t_min,
|
|
t_max,
|
|
trim_min,
|
|
trim_max,
|
|
middle,
|
|
Angle,
|
|
PI2 = 2*M_PI ;
|
|
Standard_Integer ii, degree = num_poles -1 ;
|
|
locUFirst = UFirst ;
|
|
|
|
// Return UFirst in [-2PI; 2PI]
|
|
// to make rotations without risk
|
|
while (locUFirst > PI2) {
|
|
locUFirst -= PI2;
|
|
}
|
|
while (locUFirst < - PI2) {
|
|
locUFirst += PI2;
|
|
}
|
|
|
|
// Return to the arc [0, Delta]
|
|
Delta = ULast - UFirst;
|
|
middle = 0.5e0 * Delta ;
|
|
|
|
// coincide the required bisector of the angular sector with
|
|
// axis -Ox definition of the circle in Bezier of degree 7 so that
|
|
// parametre 1/2 of Bezier was exactly a point of the bissectrice
|
|
// of the required angular sector.
|
|
//
|
|
Angle = middle - M_PI ;
|
|
//
|
|
// Circle of radius 1. See Euclid
|
|
//
|
|
|
|
TColgp_Array1OfPnt2d TPoles(1,8),
|
|
NewTPoles(1,8) ;
|
|
TPoles(1).SetCoord(1.,0.);
|
|
TPoles(2).SetCoord(1.,1.013854);
|
|
TPoles(3).SetCoord(-0.199043,1.871905);
|
|
TPoles(4).SetCoord(-1.937729,1.057323);
|
|
TPoles(5).SetCoord(-1.937729,-1.057323);
|
|
TPoles(6).SetCoord(-0.199043,-1.871905);
|
|
TPoles(7).SetCoord(1.,-1.013854);
|
|
TPoles(8).SetCoord(1.,0.);
|
|
gp_Trsf2d T;
|
|
T.SetRotation(gp::Origin2d(),Angle);
|
|
for (ii=1; ii<=num_poles; ii++) {
|
|
TPoles(ii).Transform(T);
|
|
}
|
|
|
|
|
|
t_min = 1.0e0 - (Delta * 1.3e0 / M_PI) ;
|
|
t_min *= 0.5e0 ;
|
|
t_min = Max(t_min,0.0e0) ;
|
|
t_max = 1.0e0 + (Delta * 1.3e0 / M_PI) ;
|
|
t_max *= 0.5e0 ;
|
|
t_max = Min(t_max,1.0e0) ;
|
|
trim_max = Locate(Delta,
|
|
TPoles,
|
|
t_min,
|
|
t_max);
|
|
//
|
|
// as Bezier is symmetric correspondingly to the bissector
|
|
// of the angular sector ...
|
|
|
|
trim_min = 1.0e0 - trim_max ;
|
|
//
|
|
Standard_Real knot_array[2] ;
|
|
Standard_Integer mults_array[2] ;
|
|
knot_array[0] = 0.0e0 ;
|
|
knot_array[1] = 1.0e0 ;
|
|
mults_array[0] = degree + 1 ;
|
|
mults_array[1] = degree + 1 ;
|
|
|
|
TColStd_Array1OfReal the_knots(knot_array[0],1,2),
|
|
the_new_knots(knot_array[0],1,2);
|
|
TColStd_Array1OfInteger the_mults(mults_array[0],1,2),
|
|
the_new_mults(mults_array[0],1,2) ;
|
|
|
|
BSplCLib::Trimming(degree,
|
|
Standard_False,
|
|
the_knots,
|
|
the_mults,
|
|
TPoles,
|
|
BSplCLib::NoWeights(),
|
|
trim_min,
|
|
trim_max,
|
|
the_new_knots,
|
|
the_new_mults,
|
|
NewTPoles,
|
|
BSplCLib::NoWeights());
|
|
|
|
// readjustment is obviously redundant
|
|
Standard_Real SinD = Sin(Delta), CosD = Cos(Delta);
|
|
gp_Pnt2d Pdeb(1., 0.);
|
|
gp_Pnt2d Pfin(CosD, SinD);
|
|
|
|
Standard_Real dtg = NewTPoles(1).Distance(NewTPoles(2));
|
|
NewTPoles(1) = Pdeb;
|
|
gp_XY theXY(0.,dtg);
|
|
Pdeb.ChangeCoord() += theXY;
|
|
NewTPoles(2) = Pdeb;
|
|
|
|
// readjustment to Euclid
|
|
dtg = NewTPoles(num_poles).Distance(NewTPoles(num_poles-1));
|
|
NewTPoles(num_poles) = Pfin;
|
|
theXY.SetCoord(dtg*SinD,-dtg*CosD);
|
|
Pfin.ChangeCoord() += theXY;
|
|
NewTPoles(num_poles-1) = Pfin;
|
|
|
|
// Rotation to return to the arc [LocUFirst, LocUFirst+Delta]
|
|
T.SetRotation(gp::Origin2d(), locUFirst);
|
|
for (ii=1; ii<=num_poles; ii++) {
|
|
NewTPoles(ii).Transform(T);
|
|
}
|
|
|
|
for (ii=1; ii<=num_poles; ii++) {
|
|
CosNumeratorPtr->SetValue(ii,NewTPoles(ii).X());
|
|
SinNumeratorPtr->SetValue(ii,NewTPoles(ii).Y());
|
|
DenominatorPtr->SetValue(ii,1.);
|
|
}
|
|
}
|
|
|
|
/*
|
|
void BuildHermitePolynomialCosAndSin
|
|
(const Standard_Real UFirst,
|
|
const Standard_Real ULast,
|
|
const Standard_Integer num_poles,
|
|
Handle(TColStd_HArray1OfReal)& CosNumeratorPtr,
|
|
Handle(TColStd_HArray1OfReal)& SinNumeratorPtr,
|
|
Handle(TColStd_HArray1OfReal)& DenominatorPtr)
|
|
{
|
|
|
|
if (num_poles%2 != 0) {
|
|
Standard_ConstructionError::Raise();
|
|
}
|
|
Standard_Integer ii;
|
|
Standard_Integer ordre_deriv = num_poles/2;
|
|
Standard_Real ang = ULast - UFirst;
|
|
Standard_Real Cd = Cos(UFirst);
|
|
Standard_Real Sd = Sin(UFirst);
|
|
Standard_Real Cf = Cos(ULast);
|
|
Standard_Real Sf = Sin(ULast);
|
|
|
|
Standard_Integer Degree = num_poles-1;
|
|
TColStd_Array1OfReal FlatKnots(1,2*num_poles);
|
|
TColStd_Array1OfReal Parameters(1,num_poles);
|
|
TColStd_Array1OfInteger ContactOrderArray(1,num_poles);
|
|
TColgp_Array1OfPnt2d Poles(1,num_poles);
|
|
TColgp_Array1OfPnt2d TPoles(1,num_poles);
|
|
|
|
|
|
for (ii=1; ii<=num_poles; ii++) {
|
|
FlatKnots(ii) = 0.;
|
|
FlatKnots(ii+num_poles) = 1.;
|
|
}
|
|
|
|
Standard_Real coef = 1.;
|
|
Standard_Real xd,yd,xf,yf;
|
|
|
|
for (ii=1; ii<=ordre_deriv; ii++) {
|
|
Parameters(ii) = 0.;
|
|
Parameters(ii+ordre_deriv) = 1.;
|
|
|
|
ContactOrderArray(ii) = ContactOrderArray(num_poles-ii+1) = ii-1;
|
|
|
|
switch ((ii-1)%4) {
|
|
case 0:
|
|
{
|
|
xd = Cd*coef;
|
|
yd = Sd*coef;
|
|
xf = Cf*coef;
|
|
yf = Sf*coef;
|
|
}
|
|
break;
|
|
case 1:
|
|
{
|
|
xd = -Sd*coef;
|
|
yd = Cd*coef;
|
|
xf = -Sf*coef;
|
|
yf = Cf*coef;
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
xd = -Cd*coef;
|
|
yd = -Sd*coef;
|
|
xf = -Cf*coef;
|
|
yf = -Sf*coef;
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
xd = Sd*coef;
|
|
yd = -Cd*coef;
|
|
xf = Sf*coef;
|
|
yf = -Cf*coef;
|
|
}
|
|
break;
|
|
}
|
|
|
|
Poles(ii).SetX(xd);
|
|
Poles(ii).SetY(yd);
|
|
Poles(num_poles-ii+1).SetX(xf);
|
|
Poles(num_poles-ii+1).SetY(yf);
|
|
|
|
coef *= ang;
|
|
}
|
|
|
|
Standard_Integer InversionPb;
|
|
BSplCLib::Interpolate(Degree,FlatKnots,Parameters,
|
|
ContactOrderArray,Poles,InversionPb);
|
|
|
|
if (InversionPb !=0) {
|
|
Standard_ConstructionError::Raise();
|
|
}
|
|
for (ii=1; ii<=num_poles; ii++) {
|
|
CosNumeratorPtr->SetValue(ii,Poles(ii).X());
|
|
SinNumeratorPtr->SetValue(ii,Poles(ii).Y());
|
|
DenominatorPtr->SetValue(ii,1.);
|
|
}
|
|
|
|
}
|
|
*/
|