I'm new to Processing. Why don't I see the first matrix drawn? I seem to only see the matrix after the delay, and not the one before. My ultimate goal is to watch how a matrix changes over time steps.
// Number of columns and rows in the grid
int[][] myArray = { {0, 1, 2, 3},
{3, 2, 1, 0},
{3, 5, 6, 1},
{3, 8, 3, 4} };
void setup() {
size(200,200);
}
void draw() {
background(204);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
rect(20+30*j,30+30*i,3,3);
}
}
delay(2500);
background(204);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
rect(40+30*j,50+30*i,7,7);
}
}
}
Your myArray variable is misleading, it doesn't seem to be used anywhere.
Basically you want to animate/interpolate between values.
Your code does this in the draw loop:
clear the background
draw 16 squares
wait 2500 ms
clear the background
draw 16 squares
which you'll tiny squares and after 2500 ms larger squares and that's it.
What want to do can be achieved in many ways, from the simpler to the more complex. Luckily Processing offers a lot of handy functions.
You want to store a property (like x position of a box) in a variable which you'll update over time and use the updated value to redraw on screen:
int x = 20;
int y = 30;
int w = 3;
int h = 3;
void setup() {
size(200,200);
}
void draw() {
//update
if(x <= 40) x++;
if(y <= 50) y++;
if(w <= 7) w++;
if(h <= 7) h++;
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(x+30*j,y+30*i,w,h);
}
}
}
You could also map() your values to a variable changing over time:
int x,y,s;
int xmin = 20,xmax = 40;
int ymin = 30,ymax = 50;
int smin = 3,smax = 7;
void setup() {
size(200,200);
}
void draw() {
//update
x = (int)map(mouseX,0,width,xmin,xmax);
y = (int)map(mouseX,0,width,ymin,ymax);
s = (int)map(mouseX,0,width,smin,smax);
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(x+30*j,y+30*i,s,s);
}
}
}
Or use linear interpolation (already implemented as lerp()):
int xmin = 20,xmax = 40;
int ymin = 30,ymax = 50;
int smin = 3,smax = 7;
void setup() {
size(200,200);
}
void draw() {
//update
float t = (float)mouseX/width;
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(lerp(xmin,xmax,t)+30*j,
lerp(ymin,ymax,t)+30*i,
lerp(smin,smax,t) ,
lerp(smin,smax,t) );
}
}
}
and you could alter your interpolation amount based on any variable you like:
int xmin = 20,xmax = 40;
int ymin = 30,ymax = 50;
int smin = 3,smax = 7;
void setup() {
size(200,200);
}
void draw() {
//update
float t = abs(sin(frameCount * .01));
//draw
background(204);
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
rect(lerp(xmin,xmax,t)+30*j,
lerp(ymin,ymax,t)+30*i,
lerp(smin,smax,t) ,
lerp(smin,smax,t) );
}
}
}
HTH
Related
I am taking a coding class, and I am struggling to do the following:
Rewrite the following code into an object-oriented fashion with a Snake class, and use an array to make a second snake appear.
This is what I have so far.
THIS IS NOT HOMEWORK, DO NOT WORRY. THIS IS A CLASS I AM TAKING ONLINE
int[] xpos = new int[50];
int[] ypos = new int[50];
void setup() {
size(800,600);
// Initialize
for (int i = 0; i < xpos.length; i++){
xpos[i] = 0;
ypos[i] = 0;
}
}
void draw() {
background(255);
// Shift Array Values
for (int i = 0; i < xpos.length - 1; i++){
xpos[i] = xpos[i + 1];
ypos[i] = ypos[i + 1];
}
// New location
xpos[xpos.length - 1] = mouseX;
ypos[ypos.length - 1] = mouseY;
// Draw Everything
for (int i = 0; i < xpos.length - 1; i++){
noStroke();
fill(255 - i*5);
ellipse(xpos[i], ypos[i], i, i);
}
}
So I don't know how much you already know about objects is Processing, so I hope you will understand this.
A object is just an instance of a class.
A class can include variables and functions.
When you create an object from a class you can set the variables of the object, so that two different objects can have two different values for the same variable.
When you run a function of an object it will perform the function only on the variables from that object (not from the others).
So to create a class you just wrap the code in class [class name here] { [your code here] }.
You can cut out stuf that you don't want to be executed multible times like background(255); and paste it back into draw function.
Now you have to rename the functions: for the setup function you can use a constructer which is just a function without a return type (like void) and with the same name as the class. This will automatically run when you create the object later. The draw function you can just name how you want (I named it update).
So at that point you should have this:
class Snake{
private int[] xpos = new int[50];
private int[] ypos = new int[50];
Snake(){
for (int i = 0; i < xpos.length; i++){
xpos[i] = 0;
ypos[i] = 0;
}
}
void update(){
// Shift Array Values
for (int i = 0; i < xpos.length - 1; i++){
xpos[i] = xpos[i + 1];
ypos[i] = ypos[i + 1];
}
// New location
xpos[xpos.length - 1] = mouseX;
ypos[ypos.length - 1] = mouseY;
// Draw Everything
for (int i = 0; i < xpos.length - 1; i++){
noStroke();
fill(255 - i*5);
ellipse(xpos[i], ypos[i], i, i);
}
}
}
so now you can create an array of snakes and run the update function (or what ever you named it) on all of them (of cause I would do that with a loop, but I think this way it's more obvious)
Snake[] snakes = {new Snake(), new Snake()};
void setup() {
size(800,600);
// Initialize
}
void draw() {
background(255);
snakes[0].update();
snakes[1].update();
}
Now you have two snakes, but you can't see both of them because they are on top of each other. That's why I added a variable offset, that will offset the two snakes and r, g, b variables for the color of the snake.
of cause you have to pass the variables to the object when you create it and recieve it in the constructor.
So when you're done you should have something like that:
Snake[] snakes = {new Snake(0,0,255, 0), new Snake(255,0,0, 50)};
void setup() {
size(800,600);
// Initialize
}
void draw() {
background(255);
snakes[0].update();
snakes[1].update();
}
class Snake{
private int[] xpos = new int[50];
private int[] ypos = new int[50];
private int r;
private int g;
private int b;
private int offset;
Snake(int r, int g, int b, int offset){
this.r = r;
this.g = g;
this.b = b;
this.offset = offset;
for (int i = 0; i < xpos.length; i++){
xpos[i] = 0;
ypos[i] = 0;
}
}
void update(){
// Shift Array Values
for (int i = 0; i < xpos.length - 1; i++){
xpos[i] = xpos[i + 1];
ypos[i] = ypos[i + 1];
}
// New location
xpos[xpos.length - 1] = mouseX +offset;
ypos[ypos.length - 1] = mouseY +offset;
// Draw Everything
for (int i = 0; i < xpos.length - 1; i++){
noStroke();
fill(r - i*5, g - i*5, b - i*5);
ellipse(xpos[i], ypos[i], i, i);
}
}
}
So finally it should look like this:
two snakes in red and blue
I hope I could help you with this!
How do I write the code (below) in an alternative (beginner) way? I don't wish to use createShape, setFill and addChild. Instead, any other way to perform the same thing?
grid = createShape(GROUP)
for i in range(C*R):
self.cell = createShape(RECT, (i%C)*S, (i//C)*S, S, S)
self.cell.setFill(colors[i] if i in filled else 210)
grid.addChild(self.cell)
Assuming that you're try to create a rectangle grid:
final int _numRows = 5;
final int _numCols = 7;
int l = 20;
int t = 20;
int w = 90;
int h = 60;
int hg = 10;
int vg = 10;
int left;
int top;
void rectGrid() {
for(int k = 0; k < _numRows; k++) {
for(int j = 0; j < _numCols; j++){
left = l + j*(w+vg);
top = t + k*(h+hg);
stroke(255);
strokeWeight(2);
fill(118);
rect( left, top, w, h);
}
}
}
void setup() {
size(800,500);
background(0,0,245);
rectGrid();
}
void draw() {
}
Adds a color array:
/*
Adds color array to rectangle grid.
*/
final int _numRows = 5;
final int _numCols = 7;
int l = 20;
int t = 20;
int w = 90;
int h = 60;
int hg = 10;
int vg = 10;
int left;
int top;
int count = 0;
color[] c;
void colorArray(){
for(int x=0; x< _numRows*_numCols; x++){
c[x] = color(random(255),random(255),random(255))
}
}
void rectGrid() {
for(int k = 0; k < _numRows; k++) {
for(int j = 0; j < _numCols; j++){
left = l + j*(w+vg);
top = t + k*(h+hg);
stroke(255);
strokeWeight(2);
fill(c[count]);
rect( left, top, w, h);
count++;
}
}
}
void setup() {
size(800,500);
background(0,0,245);
c = new color[_numCols*_numRows];
colorArray();
// Make sure the color array is filled first
rectGrid();
}
void draw() {
}
I want to make a Voronoi tiling which fits itself to some text in Processing 3.5.3. I've got the algorithm for standard Voronoi tiling implemented, but I initialise all points to just be randomly distributed across the window.
I've got a list of points which make up some letters, generated by the geomerative package. They're all in the standard (x, y) format.
I'm looking for a function which would take the text points and the window size into account and give me back a sort of distribution, or, better yet, a list of points already following that distribution.
My code:
import geomerative.*;
public class Point {
public RPoint p = new RPoint(0, 0);;
public color c;
public boolean isTextPt;
public Point(int _w, int _h, float[][] distribution) {
this.p.x = random(_w);
this.p.y = random(_h);
//this.c = color(random(100, 250), random(100, 250), random(100, 250));
this.c = color(map(p.x, 0, _w, 50, 160), map(p.y, 0, _h, 0, 150), 255);
this.isTextPt = false;
}
public Point(float _x, float _y) {
this.p.x = _x;
this.p.y = _y;
this.c = color(random(50, 160), random(100, 250), 255);
this.isTextPt = true;
}
}
int baseAmountOfCells = 50;
RShape shape;
RPoint[] textPts;
Point[] points;
void setup() {
RG.init(this);
shape = new RFont("RobotoMono-Medium.ttf", 140, RFont.CENTER).toShape("voronoi songs for worley days");
textPts = shape.getPoints();
fullScreen();
colorMode(HSB);
points = new Point[baseAmountOfCells + textPts.length];
for (int i = 0; i < baseAmountOfCells; i ++) {
points[i] = new Point(width, height);
}
for (int i = 0; i < textPts.length; i ++) {
points[baseAmountOfCells + i] = new Point(textPts[i].x / 2 + width / 2, textPts[i].y / 2 + height / 2);
}
println("Amount of text points: " + str(textPts.length));
}
void draw() {
loadPixels();
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float record = width * height; //it can never be more than this
int recIndex = 0;
for (int i = 0; i < points.length; i++) {
float d = dist(x, y, points[i].p.x, points[i].p.y);
if (d < record) {
record = d;
recIndex = i;
}
}
Point pt = points[recIndex];
pixels[index] = color(pt.c);
index++;
}
}
updatePixels();
for (Point pt : points) {
if (pt.isTextPt) {
stroke(0);
strokeWeight(2);
point(pt.p.x, pt.p.y);
}
}
noLoop();
}
Use a two-dimensional array to represent a nxn grid.
var grid = new int[n,n];
Note that there are two more diagonal lines.
If i will solve this problem. I will make so.
Create extension method for Int[] (So, you can create your own class. But it's another way. I want to show light waight solution)
public static class IntAsMatrixExtensions {
public const int MatrixColumsCount = 3;
public static int At(this int[] matrix, int i, int j)
{
return matrix[i * MatrixColumsCount + j];
}
public static int[] Create()
{
var grid = new int[MatrixColumsCount*MatrixColumsCount] {
1,2,3,
4,5,6,
7,8,9
};
return grid;
}
}
Then first you should print matrix:
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
for(int j = 0; j < IntAsMatrixExtensions.MatrixColumsCount; j++)
{
Console.Write(grid.At(i, j));
}
Console.WriteLine();
}
Then print transponated matrix:
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
for(int j = 0; j < IntAsMatrixExtensions.MatrixColumsCount; j++)
{
Console.Write(grid.At(j, i)); //!!! i and j is swithed
}
Console.WriteLine();
}
Then print diag:
//Print diag
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
Console.Write(grid.At(i, i)); //!!! i and j is swithed
}
Then print inverse diag:
for(int i = 0; i < IntAsMatrixExtensions.MatrixColumsCount; i++)
{
Console.Write(grid.At(i, IntAsMatrixExtensions.MatrixColumsCount - i - 1)); //!!! i and j is swithed
}
Here is example on fiddle https://dotnetfiddle.net/pyX31r
I'm new to coding (as I'm sure you might be able to tell). The program runs and generates 1 Tubble, but the additional objects don't show.
Here's my class:
class Tubble {
float x;
float y;
float diameter;
float yspeed;
float tempD = random(2,86);
Tubble() {
x = random(width);
y = height-60;
diameter = tempD;
yspeed = random(0.1, 3);
}
void ascend() {
y -= yspeed;
x = x + random(-2, 2);
}
void dis() {
stroke(0);
fill(127, 100);
ellipse(x, y, diameter, diameter);
}
void top() {
if (y < -diameter/2) {
y = height+diameter/2;
}
}
}
Class
class Particle {
float x, y;
float r;
float speed = 2.2;
int direction = 1;
PImage pbubbles;
Particle(float x_, float y_, float r_) {
x = x_;
y = y_;
r = r_;
}
void display() {
stroke(#F5D7D7);
strokeWeight(2.2);
noFill();
ellipse(x, y, r*2, r*2);
}
boolean overlaps(Particle other) {
float d = dist(x, y, other.x, other.y);
if (d < r + other.r) {
return true;
} else {
return false;
}
}
void move() { //testing
x += (speed * direction);
if ((x > (width - r)) || (x < r)) {
direction *= -1;
}
}
void updown() {
y += (speed * direction);
if ((y > (height - r)) || (y < r)) {
direction *= -1;
}
}
}
Main sketch:
Tubble[] tubbles = new Tubble [126];
PImage bubbles;
Particle p1;
Particle p2;
Particle p3;
Particle p4;
Particle p5;
float x,y;
float speed;
int total = 0;
int i;
//int direction = 1;
void setup() {
size(800, 925);
bubbles = loadImage("purple_bubbles.png");
p1 = new Particle (100, 100, 50);
p2 = new Particle (500, 200, 100);
p3 = new Particle (600, 600, 82);
p4 = new Particle (height/2, width/2, 200);
p5 = new Particle ((height/3), (width/3), 20);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i] = new Tubble();
}
}
void mousePressed() {
total = total + 1;
}
void keyPressed() {
total = total - 1;
}
void draw() {
image(bubbles, 0, 0, 800, 925);
//background(0);
for (int i = 0; i < tubbles.length; i++); {
tubbles[i].ascend();
tubbles[i].dis();
tubbles[i].top();
}
if ((p2.overlaps(p1)) && (p2.overlaps(p4))) {
background(#BF55AB, 25);
}
if ((p3.overlaps(p2)) && (p3.overlaps(p4))) {
background(#506381, 80);
}
p2.x = mouseX;
p3.y = mouseY;
p1.display();
p2.display();
p3.display();
p4.display();
p5.display();
p4.move();
p5.updown();
// for (int i = 0; i < tubbles.length; i++); {
// tubbles[i].dis();
// tubbles[i].ascend();
// tubbles[i].top();
// }
}
There are extra semicolons in the lines
for (int i = 0; i < tubbles.length; i++); {
for (int i = 0; i < tubbles.length; i++); {
// for (int i = 0; i < tubbles.length; i++); {
It make the for loop do virtually nothing.
Then the block after the for loop will read the global variable i and do the action only once.
Remove the semicolons like this to put the block in the loop.
for (int i = 0; i < tubbles.length; i++) {
for (int i = 0; i < tubbles.length; i++) {
// for (int i = 0; i < tubbles.length; i++) {