mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-07-10 04:17:44 +08:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
915
src/Geom2dAPI/Geom2dAPI_Interpolate.cxx
Executable file
915
src/Geom2dAPI/Geom2dAPI_Interpolate.cxx
Executable file
@@ -0,0 +1,915 @@
|
||||
// File: GeomAPI_Interpolate.cxx
|
||||
// Created: Thu Aug 18 15:53:59 1994
|
||||
// Author: Laurent PAINNOT
|
||||
// <lpa@metrox>
|
||||
// 8-Aug-95 : xab : interpolation uses BSplCLib::Interpolate
|
||||
//
|
||||
|
||||
#include <Geom2dAPI_Interpolate.ixx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
#include <TColStd_Array1OfBoolean.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColStd_HArray1OfBoolean.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckPoints
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Boolean CheckPoints(const TColgp_Array1OfPnt2d& PointArray,
|
||||
const Standard_Real Tolerance)
|
||||
{
|
||||
Standard_Integer ii ;
|
||||
Standard_Real tolerance_squared = Tolerance * Tolerance,
|
||||
distance_squared ;
|
||||
Standard_Boolean result = Standard_True ;
|
||||
for (ii = PointArray.Lower() ; result && ii < PointArray.Upper() ; ii++) {
|
||||
distance_squared =
|
||||
PointArray.Value(ii).SquareDistance(PointArray.Value(ii+1)) ;
|
||||
result = (distance_squared >= tolerance_squared) ;
|
||||
}
|
||||
return result ;
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CheckTangents
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Boolean CheckTangents(
|
||||
const TColgp_Array1OfVec2d& Tangents,
|
||||
const TColStd_Array1OfBoolean& TangentFlags,
|
||||
const Standard_Real Tolerance)
|
||||
{
|
||||
Standard_Integer ii,
|
||||
index ;
|
||||
Standard_Real tolerance_squared = Tolerance * Tolerance,
|
||||
distance_squared ;
|
||||
Standard_Boolean result = Standard_True ;
|
||||
index = TangentFlags.Lower() ;
|
||||
for (ii = Tangents.Lower(); result && ii <= Tangents.Upper() ; ii++) {
|
||||
if(TangentFlags.Value(index)) {
|
||||
distance_squared =
|
||||
Tangents.Value(ii).SquareMagnitude() ;
|
||||
result = (distance_squared >= tolerance_squared) ;
|
||||
}
|
||||
index += 1 ;
|
||||
}
|
||||
return result ;
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CheckParameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Boolean CheckParameters(const
|
||||
TColStd_Array1OfReal& Parameters)
|
||||
{
|
||||
Standard_Integer ii ;
|
||||
Standard_Real distance ;
|
||||
Standard_Boolean result = Standard_True ;
|
||||
for (ii = Parameters.Lower() ; result && ii < Parameters.Upper() ; ii++) {
|
||||
distance =
|
||||
Parameters.Value(ii+1) - Parameters.Value(ii) ;
|
||||
result = (distance >= RealSmall()) ;
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : BuildParameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static void BuildParameters(const Standard_Boolean PeriodicFlag,
|
||||
const TColgp_Array1OfPnt2d& PointsArray,
|
||||
Handle_TColStd_HArray1OfReal& ParametersPtr)
|
||||
{
|
||||
Standard_Integer ii,
|
||||
index ;
|
||||
Standard_Real distance ;
|
||||
Standard_Integer
|
||||
num_parameters = PointsArray.Length() ;
|
||||
if (PeriodicFlag) {
|
||||
num_parameters += 1 ;
|
||||
}
|
||||
ParametersPtr =
|
||||
new TColStd_HArray1OfReal(1,
|
||||
num_parameters) ;
|
||||
ParametersPtr->SetValue(1,0.0e0) ;
|
||||
index = 2 ;
|
||||
for (ii = PointsArray.Lower() ; ii < PointsArray.Upper() ; ii++) {
|
||||
distance =
|
||||
PointsArray.Value(ii).Distance(PointsArray.Value(ii+1)) ;
|
||||
ParametersPtr->SetValue(index,
|
||||
ParametersPtr->Value(ii) + distance) ;
|
||||
index += 1 ;
|
||||
}
|
||||
if (PeriodicFlag) {
|
||||
distance =
|
||||
PointsArray.Value(PointsArray.Upper()).
|
||||
Distance(PointsArray.Value(PointsArray.Lower())) ;
|
||||
ParametersPtr->SetValue(index,
|
||||
ParametersPtr->Value(ii) + distance) ;
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : BuildPeriodicTangents
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static void BuildPeriodicTangent(
|
||||
const TColgp_Array1OfPnt2d& PointsArray,
|
||||
TColgp_Array1OfVec2d& TangentsArray,
|
||||
TColStd_Array1OfBoolean& TangentFlags,
|
||||
const TColStd_Array1OfReal& ParametersArray)
|
||||
{
|
||||
Standard_Integer
|
||||
ii,
|
||||
degree ;
|
||||
Standard_Real *point_array,
|
||||
*parameter_array,
|
||||
eval_result[2][2] ;
|
||||
|
||||
gp_Vec2d a_vector ;
|
||||
|
||||
if (PointsArray.Length() < 3) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
|
||||
if (!TangentFlags.Value(1)) {
|
||||
degree = 3 ;
|
||||
if (PointsArray.Length() == 3) {
|
||||
degree = 2 ;
|
||||
}
|
||||
point_array = (Standard_Real *) &PointsArray.Value(PointsArray.Lower()) ;
|
||||
parameter_array =
|
||||
(Standard_Real *) &ParametersArray.Value(1) ;
|
||||
TangentFlags.SetValue(1,Standard_True) ;
|
||||
PLib::EvalLagrange(ParametersArray.Value(1),
|
||||
1,
|
||||
degree,
|
||||
2,
|
||||
point_array[0],
|
||||
parameter_array[0],
|
||||
eval_result[0][0]) ;
|
||||
for (ii = 1 ; ii <= 2 ; ii++) {
|
||||
a_vector.SetCoord(ii,eval_result[1][ii-1]) ;
|
||||
}
|
||||
TangentsArray.SetValue(1,a_vector) ;
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : BuildTangents
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static void BuildTangents(const TColgp_Array1OfPnt2d& PointsArray,
|
||||
TColgp_Array1OfVec2d& TangentsArray,
|
||||
TColStd_Array1OfBoolean& TangentFlags,
|
||||
const TColStd_Array1OfReal& ParametersArray)
|
||||
{
|
||||
Standard_Integer ii,
|
||||
degree ;
|
||||
Standard_Real *point_array,
|
||||
*parameter_array,
|
||||
|
||||
eval_result[2][2] ;
|
||||
gp_Vec2d a_vector ;
|
||||
|
||||
degree = 3 ;
|
||||
|
||||
if ( PointsArray.Length() < 3) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
if (PointsArray.Length() == 3) {
|
||||
degree = 2 ;
|
||||
}
|
||||
if (!TangentFlags.Value(1)) {
|
||||
point_array = (Standard_Real *) &PointsArray.Value(PointsArray.Lower()) ;
|
||||
parameter_array =
|
||||
(Standard_Real *) &ParametersArray.Value(1) ;
|
||||
TangentFlags.SetValue(1,Standard_True) ;
|
||||
PLib::EvalLagrange(ParametersArray.Value(1),
|
||||
1,
|
||||
degree,
|
||||
2,
|
||||
point_array[0],
|
||||
parameter_array[0],
|
||||
eval_result[0][0]) ;
|
||||
for (ii = 1 ; ii <= 2 ; ii++) {
|
||||
a_vector.SetCoord(ii,eval_result[1][ii-1]) ;
|
||||
}
|
||||
TangentsArray.SetValue(1,a_vector) ;
|
||||
}
|
||||
if (! TangentFlags.Value(TangentFlags.Upper())) {
|
||||
point_array =
|
||||
(Standard_Real *) &PointsArray.Value(PointsArray.Upper() - degree) ;
|
||||
TangentFlags.SetValue(TangentFlags.Upper(),Standard_True) ;
|
||||
parameter_array =
|
||||
(Standard_Real *)&ParametersArray.Value(ParametersArray.Upper() - degree) ;
|
||||
PLib::EvalLagrange(ParametersArray.Value(ParametersArray.Upper()),
|
||||
1,
|
||||
degree,
|
||||
2,
|
||||
point_array[0],
|
||||
parameter_array[0],
|
||||
eval_result[0][0]) ;
|
||||
for (ii = 1 ; ii <= 2 ; ii++) {
|
||||
a_vector.SetCoord(ii,eval_result[1][ii-1]) ;
|
||||
}
|
||||
TangentsArray.SetValue(TangentsArray.Upper(),a_vector) ;
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : BuildTangents
|
||||
//purpose : scale the given tangent so that they have the length of
|
||||
// the size of the derivative of the lagrange interpolation
|
||||
//
|
||||
//=======================================================================
|
||||
static void ScaleTangents(const TColgp_Array1OfPnt2d& PointsArray,
|
||||
TColgp_Array1OfVec2d& TangentsArray,
|
||||
const TColStd_Array1OfBoolean& TangentFlags,
|
||||
const TColStd_Array1OfReal& ParametersArray)
|
||||
{
|
||||
Standard_Integer ii,
|
||||
jj,
|
||||
degree=0,
|
||||
index,
|
||||
num_points ;
|
||||
|
||||
Standard_Real *point_array,
|
||||
*parameter_array,
|
||||
value[2],
|
||||
ratio,
|
||||
eval_result[2][2] ;
|
||||
|
||||
gp_Vec2d a_vector ;
|
||||
|
||||
num_points = PointsArray.Length() ;
|
||||
if (num_points == 2) {
|
||||
degree = 1 ;
|
||||
}
|
||||
else if (num_points >= 3) {
|
||||
degree = 2 ;
|
||||
}
|
||||
|
||||
index = PointsArray.Lower() ;
|
||||
for (ii = TangentFlags.Lower() ; ii <= TangentFlags.Upper() ; ii++) {
|
||||
if (TangentFlags.Value(ii)) {
|
||||
point_array =
|
||||
(Standard_Real *) &PointsArray.Value(index) ;
|
||||
parameter_array =
|
||||
(Standard_Real *) &ParametersArray.Value(index) ;
|
||||
PLib::EvalLagrange(ParametersArray.Value(ii),
|
||||
1,
|
||||
degree,
|
||||
2,
|
||||
point_array[0],
|
||||
parameter_array[0],
|
||||
eval_result[0][0]) ;
|
||||
value[0] =
|
||||
value[1] = 0.0e0 ;
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
value[0] += Abs(TangentsArray.Value(ii).Coord(jj)) ;
|
||||
value[1] += Abs(eval_result[1][jj-1]) ;
|
||||
}
|
||||
ratio = value[1] / value[0] ;
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_vector.SetCoord(jj, ratio *
|
||||
TangentsArray.Value(ii).Coord(jj)) ;
|
||||
}
|
||||
TangentsArray.SetValue(ii, a_vector) ;
|
||||
if (ii != TangentFlags.Lower()) {
|
||||
index += 1 ;
|
||||
}
|
||||
if (index > PointsArray.Upper() - degree) {
|
||||
index = PointsArray.Upper() - degree ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Geom2dAPI_Interpolate
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Geom2dAPI_Interpolate::Geom2dAPI_Interpolate
|
||||
(const Handle_TColgp_HArray1OfPnt2d& PointsPtr,
|
||||
const Standard_Boolean PeriodicFlag,
|
||||
const Standard_Real Tolerance) :
|
||||
myTolerance(Tolerance),
|
||||
myPoints(PointsPtr),
|
||||
myIsDone(Standard_False),
|
||||
myPeriodic(PeriodicFlag),
|
||||
myTangentRequest(Standard_False)
|
||||
|
||||
{
|
||||
Standard_Integer ii ;
|
||||
Standard_Boolean result =
|
||||
CheckPoints(PointsPtr->Array1(),
|
||||
Tolerance) ;
|
||||
myTangents =
|
||||
new TColgp_HArray1OfVec2d(myPoints->Lower(),
|
||||
myPoints->Upper()) ;
|
||||
myTangentFlags =
|
||||
new TColStd_HArray1OfBoolean(myPoints->Lower(),
|
||||
myPoints->Upper()) ;
|
||||
|
||||
if (!result) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
BuildParameters(PeriodicFlag,
|
||||
PointsPtr->Array1(),
|
||||
myParameters) ;
|
||||
|
||||
for (ii = myPoints->Lower() ; ii <= myPoints->Upper() ; ii++) {
|
||||
myTangentFlags->SetValue(ii,Standard_False) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Geom2dAPI_Interpolate
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Geom2dAPI_Interpolate::Geom2dAPI_Interpolate
|
||||
(const Handle_TColgp_HArray1OfPnt2d& PointsPtr,
|
||||
const Handle_TColStd_HArray1OfReal& ParametersPtr,
|
||||
const Standard_Boolean PeriodicFlag,
|
||||
const Standard_Real Tolerance) :
|
||||
myTolerance(Tolerance),
|
||||
myPoints(PointsPtr),
|
||||
myIsDone(Standard_False),
|
||||
myParameters(ParametersPtr),
|
||||
myPeriodic(PeriodicFlag),
|
||||
myTangentRequest(Standard_False)
|
||||
{
|
||||
Standard_Integer ii ;
|
||||
|
||||
|
||||
Standard_Boolean result =
|
||||
CheckPoints(PointsPtr->Array1(),
|
||||
Tolerance) ;
|
||||
|
||||
if (PeriodicFlag) {
|
||||
if ((PointsPtr->Length()) + 1 != ParametersPtr->Length()) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
}
|
||||
myTangents =
|
||||
new TColgp_HArray1OfVec2d(myPoints->Lower(),
|
||||
myPoints->Upper()) ;
|
||||
myTangentFlags =
|
||||
new TColStd_HArray1OfBoolean(myPoints->Lower(),
|
||||
myPoints->Upper()) ;
|
||||
|
||||
if (!result) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
|
||||
result =
|
||||
CheckParameters(ParametersPtr->Array1()) ;
|
||||
if (!result) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
|
||||
for (ii = myPoints->Lower() ; ii <= myPoints->Upper() ; ii++) {
|
||||
myTangentFlags->SetValue(ii,Standard_False) ;
|
||||
}
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Load
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Geom2dAPI_Interpolate::Load(
|
||||
const TColgp_Array1OfVec2d& Tangents,
|
||||
const Handle_TColStd_HArray1OfBoolean& TangentFlagsPtr)
|
||||
|
||||
{
|
||||
Standard_Boolean result ;
|
||||
Standard_Integer ii ;
|
||||
myTangentRequest = Standard_True ;
|
||||
myTangentFlags = TangentFlagsPtr ;
|
||||
if (Tangents.Length() != myPoints->Length() ||
|
||||
TangentFlagsPtr->Length() != myPoints->Length()) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
result =
|
||||
CheckTangents(Tangents,
|
||||
TangentFlagsPtr->Array1(),
|
||||
myTolerance) ;
|
||||
if (result) {
|
||||
myTangents =
|
||||
new TColgp_HArray1OfVec2d(Tangents.Lower(),Tangents.Upper()) ;
|
||||
for (ii = Tangents.Lower() ; ii <= Tangents.Upper() ; ii++ ) {
|
||||
myTangents->SetValue(ii,Tangents.Value(ii)) ;
|
||||
}
|
||||
ScaleTangents(myPoints->Array1(),
|
||||
myTangents->ChangeArray1(),
|
||||
TangentFlagsPtr->Array1(),
|
||||
myParameters->Array1()) ;
|
||||
}
|
||||
else {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Load
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Geom2dAPI_Interpolate::Load(const gp_Vec2d& InitialTangent,
|
||||
const gp_Vec2d& FinalTangent)
|
||||
{
|
||||
Standard_Boolean result ;
|
||||
myTangentRequest = Standard_True ;
|
||||
myTangentFlags->SetValue(1,Standard_True) ;
|
||||
myTangentFlags->SetValue(myPoints->Length(),Standard_True) ;
|
||||
myTangents->SetValue(1,InitialTangent) ;
|
||||
myTangents->SetValue(myPoints->Length(),FinalTangent);
|
||||
result =
|
||||
CheckTangents(myTangents->Array1(),
|
||||
myTangentFlags->Array1(),
|
||||
myTolerance) ;
|
||||
if (!result) {
|
||||
Standard_ConstructionError::Raise();
|
||||
}
|
||||
ScaleTangents(myPoints->Array1(),
|
||||
myTangents->ChangeArray1(),
|
||||
myTangentFlags->Array1(),
|
||||
myParameters->Array1()) ;
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Geom2dAPI_Interpolate::Perform()
|
||||
{
|
||||
if (myPeriodic) {
|
||||
PerformPeriodic() ;
|
||||
}
|
||||
else {
|
||||
PerformNonPeriodic() ;
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : PerformPeriodic
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Geom2dAPI_Interpolate::PerformPeriodic()
|
||||
{
|
||||
Standard_Integer degree,
|
||||
ii,
|
||||
jj,
|
||||
index,
|
||||
index1,
|
||||
// index2,
|
||||
mult_index,
|
||||
half_order,
|
||||
inversion_problem,
|
||||
num_points,
|
||||
num_distinct_knots,
|
||||
num_poles ;
|
||||
|
||||
Standard_Real period ;
|
||||
|
||||
gp_Pnt2d a_point ;
|
||||
|
||||
num_points = myPoints->Length() ;
|
||||
period = myParameters->Value(myParameters->Upper()) -
|
||||
myParameters->Value(myParameters->Lower()) ;
|
||||
num_poles = num_points + 1 ;
|
||||
if (num_points == 2 && !myTangentRequest) {
|
||||
//
|
||||
// build a periodic curve of degree 1
|
||||
//
|
||||
|
||||
degree = 1 ;
|
||||
TColStd_Array1OfInteger deg1_mults(1,num_poles) ;
|
||||
for (ii = 1 ; ii <= num_poles ; ii++) {
|
||||
deg1_mults.SetValue(ii,1) ;
|
||||
}
|
||||
|
||||
myCurve =
|
||||
new Geom2d_BSplineCurve(myPoints->Array1(),
|
||||
myParameters->Array1(),
|
||||
deg1_mults,
|
||||
degree,
|
||||
myPeriodic) ;
|
||||
myIsDone = Standard_True ;
|
||||
|
||||
}
|
||||
else {
|
||||
num_distinct_knots = num_points + 1 ;
|
||||
half_order = 2 ;
|
||||
degree = 3 ;
|
||||
num_poles += 2 ;
|
||||
if (myTangentRequest)
|
||||
for (ii = myTangentFlags->Lower() + 1 ;
|
||||
ii <= myTangentFlags->Upper() ; ii++) {
|
||||
if (myTangentFlags->Value(ii)) {
|
||||
num_poles += 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
TColStd_Array1OfReal parameters(1,num_poles) ;
|
||||
TColStd_Array1OfReal flatknots(1,num_poles + degree + 1) ;
|
||||
TColStd_Array1OfInteger mults(1,num_distinct_knots) ;
|
||||
TColStd_Array1OfInteger contact_order_array(1, num_poles) ;
|
||||
TColgp_Array1OfPnt2d poles(1,num_poles) ;
|
||||
|
||||
for (ii = 1 ; ii <= half_order ; ii++) {
|
||||
flatknots.SetValue(ii,myParameters->Value(myParameters->Upper() -1) -
|
||||
period) ;
|
||||
flatknots.SetValue(ii + half_order,myParameters->
|
||||
Value(myParameters->Lower())) ;
|
||||
flatknots.SetValue(num_poles + ii,
|
||||
myParameters->Value(myParameters->Upper())) ;
|
||||
flatknots.SetValue(num_poles + half_order + ii,
|
||||
myParameters->Value(half_order) + period) ;
|
||||
}
|
||||
for (ii = 1 ; ii <= num_poles ; ii++) {
|
||||
contact_order_array.SetValue(ii,0) ;
|
||||
}
|
||||
for (ii = 2 ; ii < num_distinct_knots ; ii++) {
|
||||
mults.SetValue(ii,1) ;
|
||||
}
|
||||
mults.SetValue(1,half_order) ;
|
||||
mults.SetValue(num_distinct_knots ,half_order) ;
|
||||
if (num_points >= 3) {
|
||||
|
||||
//
|
||||
// only enter here if there are more than 3 points otherwise
|
||||
// it means we have already the tangent
|
||||
//
|
||||
BuildPeriodicTangent(myPoints->Array1(),
|
||||
myTangents->ChangeArray1(),
|
||||
myTangentFlags->ChangeArray1(),
|
||||
myParameters->Array1()) ;
|
||||
}
|
||||
contact_order_array.SetValue(2,1) ;
|
||||
parameters.SetValue(1,myParameters->Value(1)) ;
|
||||
parameters.SetValue(2,myParameters->Value(1)) ;
|
||||
poles.SetValue(1,myPoints->Value(1)) ;
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_point.SetCoord(jj,myTangents->Value(1).Coord(jj)) ;
|
||||
}
|
||||
poles.SetValue(2,a_point) ;
|
||||
|
||||
mult_index = 2 ;
|
||||
index = 3 ;
|
||||
index1 = degree + 2 ;
|
||||
if (myTangentRequest) {
|
||||
for (ii = myTangentFlags->Lower() + 1 ;
|
||||
ii <= myTangentFlags->Upper() ; ii++) {
|
||||
parameters.SetValue(index,myParameters->Value(ii)) ;
|
||||
flatknots.SetValue(index1,myParameters->Value(ii)) ;
|
||||
poles.SetValue(index,myPoints->Value(ii)) ;
|
||||
index += 1 ;
|
||||
index1 += 1 ;
|
||||
if (myTangentFlags->Value(ii)) {
|
||||
mults.SetValue(mult_index,mults.Value(mult_index) + 1) ;
|
||||
contact_order_array(index) = 1 ;
|
||||
|
||||
parameters.SetValue(index,
|
||||
myParameters->Value(ii)) ;
|
||||
flatknots.SetValue(index1,myParameters->Value(ii)) ;
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_point.SetCoord(jj,myTangents->Value(ii).Coord(jj)) ;
|
||||
}
|
||||
poles.SetValue(index,a_point) ;
|
||||
index += 1 ;
|
||||
index1 += 1 ;
|
||||
}
|
||||
mult_index += 1 ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
index = degree + 1 ;
|
||||
index1 = 2 ;
|
||||
for(ii = myParameters->Lower() ; ii <= myParameters->Upper() ; ii++) {
|
||||
parameters.SetValue(index1,
|
||||
myParameters->Value(ii)) ;
|
||||
flatknots.SetValue(index,
|
||||
myParameters->Value(ii)) ;
|
||||
index += 1 ;
|
||||
index1 += 1 ;
|
||||
}
|
||||
index = 3 ;
|
||||
for (ii = myPoints->Lower() + 1 ; ii <= myPoints->Upper() ; ii++) {
|
||||
//
|
||||
// copy all the given points since the last one will be initialized
|
||||
// below by the first point in the array myPoints
|
||||
//
|
||||
poles.SetValue(index,
|
||||
myPoints->Value(ii)) ;
|
||||
index += 1 ;
|
||||
}
|
||||
|
||||
}
|
||||
contact_order_array.SetValue(num_poles - 1, 1) ;
|
||||
parameters.SetValue(num_poles-1,
|
||||
myParameters->Value(myParameters->Upper())) ;
|
||||
//
|
||||
// for the periodic curve ONLY the tangent of the first point
|
||||
// will be used since the curve should close itself at the first
|
||||
// point See BuildPeriodicTangent
|
||||
//
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_point.SetCoord(jj,myTangents->Value(1).Coord(jj)) ;
|
||||
}
|
||||
poles.SetValue(num_poles-1,a_point) ;
|
||||
|
||||
parameters.SetValue(num_poles,
|
||||
myParameters->Value(myParameters->Upper())) ;
|
||||
|
||||
poles.SetValue(num_poles,
|
||||
myPoints->Value(1)) ;
|
||||
|
||||
|
||||
BSplCLib::Interpolate(degree,
|
||||
flatknots,
|
||||
parameters,
|
||||
contact_order_array,
|
||||
poles,
|
||||
inversion_problem) ;
|
||||
if (!inversion_problem) {
|
||||
TColgp_Array1OfPnt2d newpoles(poles.Value(1),
|
||||
1,
|
||||
num_poles - 2) ;
|
||||
myCurve =
|
||||
new Geom2d_BSplineCurve(newpoles,
|
||||
myParameters->Array1(),
|
||||
mults,
|
||||
degree,
|
||||
myPeriodic) ;
|
||||
myIsDone = Standard_True ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : PerformNonPeriodic
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void Geom2dAPI_Interpolate::PerformNonPeriodic()
|
||||
{
|
||||
Standard_Integer degree,
|
||||
ii,
|
||||
jj,
|
||||
index,
|
||||
index1,
|
||||
index2,
|
||||
index3,
|
||||
mult_index,
|
||||
inversion_problem,
|
||||
num_points,
|
||||
num_distinct_knots,
|
||||
num_poles ;
|
||||
|
||||
gp_Pnt2d a_point ;
|
||||
|
||||
num_points =
|
||||
num_distinct_knots =
|
||||
num_poles = myPoints->Length() ;
|
||||
if (num_poles == 2 && !myTangentRequest) {
|
||||
degree = 1 ;
|
||||
}
|
||||
else if (num_poles == 3 && !myTangentRequest) {
|
||||
degree = 2 ;
|
||||
num_distinct_knots = 2 ;
|
||||
}
|
||||
else {
|
||||
degree = 3 ;
|
||||
num_poles += 2 ;
|
||||
if (myTangentRequest)
|
||||
for (ii = myTangentFlags->Lower() + 1 ;
|
||||
ii < myTangentFlags->Upper() ; ii++) {
|
||||
if (myTangentFlags->Value(ii)) {
|
||||
num_poles += 1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TColStd_Array1OfReal parameters(1,num_poles) ;
|
||||
TColStd_Array1OfReal flatknots(1,num_poles + degree + 1) ;
|
||||
TColStd_Array1OfInteger mults(1,num_distinct_knots) ;
|
||||
TColStd_Array1OfReal knots(1,num_distinct_knots) ;
|
||||
TColStd_Array1OfInteger contact_order_array(1, num_poles) ;
|
||||
TColgp_Array1OfPnt2d poles(1,num_poles) ;
|
||||
|
||||
for (ii = 1 ; ii <= degree + 1 ; ii++) {
|
||||
flatknots.SetValue(ii,myParameters->Value(1)) ;
|
||||
flatknots.SetValue(ii + num_poles,
|
||||
myParameters->Value(num_points)) ;
|
||||
}
|
||||
for (ii = 1 ; ii <= num_poles ; ii++) {
|
||||
contact_order_array.SetValue(ii,0) ;
|
||||
}
|
||||
for (ii = 2 ; ii < num_distinct_knots ; ii++) {
|
||||
mults.SetValue(ii,1) ;
|
||||
}
|
||||
mults.SetValue(1,degree + 1) ;
|
||||
mults.SetValue(num_distinct_knots ,degree + 1) ;
|
||||
|
||||
switch (degree) {
|
||||
case 1:
|
||||
for (ii = 1 ; ii <= num_poles ; ii++) {
|
||||
poles.SetValue(ii ,myPoints->Value(ii)) ;
|
||||
}
|
||||
myCurve =
|
||||
new Geom2d_BSplineCurve(poles,
|
||||
myParameters->Array1(),
|
||||
mults,
|
||||
degree) ;
|
||||
myIsDone = Standard_True ;
|
||||
break ;
|
||||
case 2:
|
||||
knots.SetValue(1,myParameters->Value(1)) ;
|
||||
knots.SetValue(2,myParameters->Value(3)) ;
|
||||
for (ii = 1 ; ii <= num_poles ; ii++) {
|
||||
poles.SetValue(ii,myPoints->Value(ii)) ;
|
||||
|
||||
}
|
||||
BSplCLib::Interpolate(degree,
|
||||
flatknots,
|
||||
myParameters->Array1(),
|
||||
contact_order_array,
|
||||
poles,
|
||||
inversion_problem) ;
|
||||
if (!inversion_problem) {
|
||||
myCurve =
|
||||
new Geom2d_BSplineCurve(poles,
|
||||
knots,
|
||||
mults,
|
||||
degree) ;
|
||||
myIsDone = Standard_True ;
|
||||
}
|
||||
break ;
|
||||
case 3:
|
||||
//
|
||||
// check if the boundary conditions are set
|
||||
//
|
||||
if (num_points >= 3) {
|
||||
//
|
||||
// cannot build the tangents with degree 3 with only 2 points
|
||||
// if those where not given in advance
|
||||
//
|
||||
BuildTangents(myPoints->Array1(),
|
||||
myTangents->ChangeArray1(),
|
||||
myTangentFlags->ChangeArray1(),
|
||||
myParameters->Array1()) ;
|
||||
}
|
||||
contact_order_array.SetValue(2,1) ;
|
||||
parameters.SetValue(1,myParameters->Value(1)) ;
|
||||
parameters.SetValue(2,myParameters->Value(1)) ;
|
||||
poles.SetValue(1,myPoints->Value(1)) ;
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_point.SetCoord(jj,myTangents->Value(1).Coord(jj)) ;
|
||||
|
||||
}
|
||||
poles.SetValue(2,a_point) ;
|
||||
mult_index = 2 ;
|
||||
index = 3 ;
|
||||
index1 = 2 ;
|
||||
index2 = myPoints->Lower() + 1 ;
|
||||
index3 = degree + 2 ;
|
||||
if (myTangentRequest) {
|
||||
for (ii = myParameters->Lower() + 1 ;
|
||||
ii < myParameters->Upper() ; ii++) {
|
||||
parameters.SetValue(index,myParameters->Value(ii)) ;
|
||||
poles.SetValue(index,myPoints->Value(index2)) ;
|
||||
flatknots.SetValue(index3,myParameters->Value(ii)) ;
|
||||
index += 1 ;
|
||||
index3 += 1 ;
|
||||
if (myTangentFlags->Value(index1)) {
|
||||
//
|
||||
// set the multiplicities, the order of the contact, the
|
||||
// the flatknots,
|
||||
//
|
||||
mults.SetValue(mult_index,mults.Value(mult_index) + 1) ;
|
||||
contact_order_array(index) = 1 ;
|
||||
flatknots.SetValue(index3, myParameters->Value(ii)) ;
|
||||
parameters.SetValue(index,
|
||||
myParameters->Value(ii)) ;
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_point.SetCoord(jj,myTangents->Value(ii).Coord(jj)) ;
|
||||
}
|
||||
poles.SetValue(index,a_point) ;
|
||||
index += 1 ;
|
||||
index3 += 1 ;
|
||||
}
|
||||
mult_index += 1 ;
|
||||
index1 += 1 ;
|
||||
index2 += 1 ;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
index1 = 2 ;
|
||||
for(ii = myParameters->Lower() ; ii <= myParameters->Upper() ; ii++) {
|
||||
parameters.SetValue(index1,
|
||||
myParameters->Value(ii)) ;
|
||||
index1 += 1 ;
|
||||
}
|
||||
index = 3 ;
|
||||
for (ii = myPoints->Lower() + 1 ; ii <= myPoints->Upper() - 1 ; ii++) {
|
||||
poles.SetValue(index,
|
||||
myPoints->Value(ii)) ;
|
||||
index += 1 ;
|
||||
}
|
||||
|
||||
|
||||
index = degree + 1 ;
|
||||
for(ii = myParameters->Lower() ; ii <= myParameters->Upper() ; ii++) {
|
||||
flatknots.SetValue(index,
|
||||
myParameters->Value(ii)) ;
|
||||
index += 1 ;
|
||||
}
|
||||
}
|
||||
for (jj = 1 ; jj <= 2 ; jj++) {
|
||||
a_point.SetCoord(jj,
|
||||
myTangents->Value(num_points).Coord(jj)) ;
|
||||
}
|
||||
poles.SetValue(num_poles-1 ,a_point) ;
|
||||
|
||||
contact_order_array.SetValue(num_poles - 1,1) ;
|
||||
parameters.SetValue(num_poles,
|
||||
myParameters->Value(myParameters->Upper())) ;
|
||||
parameters.SetValue(num_poles -1,
|
||||
myParameters->Value(myParameters->Upper())) ;
|
||||
|
||||
poles.SetValue(num_poles,
|
||||
myPoints->Value(num_points)) ;
|
||||
|
||||
BSplCLib::Interpolate(degree,
|
||||
flatknots,
|
||||
parameters,
|
||||
contact_order_array,
|
||||
poles,
|
||||
inversion_problem) ;
|
||||
if (!inversion_problem) {
|
||||
myCurve =
|
||||
new Geom2d_BSplineCurve(poles,
|
||||
myParameters->Array1(),
|
||||
mults,
|
||||
degree) ;
|
||||
myIsDone = Standard_True ;
|
||||
}
|
||||
break ;
|
||||
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Handle_Geom2d_BSplineCurve&
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
const Handle(Geom2d_BSplineCurve)& Geom2dAPI_Interpolate::Curve() const
|
||||
{
|
||||
if ( !myIsDone)
|
||||
StdFail_NotDone::Raise(" ");
|
||||
return myCurve;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Geom2d_BSplineCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Geom2dAPI_Interpolate::operator Handle(Geom2d_BSplineCurve)() const
|
||||
{
|
||||
return myCurve;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : IsDone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Geom2dAPI_Interpolate::IsDone() const
|
||||
{
|
||||
return myIsDone;
|
||||
}
|
||||
Reference in New Issue
Block a user