Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

Curve fitting using UF_MODL_create_fitted_spline with end slopes

Status
Not open for further replies.

WilsonBlr

Aerospace
Jun 11, 2014
19
0
0
IN

I am trying to fit a curve using UF_MODL_create_fitted_spline providing end slopes. One end of the created spline shows a loop back due to the slope constraint. I have observed that NX decides the direction of the slope vector automatically. I tried negating the slope vector but still it causes a loop back. What causes this loop-back and what is the workaround for this?

I have 7 points for fitting with order 3. For a higher order 6, I see the loop-back getting reduced but the curve seems to be over constrained.
-------------------------------------------------

Data points -
P1: -1.560260,-0.181989,3.286604
P2: -1.578313,-0.213621,3.273950
P3: -1.595170,-0.242289,3.264351
P4: -1.596874,-0.276042,3.260926
P5: -1.572996,-0.298280,3.269681
P6: -1.542036,-0.306016,3.282902
P7: -1.509833,-0.310289,3.298223

Slopes -
Slope at beginning: 0.762061,0.552460,0.337714
Slope at end: 0.911118,0.097702,0.400398
 
 http://files.engineering.com/getfile.aspx?folder=76362c7e-d02e-4d83-b7d9-73b4fafbe041&file=loopback.png
Replies continue below

Recommended for you

Used NX 8.5 for this.




Code:
// standard headers
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
//
#include <time.h>
#include <stdio.h>
//
//
#include <uf.h>
#include <uf_ui.h>
#include <uf_exit.h>
#include <uf_defs.h>
#include <uf_modl_curves.h>
#include <uf_curve.h>
#include <uf.h>
#include <uf_csys.h>
#include <uf_part.h>
#include <uf_eval.h>
#include <uf_forgeo.h>
#include <uf_point.h>
#include <uf_curve.h>
#include <uf_modl_utilities.h>
#include <uf_modl_freeform.h>
#include <uf_modl.h>
#include <uf_evalsf.h>
#include <uf_defs.h>
#include <uf_modl_types.h>

using namespace std;

int ReportError( char *file, int line, char *call, int irc)
{
	if (irc)
	{
		char err[133];
		char msg[256];

		sprintf_s(msg, "ERROR code %d at line %d in %s:\n",
			irc, line, file);
		UF_get_fail_message(irc, err);
		sprintf_s(msg, "Error Message: %s\n",err);
		//std::string filstr(file);

		//stringstream ss;
		//ss << line;
		//string str_line = ss.str();
		//sprintf_s(msg, "File : %s ... Line: %s\n",filstr, str_line);

		// create exception	
		exception *ex = new exception(msg);
		throw ex;
	}
	return(irc);
}


#ifndef UF_CALL
#define UF_CALL(X) (ReportError( __FILE__, __LINE__, #X, (X)))
#endif



int main(int argc, char* argv[])
{
	try {

		// Initialize NX
		UF_CALL(UF_initialize());

		// ----- This code is for constructing part name string  -----
		// create a temporary part name
		time_t now = time(0); 
		tm *ltm = localtime(&now); 
		char l_cTimeStr[256]; 
		// write to string 
		sprintf_s(l_cTimeStr,"_%d%02d%02d_%02d%02d%02d",1900 + ltm->tm_year,1 + ltm->tm_mon,ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);  

		// append to file name 
		string partName = "BankFile";
		int index = partName.find_last_of('.');
		if (index>1)
		{
			partName = partName.substr(0,partName.size()-index+1);
		}
		int index1 = partName.find_last_of('\\');
		int index2 = partName.find_last_of('/');
		if (index1>index2)
		{
			partName = partName.substr(index1+1,partName.size()-index1);
		}
		else
		{
			partName = partName.substr(index2+1,partName.size()-index2);
		}
		// append the time stamp
		partName.append(l_cTimeStr);

		// Part tag
		tag_t m_tPartTagID;

		// Create part 
		UF_CALL(UF_PART_new(partName.c_str(),2,&m_tPartTagID));

		// Spline Curve Structure	
		SPLINE_FIT_t tFitSplineData;

		double	dMaxErr					=	0.0;			// Maximum err value
		double	dTolerance				=	0.001;			// Default Tolerance value
		tag_t	l_tSplineCrv			=	NULL_TAG;		// Tag of the geometry
		bool bIsFeature				    =	false;

		// Weight Data for the fit spline
		tFitSplineData.weights			= 	NULL;
		tFitSplineData.num_of_weights	=	0;
		tFitSplineData.weight_positions =	NULL;
		// Segments Data
		tFitSplineData.num_of_segments	=	0;	
		// Tolerance always 0.0001 for all Airfoil curves
		tFitSplineData.tolerance		=	0.001;
		// Degree of the fit spline
		tFitSplineData.degree			=	3;
		// Point Data with its memory allocation
		tFitSplineData.num_of_points	=	7;

		// error code
		int nErrorCode=0;

		// allocate memory
		tFitSplineData.points			=	(double*) malloc(3*(7)*sizeof(double));
		// copy data to UF Array
		//P1: -1.560260,-0.181989,3.286604
		//P2: -1.578313,-0.213621,3.273950
		//P3: -1.595170,-0.242289,3.264351
		//P4: -1.596874,-0.276042,3.260926
		//P5: -1.572996,-0.298280,3.269681
		//P6: -1.542036,-0.306016,3.282902
		//P7: -1.509833,-0.310289,3.298223
		int nPt = 0;
		//P1: -1.560260,-0.181989,3.286604
		tFitSplineData.points[nPt] = -1.560260; nPt++; //1
		tFitSplineData.points[nPt] = -0.181989; nPt++;
		tFitSplineData.points[nPt] = 3.286604; nPt++;

		//P2: -1.578313,-0.213621,3.273950
		tFitSplineData.points[nPt] = -1.578313; nPt++; //2
		tFitSplineData.points[nPt] = -0.213621; nPt++;
		tFitSplineData.points[nPt] = 3.273950; nPt++;

		//P3: -1.595170,-0.242289,3.264351
		tFitSplineData.points[nPt] = -1.595170; nPt++; //3
		tFitSplineData.points[nPt] = -0.242289; nPt++;
		tFitSplineData.points[nPt] = 3.264351; nPt++;

		//P4: -1.596874,-0.276042,3.260926
		tFitSplineData.points[nPt] = -1.596874; nPt++; //4
		tFitSplineData.points[nPt] = -0.276042; nPt++;
		tFitSplineData.points[nPt] = 3.260926; nPt++;

		// P5: -1.572996,-0.298280,3.269681
		tFitSplineData.points[nPt] = -1.572996; nPt++;//5
		tFitSplineData.points[nPt] = -0.298280; nPt++;
		tFitSplineData.points[nPt] = 3.269681; nPt++;

		//P6: -1.542036,-0.306016,3.282902
		tFitSplineData.points[nPt] = -1.542036; nPt++;//6
		tFitSplineData.points[nPt] = -0.306016; nPt++;
		tFitSplineData.points[nPt] = 3.282902; nPt++;

		//P7: -1.509833,-0.310289,3.298223
		tFitSplineData.points[nPt] = -1.509833; nPt++;//7
		tFitSplineData.points[nPt] = -0.310289; nPt++;
		tFitSplineData.points[nPt] = 3.298223; nPt++;

		// slope definition
		tFitSplineData.slope_flag		=	3;		//
		tFitSplineData.slopes			= 	NULL;
		tFitSplineData.slopes =	(double*) malloc(6*sizeof(double));
		tFitSplineData.slopes[0]=0.762061;
		tFitSplineData.slopes[1]=0.552460;
		tFitSplineData.slopes[2]=0.337714;
		tFitSplineData.slopes[3]=0.911118;
		tFitSplineData.slopes[4]=0.097702;
		tFitSplineData.slopes[5]=0.400398;

		// Create Fit Spline with the above structure filled
		UF_CALL(UF_MODL_create_fitted_spline(&tFitSplineData, &dMaxErr, &nErrorCode, &l_tSplineCrv));

		// Save part
		UF_CALL(UF_PART_save());

		// close part
		UF_CALL(UF_PART_close(m_tPartTagID,1,1));

		UF_CALL(UF_terminate());

	}
	catch(exception e)
	{
		cout<<"An error occured. Please see the file ErrorLog.txt to see details."<<endl;
		cout<<e.what()<<endl;

		FILE* fptr;
		fptr = fopen("ErrorLog.txt","w");	
		fprintf(fptr,"\n\n");
		fprintf(fptr,"An error occured\n");
		fprintf(fptr,e.what());
		fclose(fptr);
	}
	catch(exception *e)
	{
		cout<<"An error occured. Please see the file ErrorLog.txt to see details "<<endl;
		cout<<e->what()<<endl;

		FILE* fptr;
		fptr = fopen("ErrorLog.txt","w");	
		fprintf(fptr,"\n\n");
		fprintf(fptr,"An error occured running MeshIC application\n");
		fprintf(fptr,e->what());
		fclose(fptr);
	}
}
 
Can I suggest you set the tolerance to a larger value say 0.01. The output the maximum error and the point at which the maximum error occurs.

I ran your data with no slope control then the maximum error was 0.008 at point 4 (point numbers 1 to 7)
I then ran it using your end slopes and the maximum error was 0.0098 at point 2

Now the problem is that if you need to get a tighter tolerance and you increase say the order or the number of segments then the spline does the looping that you indicated.

Hope this helps

Frank Swinkels
 
Status
Not open for further replies.
Back
Top