cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
JMP is taking Discovery online, April 16 and 18. Register today and join us for interactive sessions featuring popular presentation topics, networking, and discussions with the experts.
Choose Language Hide Translation Bar
WendyLou315
Level III

Matrix for fit circle flips coordinates

Hello again!  I have a new problem today. 

 

I have produced a contour plotter which uses values from measurement equipment to display enlarged deviations from nominal.  This tool can scan through a file of multiple planes or parts of data to display any given contour.  The trouble starts when the first contour plotted is fine, but the next and any subsequent contours are flipped on the 45 so Q4 becomes Q2.  The tool allows to scan through contours and going back to contour 1, it is also flipped. 

 

I can't seem to make it make sense and other JMP JSL savvy folks here have looked at the code and are also stumped.  I'm attaching the script and a dummy file for processing.  I have edited the data so a single coordinate is the same for all planes and demonstrates the "flipping" better.

 

/*
Contour/Distortion Plotter V0.1 (Development version)
Author: Wendy J Lawrence
Date: Feb 2019
Purpose: Plot contour for any given measurement equipment file regardless of source/origin
*/

Names default to here(0); 
	Clear globals();
	Clear Symbols();
	Clear log();

// Prompt user to direct to file and open
if(isempty(fpath),
	dataloc = empty();
	fpath = Pick File(
		"Select *-plane.csv File to be processed:",
		dataloc,
		{"CSV Files|csv","Excel Files|csv;xls;xlsx", "All Files|*"},
		1,
		0,
		"*plane*.csv"
	);
);

print("File to be processed: " || fpath);

// Import CSV file 
dt = Open(fpath,
	Invisible(1),
	Import Settings(
		End Of Line( CRLF, CR, LF ),
		End Of Field( Comma, CSV( 0 ) ),
		Strip Quotes( 1 ),
		Use Apostrophe as Quotation Mark( 0 ),
		Scan Whole File( 1 ),
		Treat empty columns as numeric( 0 ),
		CompressNumericColumns( 0 ),
		CompressCharacterColumns( 0 ),
		CompressAllowListCheck( 0 ),
		Labels( 1 ),
		Column Names Start( 1 ),
		Data Starts( 3 ),
		Lines To Read( "All" ),
		Year Rule( "20xx" )
	)
);

//Conversion factor for source data units
if( Any( :units[1] == "English(in)", :units[1] == "Englisch(in)" ),
	MeasConversion = 1,
	MeasConversion = 25.4
);

Column_List = dt << Get Column Names( String );
GoodTitle = "Contour_Point";
PointList = {};

for( thisCol = 1, thisCol <= N Items( Column_List ), thisCol ++,
	if( Starts With( Column_List[thisCol], GoodTitle ),
		Insert Into( PointList, Column_List[thisCol] ),
		)
	);
	
//Convert the list of points into a matrix for plotting
MatTest = dt << Get As Matrix( PointList );

//Save the number of rows of planes for later use
RowsMatTest = N Rows( MatTest );

Radius = 2.9*25.4/2;

// ****Set variables and establish lists
//Reset the starting plane number with each new query
ThisPlane = 1;
ScaleFactor = 20; //( Distortion Factor to make differences visible )

LimitDiff = 5; 

//Empty lists for the coordinates to plot the graph
lstLGX = {};
lstLGY = {};
lstXNom = {};
lstYNom = {};

for( Angle = 0, Angle <= 23, Angle++,
	
	//formulas for Radians, dR Green, LG X, LG Y, x nom, y nom
	Radians = Angle * 15 * pi() / 180;
	if( MeasConversion == 1, dRGreenConv = 25.4, dRGreenConv = 1 );
	dRGreen = MatTest[ ThisPlane, Angle + 1 ] * dRGreenConv; //convert Inches to mm, leave mm as is
	ThisLGX = ( Radius + ScaleFactor*dRGreen ) * Cosine( Radians );
	ThisLGY = ( Radius + ScaleFactor*dRGreen ) * Sine( Radians );
	ThisXNom = ( Radius ) * Cosine( Radians );
	ThisYNom = ( Radius ) * Sine( Radians );
	
	Insert Into( lstLGX, ThisLGX );
	Insert Into( lstLGY, ThisLGY );
	Insert Into( lstXNom, ThisXNom );
	Insert Into( lstYNom, ThisYNom );
);


//Insert the first radius into the last element of each list
lstLGX[25] = lstLGX[1];
lstLGY[25] = lstLGY[1];
lstXNom[25] = lstXNom[1];
lstYNom[25] = lstYNom[1];

//Matrix of each Radii
XCoord = Matrix( lstLGX );
YCoord = Matrix( lstLGY );
XNom = Matrix( lstXNom );
YNom = Matrix( lstYNom );

//Each plotted shape needs to have a Fit Circle for the Chart
obj = Fit Circle( XCoord, YCoord);
objNom = Fit Circle( XNom, YNom);
	
//===========================================================
//
//				EXPRESSIONS/FUNCTIONS
//
//===========================================================	
//Expression to establish plane, part and distortion factor on chart
UpdateCompVal = Expr(
	tbPcNo << Set Text( dt:piece_number[ThisPlane] );
	tbPlaneNo << Set Text( Char( dt:plane[ThisPlane] ) );
	tbDataRow << Set Text( "Row in Data Table: " || Char( ThisPlane ) );
);

//Expression to reset the XY values for the contour display
UpdateXYCoord = Expr(
//reset the lists to properly update the contour plot
	lstLGY = {};
	lstLGX = {};

	For( Angle = 0, Angle <= 23, Angle++, 
		
		//formulas for Radians, dR Green, LG X, LG Y, x nom, y nom
		Radians = Angle * 15 * Pi() / 180;
		If( MeasConversion == 1,
			dRGreenConv = 25.4,
			dRGreenConv = 1
		);
		dRGreen = MatTest[ThisPlane, Angle + 1] * dRGreenConv; //convert Inches to mm, leave mm as is
		ThisLGY = (Radius + ScaleFactor * dRGreen) * Cosine( Radians );
		ThisLGX = (Radius + ScaleFactor * dRGreen) * Sine( Radians );

		Insert Into( lstLGX, ThisLGX, 1 );
		Insert Into( lstLGY, ThisLGY, 1 );

	);

	//Insert the first radius into the last element of both lists
	lstLGX[25] = lstLGX[1];
	lstLGY[25] = lstLGY[1];

	//Matrix of each Radii
	XCoord = Matrix( lstLGX );
	YCoord = Matrix( lstLGY );
	
	//The plotted shape needs to have a Fit Circle for the Chart
	obj = Fit Circle( XCoord, YCoord );
	
);

//for( i = 1, i <=24, i++, Print(Char( XCoord[i] ) || ", "  || Char( YCoord[i]) ) )
//Exrpession to detail Custom Graph Display
RepaintGraph = Expr(

	If( Round( Radius ) - Round( Radius, -1 ) >= 0,
		AxisScale = Round( Radius, -1 ) + 10,
		AxisScale = Round( Radius, -1 ) + 15
	);
	
	NegAxisScale = 0 - AxisScale;

	gbContour = Graph Box(
		X Scale( NegAxisScale, AxisScale ), //Get max and min from Diameter data from Product Master
		Y Scale( NegAxisScale, AxisScale ),
		X Axis( inc( 10 ) ),
		Y Axis( inc( 10 ) ),
		FrameSize( 500, 500 ),
		X Name( "(mm)" ), // << Set Font Size( 15 ),
		Y Name( "(mm)" ),
		Marker( XCoord, YCoord ),
		Line( XCoord, YCoord ),
		Pen Color( "Green" );
		Circle( {objNom[1], objNom[2]}, objNom[3] );
		Pen Color( "Red" );
		Line Style( "Dashed" );
		Pen Color( "Black" );
		Line Style( "Dotted" );
		Line( [0,  0] , Matrix( {AxisScale, NegAxisScale} ) );
		Line( Matrix( {NegAxisScale, AxisScale} ), [0, 0] );
	);
	
);



//==============================================
//
//			User Interface Window
// 
//==============================================
//DO NOT MAKE MODAL!
ThisPlane = 1;
StopPlay = 0;
Contour_win = New Window( "Contour Plot", 
	//<< On Open( <<Move Window( 0, 0 ) ), //Doesn't do anything!
	H Center Box(
		H List Box(	
			V List Box(
				tbDataRow = Text Box( "Row in Data Table: " || Char( ThisPlane ) )
			),
			H List Box(
				Spacer Box( Size( 30, 10 ) ),
				V List Box(
					H Center Box(
						H List Box(
							bbPrev = Button Box( "Prev",
								If( ThisPlane >= 2,
									ThisPlane = ThisPlane - 1;
									UpdateCompVal;
									UpdateXYCoord;
								)
							),							
							bbNext = Button Box( "Next",
								If( ThisPlane <= RowsMatTest - 1,
									ThisPlane = ThisPlane + 1;
									UpdateCompVal;
									UpdateXYCoord;
								)
							)
						)
					),
					Spacer Box( Size( 10, 15 ) ),
					H Center Box(
						V List Box(
							H List Box(
								bbAll = Button Box( "Play All",
									bbNext << Enable( 0 );
									bbPrev << Enable( 0 );
									bbAll << Enable( 0 );
									bbQuit << Enable( 0 );
									ibStop << Set( 1 );
									For( ThisPlane = 1, ThisPlane <= NRows( MatTest ), ThisPlane++,
										Wait( 1 );
										if( StopPlay == 0,
											UpdateCompVal;
											UpdateXYCoord;
											,
											bbNext << Enable( 1 );
											bbPrev << Enable( 1 );											
											bbQuit << Enable( 1 );
											bbAll << Enable( 1 );
											ibStop << Set( 0 );
											StopPlay = 0;
											Stop();
										)
									);
									bbNext << Enable( 1 );
									bbPrev << Enable( 1 );											
									bbQuit << Enable( 1 );
									bbAll << Enable( 1 );
									ibStop << Set( 0 );
									StopPlay = 0;									
								)
							),
							Spacer Box( Size( 10, 5 ) ),
							tbTotalRows = Text Box( "Total Rows: " || Char( N Rows( MatTest ) ) ),							
							Spacer Box( Size( 10, 10 ) ),
							V List Box( bbQuit = Button Box( "Quit",
								Contour_win << Close Window;
								Close( dt, No Save);
							),
							ibStop = If Box( 0, chkStop = Check Box( "Stop", chkStop << Set( 1, 0 ); StopPlay = 1 ) )
							)
						)
					)
				)
			)
		)
	),
	H Center Box(
		V List Box(
			Spacer Box( Size( 30, 10 ) ),
			H Center Box(
				H List Box(
					tbPart = Text Box( "Part No: ", <<Set Font( "Arial Black", 13, "Bold" ) ),
					tbPcNo = Text Box( dt:piece_number[ThisPlane], <<Set Font( "Arial Black", 13, "Bold" ) ),
					Spacer Box( Size( 40, 10 ) ),
					tbPlane = Text Box( "Plane Number: ", << Set Font( "Arial Black", 13, "Bold" ) ),
					tbPlaneNo = Text Box( Char( dt:Plane[ThisPlane] ), << Set Font( "Arial Black", 13, "Bold" ) )
				)
			)				
		)
	),
	gb = RepaintGraph
);
1 ACCEPTED SOLUTION

Accepted Solutions
Craige_Hales
Super User

Re: Matrix for fit circle flips coordinates

You've got X and Y reversed with respect to sin and cos in the two loops over angle.

 

edit: And very nice tool!

Craige

View solution in original post

2 REPLIES 2
Craige_Hales
Super User

Re: Matrix for fit circle flips coordinates

You've got X and Y reversed with respect to sin and cos in the two loops over angle.

 

edit: And very nice tool!

Craige
WendyLou315
Level III

Re: Matrix for fit circle flips coordinates

Oh, my @Craige_Hales !!!  Thank you SO much!  Funny how a fresh set of eyes can make all the difference in the world.

Glad you like our little tool.  It's received a lot of attention.  Glad we found this in Beta testing, though!