Subscribe Bookmark RSS Feed

Re: Creating Grid of Rectangles Using a For Loop

nqj

Occasional Contributor

Joined:

May 19, 2017

Hi,

 

I am trying to create an array of 24x2 rectangles in a new window. I can manually create these using the JSL commands for the graph box but I know that it can be done using a for loop which would be much quicker. I only need the rectangles to be two dimensions for now, and here is the following code that I was attempting to implement:

y1 = 5;
y2 = 10;
win = New Window("Spine",
		gb = Graph Box(
			Frame Size(1000,1000),
		)
	);
	
For(i = 0, i<24, i++,
	Rect(5,y1,10,y2);
	y1 = y2+1;
	y2 = y1+5;
	gb<<reshow;
);

but it doesn't seem to be working nor throwing me any errors. Thanks for any help.

 

1 ACCEPTED SOLUTION

Accepted Solutions
txnelson

Super User

Joined:

Jun 22, 2012

Solution

The Graph Box() is dynamic and when coupled with your code, everytime it attemps to refresh the screen, your y values are increasing in size.  See the code below for a fix for the issue

Names Default To Here( 1 );
win = New Window( "Spine",
	gb = Graph Box(
		Frame Size( 1000, 1000 ),
		Y Scale( 0, 500 ),
		X Scale( 0, 500 ),
		For( i = 1, i < 25, i++,
			If( i == 1,
				y1 = 5;
				y2 = 0;
			);
			Rect( 45, y1, 50, y2 );
			Rect( 50, y1, 55, y2 );
			y2 = y1 + 1;
			y1 = y1 + 6;
				
		)
	)
);
Jim
8 REPLIES
txnelson

Super User

Joined:

Jun 22, 2012

There are a couple of issues.

1. The "rect" in your code are outside of the Graph Box() and so they do not know where to apply the rectangle.

2. Your X and Y  axis specifications go outside of the range of the Graph Box().

Here is some starter code that should help you get going

Names Default To Here( 1 );
y1 = 5;
y2 = 10;
win = New Window( "Spine",
	gb = Graph Box(
		Frame Size( 1000, 1000 ),
		For( i = 0, i < 5, i++,
			Rect( 5,y1, 10,y2);
			y1 = y2 + 1;
			y2 = y1 + 5;
		);
	)
);
Jim
nqj

Occasional Contributor

Joined:

May 19, 2017

Thanks! So far I have this, which somewhat works, but is placing the rectangles at position y~125 instead of y = 5 and y = 0. Any ideas as to why this may be?

Names Default to Here(1);
y1 = 5;
y2 = 0;

win = New Window("Spine",
		gb = Graph Box(
			Frame Size(1000,1000),
			Y Scale(0,500),
			X Scale(0,500),
			For(i=1,i<25,i++,
				Rect(45,y1,50,y2);
				Rect(50,y1,55,y2);
				y2 = y1+1;
				y1 = y1+6;
				
			);
		)
	);
txnelson

Super User

Joined:

Jun 22, 2012

Solution

The Graph Box() is dynamic and when coupled with your code, everytime it attemps to refresh the screen, your y values are increasing in size.  See the code below for a fix for the issue

Names Default To Here( 1 );
win = New Window( "Spine",
	gb = Graph Box(
		Frame Size( 1000, 1000 ),
		Y Scale( 0, 500 ),
		X Scale( 0, 500 ),
		For( i = 1, i < 25, i++,
			If( i == 1,
				y1 = 5;
				y2 = 0;
			);
			Rect( 45, y1, 50, y2 );
			Rect( 50, y1, 55, y2 );
			y2 = y1 + 1;
			y1 = y1 + 6;
				
		)
	)
);
Jim
nqj

Occasional Contributor

Joined:

May 19, 2017

thanks! works perfectly. is there any way to retrieve the points used to create the rectangles as a matrix? and is there a simple way to extend this idea to 3 dimensions using JSL's OpenGL implementation?

txnelson

Super User

Joined:

Jun 22, 2012

I am not practiced with the OpenGL accessing of JMP, so I can not answer your question on how much of the graphical environment is available to it.

Concerning your other issue, I will point you to the Sample Scripts distributed with JMP, which will show you how using a 3D Scene opens up a whole world of 3D capabilities.  In particular, I will point you to the MatrixRotation and PatchEditor scripts, in which the code has feedback loops for detecting what has been drawn, and allow manipulation of those objects.

To access the samples, just go to

     Help==>Sample Data

and then from the window that is opened, then select "Open the Sample Scripts Directory"

Jim
Highlighted
Craige_Hales

Staff

Joined:

Mar 21, 2013

Here's a way to make 3D cubes, without learning OpenGL, if you don't need too many. It is really plotting the outlines with points, so the number of points can get out of hand pretty quickly and make it too slow. This example uses 12K points and still performs well.

3D matrix of cubes3D matrix of cubes

// make cube outlines using scatter plot points
dt = New Table( "cubes", New Column( "xx" ), New Column( "yy" ), New Column( "zz" ) );

make cube = function({dt,x0,x1,y0,y1,z0,z1},{x,y,z},
    if(x1<x0, x=x0;x0=x1;x1=x;);
    if(y1<y0, y=y0;y0=y1;y1=y;);
    if(z1<z0, z=z0;z0=z1;z1=z;);
	for(x=x0,x<=x1,x+=(x1-x0)/16,
            dt<<addrows(1); dt:xx=x;dt:yy=y0;dt:zz=z0;
            dt<<addrows(1); dt:xx=x;dt:yy=y0;dt:zz=z1;
            dt<<addrows(1); dt:xx=x;dt:yy=y1;dt:zz=z0;
            dt<<addrows(1); dt:xx=x;dt:yy=y1;dt:zz=z1;
	);
	for(y=y0,y<=y1,y+=(y1-y0)/16,
            dt<<addrows(1); dt:yy=y;dt:xx=x0;dt:zz=z0;
            dt<<addrows(1); dt:yy=y;dt:xx=x0;dt:zz=z1;
            dt<<addrows(1); dt:yy=y;dt:xx=x1;dt:zz=z0;
            dt<<addrows(1); dt:yy=y;dt:xx=x1;dt:zz=z1;
	);
	for(z=z0,z<=z1,z+=(z1-z0)/16,
            dt<<addrows(1); dt:zz=z;dt:yy=y0;dt:xx=x0;
            dt<<addrows(1); dt:zz=z;dt:yy=y0;dt:xx=x1;
            dt<<addrows(1); dt:zz=z;dt:yy=y1;dt:xx=x0;
            dt<<addrows(1); dt:zz=z;dt:yy=y1;dt:xx=x1;
	);
		
	);

For( xc = 20, xc <= 80, xc += 15,
    For( yc = 20, yc <= 80, yc += 20,
        For( zc = 20, zc <= 80, zc += 30,
            make cube( dt, xc - 3, xc + 3, yc - 3, yc + 3, zc - 3, zc + 3 )
        )
    )
);


dt<<Scatterplot 3D(Y( :xx, :yy, :zz ));
Craige
txnelson

Super User

Joined:

Jun 22, 2012

Cool

Jim
Craige_Hales

Staff

Joined:

Mar 21, 2013

In my example, I intended for the number of points to always be the same, but floating point round-off errors make this code

for(y=y0,y<=y1,y+=(y1-y0)/16

sometimes generate 16 vs 17 steps. A better way to write this would look something like this:

 

nsteps = 16;

for( iy = 0, iy <= nsteps, iy += 1,
   y = y0 + iy * (y1 - y0) / nsteps;

you could easily modify that loop to leave out the corner points rather than duplicating (triplicating?) them...for(iy=1, iy < nsteps, ...

Craige