Reputation: 31
This is my first time posting here, bear with me as I might mess up the formatting. With the code below, I am trying to get the 2 overlapping/concentric ellipses to repeat a random number of times (in this case I chose 1 through 20) around random places on the 400x400 canvas. I've tried many different things but what keeps happening is the concentric ellipses become scattered and it becomes a mess of color and unrecognizable shapes. The fill must stay within the outside loop and the drawing inside the nested loop.
noStroke();
var flower = function(){
for(var total = 5; total > 0; total--){
fill(random(0,255),random(0,255), random(0,255));
for(var i = 0; i < random(1,20); i++) {
ellipse(200, 200, total * 10, total * 20);
ellipse(200, 200, total * 20, total * 10);
}
}
};
flower();
For reference below, I did something similar except I did it with a while loop and used circles. The same thing needs to happen to my concentric ellipses. I've been trying to follow the same procedures I did with the while loop assignment.
var i = 0;
var circle = function(x,y) {
while (i< random (1, 20)){
stroke(random(0,255),random(0,255), random(0,255));
strokeWeight(random(0,50));
point(random(x,y), random(x,y));
i++;
}
};
draw = function() {
circle(0,400);
};
I feel like I am getting kind of close with this..
noStroke();
var flower = function(x,y){
for(var total = 5; total > 0; total--){
fill(random(0,255),random(0,255), random(0,255));
for(var i = 200; i < random(205, 300); i++) {
ellipse(i + random(x,y), i + random(x,y), total * 10, total * 20);
ellipse(i + random(x,y), i + random(x,y), total * 20, total * 10);
}
}
};
flower(5, 150);
noStroke();
var flower = function(x,y){
for(var total = 4; total > 0; total--){
fill(random(0,255),random(0,255), random(0,255));
for(var i = 0; i < random(1,20); i++) {
ellipse(i + random(x,y), i + random(x,y), total * 10, total * 20);
ellipse(i + random(x,y), i + random(x,y), total * 20, total * 10);
}
}
};
flower(0, 400);
Upvotes: 0
Views: 2550
Reputation: 51837
A simple single for loop should suffice to draw concentric circles.
In your code you do a couple of things that end up being random ellipses rather than concentric circles:
ellipse(i + random(x,y), i + random(x,y), total * 10, total * 20);
will always be en ellipse. For example:
function setup(){
createCanvas(400,400);
noStroke();
background(255);
var x = 200;
var y = 200;
//number of circles
var circles = 9;
//for each circle
for (var total = 0; total < circles; total++) {
//compute circle diameter based on reverse index (circles-total) (or max-current)
var diameter = (circles-total) * 30;
fill(total * 30);
//render the circle
ellipse(x,y, diameter, diameter);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
To get a rainbow effect, you can use colorMode() to swith to the HSB
(hue-saturation-brightness) colour space. This way you simply need to use an increasing hue value. You can even constrain the number of hues.
Here's a demo (mouseX changes the number of circles/hues)
function setup(){
createCanvas(400,400);
noStroke();
}
function draw(){
background(255);
var x = 200;
var y = 200;
//number of circles
var circles = map(mouseX,0,width,7,21);
//change the color mode to HSB (hue,saturation,brightness) - makes it easy to color rainbows, just change the hue
//reduce the hues available to how many circles we use
colorMode(HSB,circles,100,100);
//for each circle
for (var total = 0; total < circles; total++) {
//compute circle diameter based on reverse index (circles-total) (or max-current)
var diameter = (circles-total) * 30;
//change hue for each circle
fill(total,100,100);
//render the circle
ellipse(x,y, diameter, diameter);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
You can draw multiple groups of concentric circles, for example:
var circles = 10;
function setup(){
createCanvas(400,400);
noStroke();
colorMode(HSB,circles,100,100);
}
function draw(){
background(255);
flower(mouseX, mouseY);
flower(mouseX,height-mouseY);
}
var flower = function(x, y) {
for (var total = circles-1; total >= 0; total--) {
var diameter = ((20 + (total * 10)) + frameCount) % 200;
fill(total,100,100);
ellipse(x,y, diameter, diameter);
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
If you want to change positions to keep the circles still somehow grouped, you could use an array to remember past positions then shift the position of each circle by one. This would get you a trails like effect, but the circles will maintain their order so will become concentric whenever the position becomes static:
var circles = 48;
var diameterMin = 20;
var diameterMax = 80;
//store each circle's diameter in this array
var diameter = [];
//store each circle's position in this array
var positions = [];
function setup(){
createCanvas(400,400);
noStroke();
colorMode(HSB,circles-1,100,100);
for(var i = 0; i < circles; i++){
diameter[i] = map(i,0,circles-1,diameterMax,diameterMin);
positions[i] = createVector(200,200);
}
}
function updateCircles(){
//copy positions backwards from last to 2nd
for(var i = circles-1; i > 0; i--){
positions[i].x = positions[i-1].x;
positions[i].y = positions[i-1].y;
}
//set the position of the first based on mouse
positions[i].x = mouseX;
positions[i].y = mouseY;
}
function drawCircles(){
for(var i = 0; i < circles; i++){
fill(i,100,100);
ellipse(positions[i].x,positions[i].y,diameter[i], diameter[i]);
}
}
function draw(){
background(255);
updateCircles();
drawCircles();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
Upvotes: 0
Reputation: 42176
I'm not completely sure what you're asking. Are you asking how to draw both of the circles in the same place each time?
If so, then look at how you're drawing your circles:
ellipse(i + random(x, y), i + random(x, y), total * 10, total * 20);
ellipse(i + random(x, y), i + random(x, y), total * 20, total * 10);
You're calling random(x, y)
a total of four times to come up with random coordinates for each circle. This will cause them to be drawn in different places. If you want to draw them in the same place, then you should only call random(x,y)
a total of two times (once for the X position and once for the Y position) and then use those values for both circles. Something like this:
var circleX = random(x, y);
var circleY = random(x, y);
ellipse(circleX, circleY, total * 10, total * 20);
ellipse(circleX, circleY, total * 20, total * 10);
If this doesn't answer your question then please try to be more specific. Maybe post a mockup of what you want the end result to look like, and try to narrow down the problem to a specific line of code that isn't acting how you expected it to.
Upvotes: 0