turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- JMP User Community
- :
- Discussions
- :
- Discussions
- :
- Re: Creating Grid of Rectangles Using a For Loop

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 6:06 AM
(1762 views)

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.

Solved! Go to Solution.

1 ACCEPTED SOLUTION

Accepted Solutions

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 8:12 AM
(3279 views)

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 7:02 AM
(1751 views)

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 7:34 AM
(1747 views)

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; ); ) );

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 8:12 AM
(3280 views)

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 8:25 AM
(1730 views)

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?

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 28, 2017 10:31 AM
(1718 views)

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
##
##### Re: Creating Grid of Rectangles Using a For Loop

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 29, 2017 6:13 AM
(1700 views)

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.

```
// 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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Dec 29, 2017 7:01 AM
(1694 views)

Cool

Jim

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Jan 4, 2018 10:55 AM
(1574 views)

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