[SOLVED] Drawing circles inside a circle (generative dandelion)

THIS QUESTIONS IS SOLVED! :slight_smile:

Hi I am very new to processing and am trying to do roughly the same [as this post (mod edit)], but the resources posted below are not helping me find the solution…

I am now drawing the circles in a different way, and they are not random as I would like them to be.
See here my code:

//Creative Challenge 1. Version 0.1
// Date: 04/10/2022
// Author: Taissia Visser
// Name: Dandelion
// Inspired by: 
// core circle                                                                                                                             
int coreRadius = 90;
//dots to be drawn inside the core circle
int dotcoreRadius = 15;
int radius = 10;
void setup() {
  size(1000, 1000);
  background(255);
  ellipseMode(CENTER);
}
void draw() {
  pushMatrix();
  translate(width/2, height/2);
  fill(#E3E5C9);
  ellipse(0, 0, coreRadius, coreRadius);
  // first and second row of dotcircles in core
  dotcore(30);
  dotcore2(10);
  popMatrix();
}
void dotcore(int radius) {
  for (int degrees = 0; degrees < 360; degrees +=36) {
    float angle = radians(degrees);
    float dotXpos = (sin(angle)* radius);
    float dotYpos = (cos(angle)* radius);
    ellipse(dotXpos, dotYpos, dotcoreRadius, dotcoreRadius);
    }
  }
void dotcore2(int radius){
  for(int degrees = 0; degrees < 360; degrees += 120) {
    float angle = radians(degrees);
    float dotXpos = (sin(angle)* radius);
    float dotYpos = (cos(angle)* radius);
    ellipse(dotXpos, dotYpos, dotcoreRadius, dotcoreRadius);
  }
  }

Is there anyone who could help me? I think I have to use an if statement here, and I would like to make it so that if the x and y coordinates of the smaller circle are within the bigger circle, it draws the ellipse, else not. I would like to fill the whole outer ellipse with smaller circles.

Besides I was wondering if it also possible to know the (x,y) coordinates of the random circles drawn?

Thanks!

Greetings Ties

Hello @Ties2901

You’ll need to store the x, y coordinates in an array or arrayList. Then you can access them to further manipulate or plug into a println().

Also, this project might be good for using PVector, as it’s a built-in class with several methods available.
There are several tutorials on PVector on youtube at the Coding Train. Beginning overview here:

Though, this clearly can be done not using PVector. I suggest it only as a possible solution to explore.
However, since you have an object (a circle) that is a recurring element in your code, you will want to create a class for the circle. So either use the built-in PVector class or write your own class.

:nerd_face:

1 Like

Say println (dotXpos, dotYpos);

Use random for radius : radius = random (5, 200);

You can also use the for loop for the number of dots and make a random angle/ degrees

3 Likes

@Chrisir 's solution is much better!!!

No need to get into writing classes for this. :upside_down_face: I had a momentary bout of madness…
Please disregard my post.
:nerd_face:

3 Likes

Hey Chrisir, thanks!

I wanted to create a for or if loop for drawing the random circles (dotcore) within the main circle (core).

I thought about defining the area of the core circle, and create and if statement that tests if the area of the dotsmall circle falls withing the area of the core circle, if so then it draws the dotcore, else not.
However how to format this in processing is still a bit to advanced for me…

And this I then have to combine with an Array of circles? In that case I definitely need to watch some tutorials about arrays haha.

I have searched for examples but could unfortunately not find anything similar, or something that I understood. Maybe someone could give me an example code?

Thanks!

Kind regards :slight_smile:

Taissia

PS here is what I would like to achieve in the end! It is a creative challenge for my master program in Industrial Design :slight_smile: So I am mainly learning processing because I would like to generate a cool and interesting visual output.

1 Like

In my way above, the circles are just drawn randomly within
the big circle

To avoid overlapping you need to store data and compare

Google packing algorithms

3 Likes

Hello @Ties2901,

You may want to consider a 3D approach to the code; the end result will still be 2D on the screen or printed page.

Example:

There are other ways to do this and I shared mostly for the visual effect.

Each circle in above topic could be a floret\seed head and generated separately; you just make one, add some randomness and transform (translate and rotate) it… then the next one.

You would have to place or pack circles on a sphere as required… this is very achievable.

There is definitely order in nature with a touch of randomness:

Cool personal challenge!

:)

1 Like

Hi

Here is some hints colse for your demand
I think you need to use 3D
https://funprogramming.org/77-A-3D-rotating-cloud-of-points.html

https://funprogramming.org/78-An-array-is-like-a-book-full-of-numbers.html

https://funprogramming.org/79-A-spinning-star-becomes-a-plant.html

1 Like

sounds like circle packing with the added requirement of a circular arrangement…

1 Like

Old forum has some insights… and code :stuck_out_tongue:
this box below looks like it’s pointing to the home of the forum, but is actually pointing to a page…

2 Likes

It seems like you don’t really want a random sampling of points in the circle so much as you want a uniform distribution of points on a sphere. One of the simplest ways to generate N points approximately uniformly spread out on a sphere is to sample points along a Fibonacci spiral wrapping from pole to pole. Many plants follow a Fibonacci spiral for their seed spacing so this is not only easier to use but quite likely more scientifically accurate for your purpose.

http://extremelearning.com.au/evenly-distributing-points-on-a-sphere/ gives a nice description of the equations along with some tweaks to improve the sampling near the poles.

Edit: his follow-up post http://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/ might be a little easier to understand.

float goldenRatio = (1.0+sqrt(5))*0.5;
int N = 200;
float epsilon = 1.33;
float ballrad = sqrt(2.5/N);

void setup() {
  size( 900, 900, P3D );
  noStroke();
}

void ball( float theta, float phi ) {
  theta *= TAU;
  phi = acos( 1. - 2.*phi );
  pushMatrix();
  translate( cos(theta)*sin(phi), sin(theta)*sin(phi), cos(phi) );
  sphere( ballrad );
  popMatrix();
}

void draw() {
  background( 64 );
  camera( 0, 0, 4,  0, 0, 0,  0, 1, 0 );
  frustum( -1, 1, -1, 1, 2.5, 6.5 );
  lights();
  rotateY( 0.01*frameCount );
  fill( 128 );
  sphere(1.);
  fill( 255 );
  ball( 0, 0 );
  ball( 0, 1 );
  for( int i=1; i<N-1; i++ ) {
    float theta = i / goldenRatio;
    float phi = (i+epsilon)/(N-1+2*epsilon);
    ball( theta, phi );
  }
}
1 Like

So cool how everyone has its own ideas and imput! Thanks!! First time I have asked ‘the public’ how they would tackle a challenge and I am super amazed by all the replies.

Definitely motivates me to try out the suggestions everyone gave :slight_smile:

Greetings,

Taissia

3 Likes

Hii everyone,

I have started to work with the Circle Packing Algorithm since I am required to deliver a 2D code and pdf, and not a 3D one (although after this assignment I am definitely going to check 3D objects out because the examples I saw looked super cool).

I am currently following this youtube tutorial:

But I have run into a problem (time 12.40 in the video).

Whenever I try to write this code:

Dotcore newDT = newDot();
if(newDT != null){
Dotcore.add(newDT);

It gives me an error; namely that my function Dotcore newDot() { is missing a “;”.
I have tried to find where to place this “;” but I really cannot debug the code. Is there anyone who knows what is happening?

Here the error, its on the first tab:

> ArrayList<Dotcore>dotcores;
int corewidth = 90;
int coreheight = 90;
int Xcore = 500;
int Ycore = 500;
void setup () {
  size(1000, 1000);
  dotcores = new ArrayList<Dotcore>();
}
void draw () {
  background(255);
  fill(#EDF0D7);
  ellipse(Xcore, Ycore, corewidth, coreheight);
  Dotcore newDT = newDot();
  if(newDT != null){
    Dotcore.add(newDT);
  for (Dotcore DT : dotcores) {
    if (DT.edges()) {
      DT.growing = false;
    }
    DT.show();
    DT.grow();
  }
}Dotcore newDot() {
  pushMatrix();
  translate(width/2, height/2);
  float x = random(Xcore-corewidth/2, Xcore+coreheight/2);
  float y = random (Ycore- coreheight/2, Ycore+coreheight/2 );
  popMatrix();
  boolean valid = true;
  for (Dotcore DT : dotcores) {
    float d = dist(x, y, DT.x, DT.y);
    if (d<DT.r) {
      valid = false;
      break;
    }
  }
  if (valid) {
    return new Dotcore(x, y);
  } else {
    return null;
  }
}

this is my second tab;

> class Dotcore {
  float x;
  float y;
  float r;
  boolean growing = true;
  Dotcore(float x_, float y_) {
    x = x_;
    y = y_;
    r = 2;
  }
  void grow() {
    if (growing) {
      r = r +1;
    }
  }  
  boolean edges() {
    return (x + r > Xcore + corewidth/2 || x - r < Xcore - corewidth/2 || y + r > Ycore + coreheight/2 || y - r < Ycore - coreheight/2);
  }
  void show() {
    stroke(0);
    fill(#D7DBAF);
    ellipse(x, y, r*2, r*2);
  }
}

Thanks! Help is always appreciated :slight_smile:

Greetings Taissia

When posting code please format it…
I think you are missing a bracket to close draw() added below…

ArrayListdotcores;
int corewidth = 90;
int coreheight = 90;
int Xcore = 500;
int Ycore = 500;
void setup () {
	size(1000, 1000);
	dotcores = new ArrayList();
}
void draw () {
	background(255);
	fill(#EDF0D7);
	ellipse(Xcore, Ycore, corewidth, coreheight);
	Dotcore newDT = newDot();
	if(newDT != null){
		Dotcore.add(newDT);
		for (Dotcore DT : dotcores) {
			if (DT.edges()) {
				DT.growing = false;
			}
			DT.show();
			DT.grow();
		}
	}
}// I think you are missing this '}' here   !!


Dotcore newDot() {
	pushMatrix();
	translate(width/2, height/2);
	float x = random(Xcore-corewidth/2, Xcore+coreheight/2);
	float y = random (Ycore- coreheight/2, Ycore+coreheight/2 );
	popMatrix();
	boolean valid = true;
	for (Dotcore DT : dotcores) {
		float d = dist(x, y, DT.x, DT.y);
		if (d<DT.r) {
			valid = false;
			break;
		}
	}
	if (valid) {
		return new Dotcore(x, y);
	} else {
		return null;
	}
}
2 Likes

Sorry, did not receive a message yet from the platform on how to format the code, but just read it!

Unfortunately placing an extra bracket (or two) does not solve the error. It gives me the error:

Hi @Ties2901
To format your code use preformatted text

خ

1 Like

Hello @Ties2901,

Processing Forum guidelines:
https://discourse.processing.org/t/guidelines-answering-questions/2145/6

Try to cut and past your code and you will see why we ask the community to format code:
https://discourse.processing.org/faq#format-your-code

Take a look at this example and make the necessary corrections to your code:

:)

1 Like

Hii everyone!

I have continued my project and am experiencing some problems with creating a circular boundary in which the circle can be packed.

Until now I only managed to make this area a square, but how do I make this a circle?

// Creative Challenge 1. Version.9
// NAME: CRAZY GROWING DANDELION
// DATE: 07/10/2022
// AUTHOR: TAISSIA VISSER
// INSPIRED BY:
// REFERENCES:


ArrayList<Dotcore>dotcores;
int corewidth = 150;
int coreheight = 150;
int Xcore = 500;
int Ycore = 500;
int dotcounter = 20;
float seedsangle = 0.0;
int seedscounter = 100;
int counter = 0;
//ArrayList<Seed>seeds;

void setup () {
  background(255);
  size(1000, 1000);
  dotcores = new ArrayList<Dotcore>();
}

void draw () {
  // CORE DANDELION
  noStroke();
  fill(#EDF0D7);
  ellipse(Xcore, Ycore, corewidth, coreheight);

  // DOTS IN THE CORE
  pushStyle();
  newDot();
  for (Dotcore DT : dotcores) {
    if (DT.edges()) {
      DT.growing = false;
    }
    DT.show();
    DT.grow();
  }
  popStyle();

  pushStyle();
  if (counter == 0) {
    fill(3);
    ellipse(500, 500, 400, 400);
  }
  popStyle();

  stem(500, 520);

pushStyle();
  counter = counter +1;
  if (counter < seedscounter) {
    seeds(500, 500, 85);
  }
  popStyle();
}

void seeds(int x, int y, int radius) {
  seedsangle += random (-5, 5);
  x += (cos(seedsangle)*radius);
  y += (sin(seedsangle)*radius);
  translate (x, y);
  rotate(seedsangle);
  fill(#B4A47A);
  stroke(#98885F);
  strokeWeight(1);
  ellipse(0, 0, 20, 5);
}

void newDot() {
  pushMatrix();
  translate(width/2, height/2);
  float x = random(Xcore-corewidth/2, Xcore+coreheight/2);
  float y = random (Ycore- coreheight/2, Ycore+coreheight/2 );
  popMatrix();

  boolean valid = true;
  for (Dotcore DT : dotcores) {
    float d = dist(x, y, DT.x, DT.y);
    if (d<DT.r) {
      valid = false;
      break;
    }
  }
  if (valid) {
    dotcores.add(new Dotcore(x, y));
  }
}

void stem(int x, int y) {
  pushMatrix();
  translate(x, y);
  strokeWeight(20);
  stroke(#C4C94F);
  line(0, 0+60, 0, height);
  popMatrix();
}

this is the second tab

class Dotcore {

  float x;
  float y;
  float r;

  boolean growing = true;

  Dotcore(float x_, float y_) {
    x = x_;
    y = y_;
    r = 1;
  }

  void grow() {
    if (growing) {
      r = r +1;
    }
  }

  boolean edges() {
    //return (x + r > Xcore + corewidth/2 || x - r < Xcore - corewidth/2 || y + r > Ycore + coreheight/2 || y - r < Ycore - coreheight/2 || r > 7 );

    return (x + r > Xcore + (2*PI*(corewidth/2)) || x - r < Xcore - (2*PI*(corewidth/2)) || y + r > Ycore + (2*PI*(corewidth/2)) || y - r < Ycore -(2*PI*(corewidth/2)) || r > 7 );

    //return (x+(2*PI*r)>Xcore+(2*PI*(corewidth/2))|| x-(2*PI*r) < Xcore-(2*PI*(corewidth/2))|| y + (2*PI*r) > Ycore+(2*PI*(corewidth/2)) || y - (2*PI*r) < Ycore-(2*PI*(corewidth/2)) ||r>7 ) ;

    //return ((2*PI*r)>(2*PI*(corewidth/2))||  (2*PI*r) > (2*PI*(corewidth/2)) || r>7 ) ;
  }

  void show() {
    stroke(#9CA25F);
    strokeWeight(1);
    fill(#E3E8B0);
    ellipse(x, y, r*2, r*2);
  }
}

I would love to see your suggestions because i really dont know how to solve this!

As you can see, the dots appear in a rectangular shape, and not the shape of an ellipse.

I created a boolean to return a true or false and with that to stop the circles from forming,

boolean edges() {
    //return (x + r > Xcore + corewidth/2 || x - r < Xcore - corewidth/2 || y + r > Ycore + coreheight/2 || y - r < Ycore - coreheight/2 || r > 7 );

    return (x + r > Xcore + (2*PI*(corewidth/2)) || x - r < Xcore - (2*PI*(corewidth/2)) || y + r > Ycore + (2*PI*(corewidth/2)) || y - r < Ycore -(2*PI*(corewidth/2)) || r > 7 );

    //return (x+(2*PI*r)>Xcore+(2*PI*(corewidth/2))|| x-(2*PI*r) < Xcore-(2*PI*(corewidth/2))|| y + (2*PI*r) > Ycore+(2*PI*(corewidth/2)) || y - (2*PI*r) < Ycore-(2*PI*(corewidth/2)) ||r>7 ) ;

    //return ((2*PI*r)>(2*PI*(corewidth/2))||  (2*PI*r) > (2*PI*(corewidth/2)) || r>7 ) ;
  }

All of these different options did not work. :frowning:

1 Like

I think you need to implement the dist() function in combination with your radius measurement variables to detect the outer edge of the circle.
This video may be of use, though disregard the section about noise() as it is not relevant to what you are solving right now.
https://funprogramming.org/60-Are-two-circles-touching-or-intersecting.html
Hopefully, this is helpful.
:nerd_face:

2 Likes

Hello @Ties2901,

There is a topic here for random distribution within a circle:

I was able to integrate with your code and achieve this:

image

:)

1 Like