We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, I've made a sketch of circles that grow (some which then disappear) when you click the mouse. What I'm trying to make happen is every time an expanding circle touches another a new expanding circle will spawn on that point.
I've tried doing this using a simple hit test, but obviously it doesn't work as well aesthetically because the hit test runs on squares. I read that the best way to do it is using "cart to polar" (?) but I just don't know what to do concerning this.
Any help on making this work would be much appreciated :)
Here is the code I've got so far (left click creates circles that disappear as they grow, right click creates circles that will just keep on growing without fading, and spacebar will clear the page):
ArrayList circles = new ArrayList();
void setup() {
size(1280, 720, P2D);
smooth();
}
void draw(){
background(50);
for (int i=0; i<circles.size(); i++) {
ExpandingCircle ec = (ExpandingCircle) circles.get(i);
ec.update();
ec.display();
if (ec.transparency <= 0) { circles.remove(i); } // remove invisible circles
}
}
class ExpandingCircle {
int x,y;
float radius;
color c;
boolean transparencyOn;
int transparency;
ExpandingCircle(int x, int y, boolean transparencyOn) {
this.x = x;
this.y = y;
this.transparencyOn = transparencyOn;
c = color(random(150, 255),random(150, 255),random(150, 255), 100);
//c = color(random(255), 100);
//c = color(255, 150);
transparency = 255;
}
void update() {
radius++;
if (transparencyOn && radius >= 50 && transparency > 0) { transparency--; }
}
void display() {
noStroke();
fill(c,transparency);
ellipse(x,y,radius,radius);
}
}
void mousePressed()
{
if (mouseButton == RIGHT) { circles.add(new ExpandingCircle(mouseX,mouseY,false));
} else { circles.add(new ExpandingCircle(mouseX,mouseY,true)); }
}
void keyPressed() {
if (key == ' ') { circles.clear(); }
}
Answers
Can't you just use the distance between the center points of the circles? If that value is within some threshold of the sum of their radiuses, then the two circles are touching.
Perhaps most diff. part gonna be avoid triggering it more than once! :-SS
Yep, that's why I said "within some threshold" instead of "less than".
Even within a threshold, it's gonna be triggered many times @ 60 FPS me guess! (%)
That depends on what you use a threshold.
Hello ! I may will do something like that
1) inside your circle-objects, create an arrayList that will register every already contacted circles.
2) still inside your circle-object, create a function "hittest" with a circle-object as parameter. Inside that function, check the distance between the center of the circle and the center of the other circle. If the distance is less than the sum of the radius of the two circle, then there is a collision.
3-a) if you find a collision between 2 circles, loop on your arrayList to see if the collided-circle is already registred. If not, register it and create a new circle at the collision point. To get the position of the collision point. You need to get the angle from the center of your object to the other circle (you just have to use atan2 function to do it). Then the collision point will be there
3-b) during the arrayList-loop, check the alpha of each registered circle. If a circle is transparent, remove it.
That's all !
If you do that, you will be sure that each circle can collide only one time with another circle (but can still collide the other non-collided yet circles)
Good luck :)
Appending to what @tlecoz said above, another alternative for registering "touched pairs": O:-)
int
or even achar
, since the latter can't be negative (unsigned) after all.new
ExpandingCircle objects, pass++counter
as its extra argument and assign it as their id internal field.total = 5 * 3 = 15
.new
ExpandingCircle object w/ next++counter
id.Hello GoToLoop ,
I think your solution is a bit weird, at least for the first 100 circles because if the circle#2 touches the circle#3, then those 2 circles could nevers collide with circle#6. It's just an example but there are other possibilities.
You can solve that easily : you just have to start your id by 1000 instead of 0. Then you have, in the worst case, one chance on a million to miss a collision.
@tlecoz, my rationale was a little too much ahead I agree! ~:>
But it could happen w/ 3 ExpandingCircle objects create at the same time, w/ 2 of it near each other and another a little farther. Also w/ diff. growth speeds! 8-X
That
++counter
would add 1 to counter 1st. And thus it'd never be 0 until overpassing its type capacity. :-BThanks so much for all the help guys! But I'm very new to this whole coding thing, as I really appreciate your advice but I don't actually know how to implement it.
tlecoz, your three steps sound like just what I need to do! But where exactly is my circle-objects and how do I create an array list that registers already contacted circles? I'm not even sure how to let the circles know that they are touching.
I'm sure some of this must be quite simple stuff, but again, please bare with a complete coding newbie :)
@GoToLoop : you can increment by one and start your index at 1000, it's not an opposite idea. I just say that instead of write that
int counter; void setup(){ counter = 0; }
you should write that
int counter; void setup(){ counter = 1000; }
@AlfieChillar : you must to try a little bit by yourself, look at the examples, look at the reference at "arrayList". If it still not working, send us your current code and we 'll look at it :)
int counter; void setup(){ counter = 0; }
All Java fields got default initial values. An
int
is already 0! O:-)And
++counter
would add 1 and return updated value! Hence 1stid = 1
! :-bd??? I really think you don't understand what I mean....
"All Java fields got default initial values. An int is already 0! "
"And ++counter would add 1 and return updated value! Hence 1st id = 1! "
.....Ok.......
Do you think the universe will crash on itself if I assign 1000 to my Int in the setup function and then increment it using myInt++ or ++myInt ?
Really, don't see / understand the problem. The default value of a Int is 0. Ok , I never said the contrary. Now is it possible to set his value to 1000 in the setup values ? - I bet it's possible -
and then, is it possible to say "that int, greater or equal to 1000" would be our circle-id. The next circle-id would be 1001, and the next 1002, and so on ? - I bet it's possible too -
If it's possible, then the "collision-ID " between circle1001 et circle1002 would be 1001x1002. Every other ID would work then there is less a chance on a million to meet a bug
That's all......
EDIT : sorry for the tonality of my message. I was just awake and im a bad guy the morning :)
Indeed starting w/ minimum values like 1, 2, 3 got high chances of duplicate pairs.
Perhaps 11 is already a pretty enough starting value rather than 1000, but whatever! X_X
I wish I had something better than multiplication for determining a pair uniqueness! :-<