Enjoy an ad free experience by logging in. Not a member yet? Register.

Results 1 to 4 of 4

11222010, 06:16 AM #1
 Join Date
 Nov 2010
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
Math.random and fillRect with HTML5 Canvas
Hello, I'm new here so.. hi! You'll probably be seeing me a lot. Anyways here's my questions.
I am trying to get a function to draw 5 randomly sized and colored rectangles nested within each other. Meaning each rectangle should not go outside the boundaries of the rectangle it is in. The color thing I've got down in arandomColor()
function. It's the nesting rectangles inside rectangles that is confusing me (hense me being up for the past 4 hours trying to understand it) I started out with very simple code just making 5 rectangles of reducing sizes nested in each other, then added the Math.random to randomize all the sizes. Now I'm at this point and have lost my way. Please help, or maybe there is just an easier way. I added a bunch of comments in my code so maybe you'll understand what I'm trying to do.
Code:function rect() { // rectangle generator autoctx.clearRect(0, 0, 400, 400); // clear canvas // declare variables var x; var y; var width; var height; var i = 0; // counter // create random x,y coordinates x = Math.round(Math.random() * 100); y = Math.round(Math.random() * 100); do { // create random size rectangle width = Math.round(Math.random() * 400); height = Math.round(Math.random() * 400); } while (width < 100  height < 100); // make sure rectangle is big enough autoctx.fillStyle = randomColor(); // Runs random color generator autoctx.fillRect(x, y, width, height); // fill first rectangle do { x += (Math.round(Math.random() * 15)); // choose new random coordinates within previous rectangle y += (Math.round(Math.random() * 15)); // choose new random coordinates within previous rectangle //*********** KEEPS RECTANGLE HEIGHT AND WIDTHS FROM BEING A NEGATIVE NUMBER ***********// do { //*** WIDTH TESTER ***// validates width to be within previous rectangles width var testW = 0; // new width tester variable testW = width  (Math.round(Math.random() * (2 * x))); // store test width if (testW > 0) { width = testW; // if test width > 0 store in width } } while (testW < 0); // if test width < 0 continue loop do { //*** HEIGHT TESTER ***// validates height to be within previous rectangles height var testH = 0; // create height testing variable testH = height  (Math.round(Math.random() * (2 * y))); // calculate new test height if (testH > 0) { // if test height is > 0 height = testH; // store as height } } while (testH < 0); // if test height < 0 try again //*** Fills final rectangle values ***// autoctx.fillStyle = randomColor(); // Runs random color generator autoctx.fillRect(x, y, width, height); i++; // add 1 to counter } while (i < 4); // kick out of loop after the 5th rectangle }
11222010, 02:37 PM
#2
 Join Date
 Apr 2003
 Location
 Bucharest, ROMANIA
 Posts
 8,478
 Thanks
 58
 Thanked 379 Times in 375 Posts
In my opinion this should be rather a problem of analyzing and timing your operations. It has nothing to do with HTML5. It's just a logical sequence.
You have to focus on creating sets of (x,y,width,height) for all the 5 rectangles, following 2 simple rules:
After you create, randomly, the first set, try (in a loop) the new random set till:
1. the x in the new set is grater than the x from the first set. Same for the y.
2. the width in the new set is smaller than the width from the first set. same for the height.
Now repeat the operation. Except that the x,y,width and height value for comparison will be now the values from the previous created set.
All these should be don within a separate function which, in the end, should return an array (or an object), like:
Only now you should start the loop for fillStyle() and fillRect()Code:[ [x1,y1,w1,h1], [x2,y2,w2,h2], [x3,y3,w3,h3], [x4,y4,w4,h4], [x5,y5,w5,h5] ]
Need an example?
Last edited by Kor; 11222010 at 03:18 PM.
11222010, 03:56 PM
#3
 Join Date
 Apr 2003
 Location
 Bucharest, ROMANIA
 Posts
 8,478
 Thanks
 58
 Thanked 379 Times in 375 Posts
Here's a quick example (untested):
Where the arguments passed are the canvas properties:Code:function returnSets(X,Y,W,H){ var minX=X,minY=Y,maxW=W,maxH=H; var arr=[], x,y,w,h; for(var i=0;i<5;i++){ x=Math.floor((WminX+1)*Math.random()+minX); y=Math.floor((HminY+1)*Math.random()+minY); w=Math.floor((maxW+1)*Math.random()); h=Math.floor((maxH+1)*Math.random()); arr[arr.length]=[x,y,w,h]; minX=x;minY=y;maxW=w;maxH=h; } return arr }
X=0 //extreme left
Y=0 //extreme top
W= the canvas width
H= the canvas height
Could not work properly, but at least I hope it illustrates the idea behind.
Last edited by Kor; 11222010 at 04:17 PM.
11222010, 07:28 PM
#4
 Join Date
 Nov 2010
 Posts
 7
 Thanks
 0
 Thanked 0 Times in 0 Posts
I think I understand what you are suggesting and I like it. In fact, that's pretty much what I was going for but without the arrays (I don't completely understand how to use arrays yet) I think what I'm looking for is the math formulas to place the x, y coordinates inside the top left quadrant of the previous rectangle, and have the width and height fall in the bottom right quadrant of that same rectangle, making it inside the rectangle.