I am currently working on an ArrayList of an ArrayList that I want the outer ArrayList to have different locations.
So I tried to use thetranslate(); to distinguish the position of the outer ArrayList but it doesn't work. On screen it is still showing all the ArrayList at one place.
I have also tried to multiply the points location with point(v3.x * gap, v3.y * gap, v3.z * gap); but it doesn't work neither.
Does anyone knows is ther a way on how can I alter the location of outer ArrayList?
Here are the codes I am working on:
//import
import peasy.*;
//import variables
PeasyCam acam;
//position variable for pointSphere
float x;
float y;
float z;
float gap = 500;
//arraylist of arraylist
ArrayList<ArrayList <PVector>> sphereList = new ArrayList<ArrayList<PVector>>();
//empty arraylist
ArrayList<PVector> sphere1 = new ArrayList<PVector>();
void setup() {
size(1920, 1080, P3D);
//camera setting
acam = new PeasyCam(this, 500, 500, 500, 2000);
acam.rotateX(0);
acam.rotateY(0);
acam.rotateZ(0);
pointSphere(270, 27, 27);
}
void draw() {
background(0);
for (int i = 0; i < sphere1.size(); i++) {
PVector v1;
v1 = sphere1.get(i);
stroke(255);
strokeWeight(random(2, 10));
point(v1.x, v1.y, v1.z);
for (int j = 0; j < sphereList.size(); j++) {
PVector v3;
v3=sphereList.get(i).get(j);
pushMatrix();
gap = gap + 500;
translate(1000 + gap, 1000 + gap, 1000 + gap);
point(v3.x, v3.y, v3.z);
popMatrix();
}
}
}
void pointSphere (float r, float uAmount, float wAmount) {
for (float u= 0; u < 180; u += 180/uAmount) {
for (float w = 0; w < 360; w += 360/wAmount) {
//define PVector
PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u)));
//storing the location of Pvector into sphere1
sphere1.add(vS1);
sphereList.add(sphere1);
}
}
}
You have most of the "ingredients" in place (sphere points, a scene to render into, translate to offset each sphere, etc.), however there are two sections that are confusing:
1.ArrayList<ArrayList <PVector>> sphereList = new ArrayList<ArrayList<PVector>>(); this would store a list of lists of points. Do you need to render multiple spheres each with a different set of points (e.g. different float r, float uAmount, float wAmount values ?) If so, this makes sense. However if you simply want to render the same sphere in different locations, you can get away with 1 list of points (i.e. just sphere1) and render it in multiple locations.
The nested for loops in draw(): the first loop accesses and draws the sphere points. The second loop iterates for every sphere point (which is a lot). This second loop would iterate through each point and translate.
If simply rendering the same sphere 3 times in 3 locations, you can translate the group of points (i.e. before the for loop rendering each point).
Here's one way of writing it:
I recommend tweaking the pointSphere() points function so it returns the points (instead of using the hardcoded list to add points to). The advantage is you can calculate sphere points with various settings that can be stored into independent lists of points (as opposed to the single hardcoded list). (Additionally, you could easily reuse this function in other sketches as it requires copything the function indepdent of the hardcoded list of points)
e.g.
ArrayList<PVector> pointSpherePoints(float r, float uAmount, float wAmount) {
ArrayList<PVector> points = new ArrayList<PVector>();
for (float u= 0; u < 180; u += 180/uAmount) {
for (float w = 0; w < 360; w += 360/wAmount) {
//define PVector
PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u)));
//storing the location of Pvector
points.add(vS1);
}
}
return points;
}
you can write a function that renders a list of points which can be reused.
void drawSpherePoints(ArrayList<PVector> points){
for (int i = 0 ; i < points.size(); i++) {
PVector v = points.get(i);
stroke(255);
strokeWeight(random(2, 10));
point(v.x, v.y, v.z);
}
}
Putting the two together makes it simple to render the sphere in different places:
//import
import peasy.*;
//import variables
PeasyCam acam;
ArrayList<PVector> sphere1 = pointSpherePoints(270, 27, 27);
void setup() {
size(1920, 1080, P3D);
//camera setting
acam = new PeasyCam(this, 500, 500, 500, 2000);
acam.rotateX(0);
acam.rotateY(0);
acam.rotateZ(0);
}
void draw() {
background(0);
translate(width * 0.5, height * 0.5);
float gap = -1000;
for(int i = 0 ; i < 3; i++){
gap = gap + 500;
translate(1000 + gap, 1000 + gap, 1000 + gap);
drawSpherePoints(sphere1);
}
}
void drawSpherePoints(ArrayList<PVector> points){
for (int i = 0 ; i < points.size(); i++) {
PVector v = points.get(i);
stroke(255);
strokeWeight(random(2, 10));
point(v.x, v.y, v.z);
}
}
ArrayList<PVector> pointSpherePoints(float r, float uAmount, float wAmount) {
ArrayList<PVector> points = new ArrayList<PVector>();
for (float u= 0; u < 180; u += 180/uAmount) {
for (float w = 0; w < 360; w += 360/wAmount) {
//define PVector
PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u)));
//storing the location of Pvector
points.add(vS1);
}
}
return points;
}
The encapsulation makes it easier to draw spheres with independent parameters (radius, detail level):
//import
import peasy.*;
//import variables
PeasyCam acam;
int numSpheres = 3;
ArrayList<ArrayList<PVector>> spheres = new ArrayList<ArrayList<PVector>>();
void setup() {
size(1920, 1080, P3D);
//camera setting
acam = new PeasyCam(this, 500, 500, 500, 2000);
for(int i = 0 ; i < numSpheres ; i++){
int detailLevel = i + 1;
spheres.add(pointSpherePoints(30 * (detailLevel * 2), 9 * detailLevel, 9 * detailLevel));
}
}
void draw() {
background(0);
translate(width * 0.5, height * 0.5);
for(int i = 0 ; i < numSpheres ; i++){
ArrayList<PVector> sphere = spheres.get(i);
translate(100 * i, 0, 0);
drawSpherePoints(sphere);
}
}
void drawSpherePoints(ArrayList<PVector> points){
for (int i = 0 ; i < points.size(); i++) {
PVector v = points.get(i);
stroke(255);
strokeWeight(random(2, 10));
point(v.x, v.y, v.z);
}
}
ArrayList<PVector> pointSpherePoints(float r, float uAmount, float wAmount) {
ArrayList<PVector> points = new ArrayList<PVector>();
for (float u= 0; u < 180; u += 180/uAmount) {
for (float w = 0; w < 360; w += 360/wAmount) {
//define PVector
PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u)));
//storing the location of Pvector
points.add(vS1);
}
}
return points;
}
or even a sphere of spheres:
//import
import peasy.*;
//import variables
PeasyCam acam;
ArrayList<PVector> sphere1 = pointSpherePoints(270, 27, 27);
void setup() {
size(1920, 1080, P3D);
//camera setting
acam = new PeasyCam(this, 500, 500, 500, 2000);
}
void draw() {
background(0);
translate(width * 0.5, height * 0.5);
for(int i = 0 ; i < sphere1.size(); i += 10){
// scale vector point
PVector v = PVector.mult(sphere1.get(i), 10);
pushMatrix();
translate(v.x, v.y, v.z);
drawSpherePoints(sphere1);
popMatrix();
}
}
void drawSpherePoints(ArrayList<PVector> points){
for (int i = 0 ; i < points.size(); i++) {
PVector v = points.get(i);
stroke(255);
strokeWeight(random(2, 10));
point(v.x, v.y, v.z);
}
}
ArrayList<PVector> pointSpherePoints(float r, float uAmount, float wAmount) {
ArrayList<PVector> points = new ArrayList<PVector>();
for (float u= 0; u < 180; u += 180/uAmount) {
for (float w = 0; w < 360; w += 360/wAmount) {
//define PVector
PVector vS1 = new PVector(r*sin(radians(u))*cos(radians(w)), r*sin(radians(u))*sin(radians(w)), r*cos(radians(u)));
//storing the location of Pvector
points.add(vS1);
}
}
return points;
}
Related
Can anyone help me?
So, I'm supposed to have a ball that is moving horizontally, such that every time I press the mouse, a ball would get shoot vertically, then slows down due to friction. The vertical ball would stay in the old position but the player would reset.
How do I go about doing that without using classes?
Here my code so far:
boolean circleupdatetostop = true;
float x = 100;
float yshot = 880;
float speedshot = random(4,10);
float speedx = 6;
void setup() {
size(1280,960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(x,880,80);
if (x > width || x < 0 ) {
speedx = speedx * -1;
}
if (circleupdatetostop) {
x = x + speedx;
}
if (circleupdatetostop == false) {
float locationx = x;
stroke(0);
fill(255,0,255);
circle(locationx,yshot,30);
yshot = yshot - speedshot;
}
}
void mousePressed () {
circleupdatetostop = !circleupdatetostop;
}
I'm not entirely sure if this is what you meant, but you could achieve shooting multiple balls by using ArrayList as well as processing's PVector to better handle the x and y coordinate pairs. If you wanted to look at classes, see this post.
import java.util.*;
// Whether the ball is moving or not
boolean circleupdatetostop = true;
// Information about the main_ball
PVector position = new PVector(100, 880);
PVector speed = new PVector(6, 0);
float diameter = 80;
// Information about the sot balls
ArrayList<PVector> balls_loc = new ArrayList<PVector>();
ArrayList<PVector> balls_speed = new ArrayList<PVector>();
float diameter_shot = 30;
float friction = 0.994;
void setup() {
size(1280, 960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(position.x, position.y, diameter);
// Remember to consider the radius of the ball when bouncing off the edges
if (position.x + diameter/2 > width || position.x - diameter/2 < 0 ) {
speed.mult(-1);
}
if (circleupdatetostop) {
position.add(speed);
}
// Cycle through the list updating their speed and draw each ball
for (int i = 0; i<balls_loc.size(); i++) {
balls_speed.get(i).mult(friction+random(-0.05, 0.05));
balls_loc.get(i).add(balls_speed.get(i));
stroke(0);
fill(255, 0, 255);
circle(balls_loc.get(i).x, balls_loc.get(i).y, diameter_shot);
}
}
void mousePressed(){
// Add a new ball to be drawn
if(circleupdatetostop){
balls_loc.add(new PVector(position.x, position.y));
balls_speed.add(new PVector(0, random(-4, -10)));
}
circleupdatetostop = !circleupdatetostop;
}
I'm trying to create a program, wherein the ellipses revolve around the center screen and add a trailing pattern to it. I'm using ArrayList in processing to store the old vector then draw it, but it's not rendering. Or am I doing things wrong? The part where I wrote it is on the bottom part, thank you.
Particle[] part = new Particle[10];
int len = 10;
void setup(){
size(1000,1000,P2D);
//fullScreen();
for(int i = 0; i < len; i++){
part[i] = new Particle();
}
}
void draw(){
background(255);
for(int i = 0; i < len; i++){
part[i].show();
part[i].update();
part[i].trail();
}
}
class Particle{
float r,angle,d;
PVector pos = new PVector();
ArrayList<PVector> history = new ArrayList<PVector>();
Particle(){
angle = random(20,360);
r = random(20,300);
pos.x = width/2 + cos(angle) * r;
pos.y = height/2 + sin(angle) * r;
}
void show(){
stroke(0,0,255);
ellipse(pos.x,pos.y,5,5);
//line(x,y,width/2,height/2);
}
void update(){
pos.x = width/2 + cos(angle) * r;
pos.y = height/2 + sin(angle) * r;
angle += random(0.001,0.01);
}
void trail(){
history.add(pos);
if(history.size() > 50){
history.remove(0);
}
for(int i = 0; i < history.size(); i++){
PVector prev = history.get(i);
ellipse(prev.x,prev.y,5,5);
}
}
}
When you do
history.add(pos);
then you do not create a new PVector object. You just add a reference to the attribute pos to the array list history. When pos is changed, then still all elements of history refer to pos. There exist just one PVecor object for each Particle.
Create a copy of pos when you add it to history, to solve the issue:
history.add(pos.copy());
I need to create a loop which will space circles equally around a circle in Processing.
I know I can somehow implement a FOR loop.
I need to be able to increase or decrease the number of circles around this circle (with button presses) but keep them equally spaced.
I know the formula's I need to include in the FOR loop to get the X and Y axis. The formulas:
being
X = R*cos(angle-90)+Y0
Y = R*sin(angle-90)+X0
I understand the three parameters of the FOR loop; when does it start, when does it finish, what changes when it runs.
What I can't see is how to implement the formulas into the FOR loop.
Many thanks
Here is the code I do have
void setup () {
size (600, 600);
background (255, 255, 255);
smooth ();
ellipse (width/2, height/2, 200, 200); // the guide circle. Not needed in final code.
}
void draw() {
for (int i = 0; i < 20; i ++) {
for (int j = 0; j < 20; j ++) {
ellipse (i *20, j * 20, 20, 20);
}
}
}
This code should do the trick:
float incrementalAngle = 0.0;
void setup(){
size(600, 600);
smooth();
background(0);
ellipse(width/2, height/2, 200, 200);
drawCircles(20, 200);
}
void draw(){
}
void drawCircles(int circlesNumber, int bigCircleNumber){
float angle = incrementalAngle;
for(int i = 0; i < circlesNumber; i++){
ellipse(bigCircleNumber * cos(incrementalAngle) + height/2,
bigCircleNumber * sin(incrementalAngle) + width/2,
circlesNumber, circlesNumber);
incrementalAngle += TWO_PI / circlesNumber;
}
}
So the second loop wasn't needed, and the formula you were trying to introduce would go in the X and Y position of your ellipse, there by playing whit the angle and the cos and sin you can get the result you were looking for.
What's left now is for you to get the number of circles you want by the clicking inside a mousePressed() method and drawing that amount.
Hope this comes useful and call me if you need more help
Regards
Jose.
Thank you to everyone who helped.
I managed to do it (slightly differently to you #Jose Gonzalez
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'm new to Processing and want to make the following sketch move images down, rather than up. I have tried adjusting the y to y+= speed in void move(), which does this but the images don't reload, they just do one cycle and the screen goes blank.
Your help would be appreciated :-)
Spot[] sp = new Spot[60];
PImage myImage;
/* #pjs preload="http://mathatelle.appspot.com/imgs/drawing_circle.png"; */
void setup() {
size(800, 400);
imageMode(CENTER);
myImage = loadImage("http://mathatelle.appspot.com/imgs/drawing_circle.png"); //100x100px
for (int i = 0; i < sp.length; i++) {
sp[i] = new Spot(random(width), random(height), random(0.2,1.0), random(0.1,1.0));
}
}
void draw() {
background(0);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
class Spot {
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
void move() {
speed *= 1.01;
y -= speed;
if (y < - myImage.width*diameter/2) {
x = random(width);
y = height + myImage.width*diameter/2;
speed = random(0.5,3);
}
}
void display() {
pushMatrix();
translate(x, y);
rotate(TWO_PI*diameter);
scale(diameter);
//tint(255, 255, 255, 153);
image(myImage, 0, 0);
popMatrix();
}
}
The logical is kind of inverted already,but just invert it again :)
here there are comments in the code:
Spot[] sp = new Spot[60];
PImage myImage;
/* #pjs preload="http://mathatelle.appspot.com/imgs/drawing_circle.png"; */
void setup() {
size(800, 400);
imageMode(CENTER);
myImage = loadImage("http://mathatelle.appspot.com/imgs/drawing_circle.png"); //100x100px
for (int i = 0; i < sp.length; i++) {
// a little change where spots are created...
sp[i] = new Spot(random(width), random(-myImage.height, height - 100), random(0.2, 1.0), random(0.1, 1.0));
}
}
void draw() {
background(0);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
class Spot {
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
void move() {
speed *= 1.01;
// invert movement direction
y += speed;
// also invert the test...
if (y > height + myImage.width*diameter/2) {
x = random(width);
y = height + myImage.width*diameter/2;
speed = random(0.5, 3);
}
}
void display() {
pushMatrix();
translate(x, y);
rotate(TWO_PI*diameter);
scale(diameter);
//tint(255, 255, 255, 153);
image(myImage, 0, 0);
popMatrix();
}
}
A friend helped me out, this is the solution to my problem :-)
Spot[] sp = new Spot[60];
PImage myImage;
/* #pjs preload="http://mathatelle.appspot.com/imgs/drawing_circle.png"; */
void setup() {
size(800, 400);
imageMode(CENTER);
myImage = loadImage("http://mathatelle.appspot.com/imgs/drawing_circle.png"); //100x100px
for (int i = 0; i < sp.length; i++) {
// a little change where spots are created...
sp[i] = new Spot(random(width), random(-myImage.height, height - 100), random(0.2, 1.0), random(0.1, 1.0));
}
}
void draw() {
background(0);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
class Spot {
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
void move() {
speed *= 1.01;
y += speed;
// change y = 0 - ...
if (y > height + myImage.width*diameter/2) {
x = random(width);
y = 0 - myImage.width*diameter/2;
speed = random(0.5, 3);
}
}
void display() {
pushMatrix();
translate(x, y);
rotate(TWO_PI*diameter);
scale(diameter);
//tint(255, 255, 255, 153);
image(myImage, 0, 0);
popMatrix();
}
}
I am trying to create a visualization where the nodes of my network change size in a loop as the visualization progresses (I have stripped out the interactions between the nodes for simplicity here). I have the array sizes that is looped over in the draw function with index j. I am not sure why the nodes are not changing size. Any insight into this problem would be appreciated.
int numBalls = 5;
Ball[] balls = new Ball[numBalls];
float[] sizes = {15,25,35,45,55,65};
void setup() {
size(800, 400);
int l = 0 ;
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width),random(height), random(30, 50), i, balls);
}
noStroke();
fill(255, 204);
}
void draw() {
background(0);
for (int j = 0; j < 6; j++){
for (int i = 0; i < numBalls; i++) {
print("\nNEW ID\n");
print(i);
print("\n");
print("Diameter in balls\n");
print(balls[i].diameter);
print("\n");
balls[i].diameter = sizes[j];
print("Diameter in balls after fix\n");
print(balls[i].diameter);
balls[i].display();
}
}
}
class Ball {
float x, y;
float diameter;
float mass;
float vx = 0;
float vy = 0;
int id;
Ball[] others;
Ball(float xin, float yin, float din, int idin, Ball[] oin) {
x = xin;
y = yin;
diameter = din;
mass = 50;
id = idin;
others = oin;
}
void display() {
textSize(32);
fill(0,255,0,255);
print("\nDiameter in display\n");
print(diameter);
print("\n");
ellipse(x, y, diameter, diameter);
print("\nDiameter in display\n");
print(diameter);
print("\n");
fill(255, 0, 0, 255);
text(id,x,y);
}
}
The thing is, in your draw() function you are running over the array of sizes with the first for-loop and assigning the value of that size to the balls. This way in each draw() you subsequently attach each size on each ball, and every time the size you attach overwrites the previous one... Remember, the window of Processing only refreshes after the draw() has finished! Instead of looping over all the sizes in each draw() you probably want a different size in each draw(). So a way to do that would be:
int numBalls = 5;
int sizeCounter = 0;
int everySoManyFramesChange = 3;
Ball[] balls = new Ball[numBalls];
float[] sizes = {
15, 25, 35, 45, 55, 65
};
void setup() {
size(800, 400);
int l = 0 ;
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width), random(height), random(30, 50), i, balls);
}
noStroke();
fill(255, 204);
}
void draw() {
background(0);
for (int i = 0; i < numBalls; i++) {
balls[i].diameter = sizes[sizeCounter];
balls[i].display();
}
if (frameCount%everySoManyFramesChange == 0) sizeCounter=(sizeCounter+1)%sizes.length;
}
class Ball {
float x, y;
float diameter;
float mass;
float vx = 0;
float vy = 0;
int id;
Ball[] others;
Ball(float xin, float yin, float din, int idin, Ball[] oin) {
x = xin;
y = yin;
diameter = din;
mass = 50;
id = idin;
others = oin;
}
void display() {
textSize(32);
fill(0, 255, 0, 255);
ellipse(x, y, diameter, diameter);
fill(255, 0, 0, 255);
text(id, x, y);
}
}
By the way I removed all those print statements because they are making the sketch horribly slow, but be my guest and re-introduce them!