I am trying to make rocket explosion in processing - processing

I'm trying to make the lines around the circle in void explosion to appear when tailY == upHeight. I don't know where to place explosion. Can someone help me with this please? The rocket needs to explode when it reaches certain height.
void draw() {
background(0);
drawRocket();
if (tailY == upHeight) {
explosion();
}
}
void explosion() {
noFill();
noStroke();
circle(tailX, tailY, circleSize);
for (int i = 0; i < a; i++) {
float angle;
if (a*i==0)
angle = radians(360.0);
else
angle = radians(360.0/a*i);
float x1 = tailX + circleSize/2 * cos(angle);
float y1 = tailY + circleSize/2 * sin(angle);
float x2 = tailX + (circleSize+10) * cos(angle);
float y2 = tailY + (circleSize+10) * sin(angle);
stroke(red, green, blue);
line(x1, y1, x2, y2);
}
}

You're so close, literally and figuratively :) !
The issue is that you're checking if two floating points value match exactly: if (tailY == upHeight).
If you add println(tailY, upHeight); right before this condition you'll see values get really close, never match, then diverge.
With floating point number it's safer to compare with a bit of tolerance (e.g. if tailY is close to upHeight (with a bit of +/- tolerance).
In you're case, since you only want to see the explosion past a threshold(upHeight) you can loosen the condition (e.g. <=) to:
if (tailY <= upHeight) {
explosion();
}

Related

How to make this pattern to expand and shrink back

i have a task to make a pattern of circles and squares as described on photo, and i need to animate it so that all objects smoothly increase to four times the size and then shrink back to their original size and this is repeated. i tried but i cant understand problem
{
size(500,500);
background(#A5A3A3);
noFill();
rectMode(CENTER);
ellipseMode(CENTER);
}
void pattern(int a, int b)
{
boolean isShrinking = false;
for(int x = 0; x <= width; x += a){
for(int y = 0; y <= height; y += a){
stroke(#1B08FF);
ellipse(x,y,a,a);
stroke(#FF0000);
rect(x,y,a,a);
stroke(#0BFF00);
ellipse(x+25,y+25,a/2,a/2);
if (isShrinking){a -= b;}
else {a += b;}
if (a == 50 || a == 200){
isShrinking = !isShrinking ; }
}
}
}
void draw()
{
pattern(50,1);
}
this is what pattern need to look like
Great that you've posted your attempt.
From what you presented I can't understand the problem either. If this is an assignment, perhaps try to get more clarifications ?
If you comment you the isShrinking part of the code indeed you have an drawing similar to image you posted.
animate it so that all objects smoothly increase to four times the size and then shrink back to their original size and this is repeated
Does that simply mean scaling the whole pattern ?
If so, you can make use of the sine function (sin()) and the map() function to achieve that:
sin(), as the reference mentions, returns a value between -1 and 1 when you pass it an angle between 0 and 2 * PI (because in Processing trig. functions use radians not degrees for angles)
You can use frameCount divided by a fractional value to mimic an even increasing angle. (Even if you go around the circle multiple times (angle > 2 * PI), sin() will still return a value between -1 and 1)
map() takes a single value from one number range and maps it to another. (In your case from sin()'s result (-1,1) to the scale range (1,4)
Here's a tweaked version of your code with the above notes:
void setup()
{
size(500, 500, FX2D);
background(#A5A3A3);
noFill();
rectMode(CENTER);
ellipseMode(CENTER);
}
void pattern(int a)
{
for (int x = 0; x <= width; x += a) {
for (int y = 0; y <= height; y += a) {
stroke(#1B08FF);
ellipse(x, y, a, a);
stroke(#FF0000);
rect(x, y, a, a);
stroke(#0BFF00);
ellipse(x+25, y+25, a/2, a/2);
}
}
}
void draw()
{
// clear frame (previous drawings)
background(255);
// use the frame number as if it's an angle
float angleInRadians = frameCount * .01;
// map the sin of the frame based angle to the scale range
float sinAsScale = map(sin(angleInRadians), -1, 1, 1, 4);
// apply the scale
scale(sinAsScale);
// render the pattern (at current scale)
pattern(50);
}
(I've chosen the FX2D renderer because it's smoother in this case.
Additionally I advise in the future formatting the code. It makes it so much easier to read and it barely takes any effort (press Ctrl+T). On the long run you'll read code more than you'll write it, especially on large programs and heaving code that's easy to read will save you plenty of time and potentially headaches.)

Processing - why does my Random Walker always tend toward the top left?

I am currently going through Daniel Shiffman's 'The Nature Of Code', and have been playing around with one of the first exercises - a simple 'RandomWalker()'. I have implemented similar things in Java & had no trouble, however for some reason my walker always seems to go in more or less the same direction:
RandomWalker
This happens 100% of the time. Here is my code:
class Walker
{
int x;
int y;
// Constructor
Walker()
{
x = width / 2;
y = height / 2;
}
void display()
{
stroke(0); // Colour
point(x, y); // Colours one pixel in
}
void step()
{
float stepX;
float stepY;
stepX = random(-1, 1);
stepY = random(-1, 1);
x += stepX;
y += stepY;
}
}
Walker w;
void setup()
{
size(640, 360);
w = new Walker();
background(255);
}
void draw()
{
w.step();
w.display();
}
Is this some artefact of the random function? My first thought is that it's something to do with the pseudorandom nature of the function but the textbook specifically states that this should not be noticeable, and yet this happens every single time. I was wondering if maybe there's something wrong with my code?
Thanks in advance.
Your x and y variables are both int types. That means that they don't have a decimal part, so any time you add or subtract from them, they are truncated. Here are some examples:
int x = 1;
x = x + .5;
//1.5 is truncated, and x stays 1
int x = 1;
x = x - .5;
//.5 is truncated, and x becomes 0
This is why you see your x and y variables only decreasing. To fix this, just change x and y to float types, so they keep track of the decimals.
If you really need x and y to be int values, then you need stepX and stepY to also be int values:
int stepX;
int stepY;
stepX = (int)random(-5, 5);
stepY = (int)random(-5, 5);
x += stepX;
y += stepY;
But you probably just want to store x and y as float values.
PS: I love random walkers!

Calculate ellipse size in relation to distance from center point

I want to achieve a slow fade in size on every collapse into itself. In other words, when the circle is at its biggest, the ellipses will be at the largest in size and conversely the opposite for the retraction. So far I am trying to achieve this affect by remapping the cSize from the distance of the center point, but somewhere along the way something is going wrong. At the moment I am getting a slow transition from small to large in ellipse size, but the inner ellipses are noticeably larger. I want an equal distribution of size amongst all ellipses in relation to center point distance.
I've simplified the code down to 4 ellipses rather than an array of rows of ellipses in order to hopefully simplify this example. This is done in the for (int x = -50; x <= 50; x+=100).
I've seen one or two examples that slightly does what I want, but is more or less static. This example is kind of similar because the ellipse size gets smaller or larger in relation to the mouse position
Distance2D
Here is an additional diagram of the grid of ellipses I am trying to create, In addition, I am trying to scale that "square grid" of ellipses by a center point.
Multiple ellipses + Scale by center
Any pointers?
float cSize;
float shrinkOrGrow;
void setup() {
size(640, 640);
noStroke();
smooth();
fill(255);
}
void draw() {
background(#202020);
translate(width/2, height/2);
if (cSize > 10) {
shrinkOrGrow = 0;
} else if (cSize < 1 ) {
shrinkOrGrow = 1;
}
if (shrinkOrGrow == 1) {
cSize += .1;
} else if (shrinkOrGrow == 0) {
cSize -= .1;
}
for (int x = -50; x <= 50; x+=100) {
for (int y = -50; y <= 50; y+=100) {
float d = dist(x, y, 0, 0);
float fromCenter = map(cSize, 0, d, 1, 10);
pushMatrix();
translate(x, y);
rotate(radians(d + frameCount));
ellipse(x, y, fromCenter, fromCenter);
popMatrix();
}
}
}
The values you're passing into the map() function don't make a lot of sense to me:
float fromCenter = map(cSize, 0, d, 1, 100);
The cSize variable bounces from 1 to 10 independent of anything else. The d variable is the distance of each ellipse to the center of the circle, but that's going to be static for each one since you're using the rotate() function to "move" the circle, which never actually moves. That's based only on the frameCount variable, which you never use to calculate the size of your ellipses.
In other words, the position of the ellipses and their size are completely unrelated in your code.
You need to refactor your code so that the size is based on the distance. I see two main options for doing this:
Option 1: Right now you're moving the circles on screen using the translate() and rotate() functions. You could think of this as the camera moving, not the ellipses moving. So if you want to base the size of the ellipse on its distance from some point, you have to get the distance of the transformed point, not the original point.
Luckily, Processing gives you the screenX() and screenY() functions for figuring out where a point will be after you transform it.
Here's an example of how you might use it:
for (int x = -50; x <= 50; x+=100) {
for (int y = -50; y <= 50; y+=100) {
pushMatrix();
//transform the point
//in other words, move the camera
translate(x, y);
rotate(radians(frameCount));
//get the position of the transformed point on the screen
float screenX = screenX(x, y);
float screenY = screenY(x, y);
//get the distance of that position from the center
float distanceFromCenter = dist(screenX, screenY, width/2, height/2);
//use that distance to create a diameter
float diameter = 141 - distanceFromCenter;
//draw the ellipse using that diameter
ellipse(x, y, diameter, diameter);
popMatrix();
}
}
Option 2: Stop using translate() and rotate(), and use the positions of the ellipses directly.
You might create a class that encapsulates everything you need to move and draw an ellipse. Then just create instances of that class and iterate over them. You'd need some basic trig to figure out the positions, but you could then use them directly.
Here's a little example of doing it that way:
ArrayList<RotatingEllipse> ellipses = new ArrayList<RotatingEllipse>();
void setup() {
size(500, 500);
ellipses.add(new RotatingEllipse(width*.25, height*.25));
ellipses.add(new RotatingEllipse(width*.75, height*.25));
ellipses.add(new RotatingEllipse(width*.75, height*.75));
ellipses.add(new RotatingEllipse(width*.25, height*.75));
}
void draw() {
background(0);
for (RotatingEllipse e : ellipses) {
e.stepAndDraw();
}
}
void mouseClicked() {
ellipses.add(new RotatingEllipse(mouseX, mouseY));
}
void mouseDragged() {
ellipses.add(new RotatingEllipse(mouseX, mouseY));
}
class RotatingEllipse {
float rotateAroundX;
float rotateAroundY;
float distanceFromRotatingPoint;
float angle;
public RotatingEllipse(float startX, float startY) {
rotateAroundX = (width/2 + startX)/2;
rotateAroundY = (height/2 + startY)/2;
distanceFromRotatingPoint = dist(startX, startY, rotateAroundX, rotateAroundY);
angle = atan2(startY-height/2, startX-width/2);
}
public void stepAndDraw() {
angle += PI/64;
float x = rotateAroundX + cos(angle)*distanceFromRotatingPoint;
float y = rotateAroundY + sin(angle)*distanceFromRotatingPoint;
float distance = dist(x, y, width/2, height/2);
float diameter = 50*(500-distance)/500;
ellipse(x, y, diameter, diameter);
}
}
Try clicking or dragging in this example. User interaction makes more sense to me using this approach, but which option you choose really depends on what fits inside your head the best.

Sorting an array of objects based on one attribute only in Processing

I have a series of randomly plotted lines from a class called Line.
I have put all the objects into an array. I would like to connect any lines that are near each other with a dotted line. The simplest way I can think of doing this is to say if the x1 co-ordinate is <5 pixels from the x1 of another line, then draw a dotted line connecting the two x1 co-ordinates.
The problem I have is how to compare all the x1 co-ordinates with all the other x1 co-ordinates. I think this should involve 1. Sorting the array and then 2. Comparing consecutive array elements. However I want to sort only on x1 and I dont know how to do this.
Here is my code so far:
class Line{
public float x1;
public float y1;
public float x2;
public float y2;
public color cB;
public float rot;
public float fat;
public Line(float x1, float y1, float x2, float y2, color tempcB, float rot, float fat){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.cB = tempcB;
this.rot = rot;
this.fat = fat;
};void draw(){
line(x1, y1, x2, y2);
//float rot = random(360);
float fat = random(5);
strokeWeight(fat);
////stroke (red,green,blue,opacity)
stroke(fat*100, 0, 0);
rotate(rot);
}
}
//Create array of objects
ArrayList<Line> lines = new ArrayList<Line>();
void setup(){
background(204);
size(600, 600);
for(int i = 0; i < 200; i++){
float r = random(500);
float s = random(500);
lines.add(new Line(r,s,r+10,s+10,color(255,255,255),random(360),random(5)));
}
//Draw out all the lines from the array
for(Line line : lines){
line.draw();
//Print them all out
println(line.x1,line.y1,line.x2,line.y2,line.cB,line.rot,line.fat);
}
}
//Now create connections between the elements
//If the x1 of the line is <5 pixels from another line then create a dotted line between the x1 points.
Like the other answer said, you need to compare both end points for this to make any sense. You also don't have to sort anything.
You should be using the dist() function instead of trying to compare only the x coordinate. The dist() function takes 2 points and gives you their distance. You can use this to check whether two points are close to each other or not:
float x1 = 75;
float y1 = 100;
float x2 = 25;
float y2 = 125;
float distance = dist(x1, y1, x2, y2);
if(distance < 100){
println("close");
}
You can use this function in your Line class to loop through other Lines and check for close points, or find the closest points, whatever you want.
As always, I recommend you try something out and ask another question if you get stuck.
The problem lies in the fact that a Line is composed of two points, and despite being tied together (pun intended), you need to check the points of each Line independently. The only point you really don't need to check is other point in the same Line instance.
In this case, it might be in your best interest to have a Point class. Line would then use Point instances to define both ends rather than the raw float coordinates. In this way, you can have both a list of Lines as well as a list of Points.
In this way you can sort Points by x coordinate or y coordinate and grab all points within 5 pixels of your point (and that isn't the same instance or other point in Line instance of course).
Being able to split handling into Points and Lines is important in that you're using multiple views to handle the same data. As a general rule, you should rearrange said data whenever it becomes cumbersome to deal with in its current form. However if I may make a recommendation, the sorting is not strictly necessary. If you're checking a single point with all other points, you'd have to sort repeatedly according to the current point which is more work than simply making a pass in a list to deal with all other points that are close enough.

Processing - show one circle at a time

I have written this code which, on a mouse button press, increases or decreases the number of circles visible, equally spaced around a circle.
int nbr_circles = 2;
void setup() {
size(600, 600);
smooth();
background(255);
}
void draw() {
background(255);
float cx = width/2.0;
float cy = height/2.0;
fill(0);
//float x, y; //
for (int i = 0; i < nbr_circles; i++)
{
float angle = i * TWO_PI / nbr_circles;
float x = cx + 110.0 * cos(angle);
float y = cy + 110.0 * sin(angle);
ellipse(x, y, 20, 20);
}
}
void mousePressed() {
if (mouseButton == LEFT) {
if (nbr_circles < 20)
nbr_circles = nbr_circles + 1;
} else if (mouseButton == RIGHT) {
if (nbr_circles > 2)
nbr_circles = nbr_circles - 1;
}
}
I would like to alter the code so that, with nbr_circles fixed at 10, only one circle is visible at a time, each in turn in successive frames.
I have changed the code a little. The mouse buttons do nothing and the nbr_circles is fixed at 10.
How can I now show one circle at a time?
show circle #1 -> hide circle #1, show circle #2 -> hide circle #2, show circle #3 … -> hide circle #9, show circle #10 -> hide circle #1, show circle #1…
Adjusted code - where is it going wrong?
int nbr_circles = 2;
int i = 1;
void setup () {
size (600, 600);
}
void draw () {
background (255);
fill (0);
float cx = width/2.0;
float cy = height/2.0;
float angle = i * TWO_PI / nbr_circles;
float x = cx + 110.0 * cos(angle);
float y = cy + 110.0 * sin(angle);
ellipse(x, y, 20, 20);
}
if (mouseButton == LEFT) {
if (ellipse(x,y,20,20))
rotate (angle);
}
Thanks in advance.
Taking a step back, I really suggest you start a bit smaller, instead of posting a new question every time you get stuck. It looks like you've got a fundamental misunderstanding of the basic syntax of Processing, so maybe you should go back and do some tutorials until you're more comfortable in it. That's probably the most "correct" answer I can give you, even though it's probably not what you're looking for.
To answer the question of why your adjusted code doesn't work, it's because none of the syntax makes sense. First of all, you've got an if statement outside of a function, which isn't valid. When do you expect that if statement to be executed?
Secondly, you've got the ellipse() function inside an if statement, but the ellipse() function doesn't return a boolean. What do you expect that to do? And finally, what do you expect that rotate function to do?
It seems like you're trying to copy-paste code you found on the internet without really understanding any of it. That's not going to work. You have to take a step back and understand the basics before you can expect to make a program that actually does what you want it to do.
If you edit your "adjusted code" to fix the problems I pointed out, I'll try to help you through the process, but you really should consider going back and starting smaller before trying to get somebody else's code you found on the internet to work.

Resources