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() {
}
Related
I'm new to processing, and trying to do this task. Maybe you know how to do it, or know where I could read about it.
I need something like this:
Thanks in advance for your help.
The image is a 4x3 grid with zero spacing between the columns(vg) and rows(hg):
final int _numRows = 3;
final int _numCols = 4;
void rectGrid(int l, int t, int w, int h, int hg, int vg) {
int left;
int top;
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(0);
strokeWeight(2);
fill(255);
rect( left, top, w, h);
}
}
}
void setup() {
size(640, 340);
background(209);
rectGrid(20, 20, 150, 100, 0, 0);
}
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!
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();
}
My triangle rasterization program works as-is, but I would like to make it easier to use by specifying explicit coordinates instead of differentials. Unfortunately, I don't know how to calculate the necessary change-of-basis matrix. This can be seen by the empty "rasterizeCnvTri" function.
The following section is my code, using the PixelToaster library for a framebuffer:
// TrueColor Example
// How to open a display in truecolor mode and work with 32 bit integer pixels.
// Copyright © Glenn Fiedler, 2004-2005. http://www.pixeltoaster.com
#include "pt/source/PixelToaster.h"
using namespace PixelToaster;
int fbuf[256][256][3];
int zbuf[256][256];
void rasterizeTriangle(int u,int dudx,int dudy,int v,int dvdx,int dvdy,int w,int dwdx,int dwdy,int r,int g,int b)
{
int u_rw = u;
int v_rw = v;
int w_rw = w;
for(int j=0; j<256; j++)
{
int u_pt = u_rw;
int v_pt = v_rw;
int w_pt = w_rw;
for(int i=0; i<256; i++)
{
if(w_pt>=zbuf[i][j] && u_pt>=0 && v_pt>=0 && (u_pt+v_pt)<4096)
{fbuf[i][j][0]=r; fbuf[i][j][1]=g; fbuf[i][j][2]=b; zbuf[i][j]=w_pt;}
u_pt += dudx;
v_pt += dvdx;
w_pt += dwdx;
}
u_rw += dudy;
v_rw += dvdy;
w_rw += dwdy;
}
}
void rasterizeCnvTri(int x1,int x2,int x3,int y1,int y2,int y3,int w1,int w2,int w3,int r,int g,int b)
{
//how to do this?
}
int main()
{
const int width = 256;
const int height = 256;
Display display( "Triangle Rasterizer", width, height, Output::Default, Mode::TrueColor );
vector<TrueColorPixel> pixels( width * height );
rasterizeTriangle(-2048,32,0,-2048,0,32,2048,0,0,255,0,0);
rasterizeTriangle(0,32,-32,-2048,0,32,4096,-16,0,255,255,255);
while ( display.open() )
{
unsigned int index = 0;
for ( int y = 0; y < height; ++y )
{
for ( int x = 0; x < width; ++x )
{
pixels[index].r = fbuf[x][y][0];
pixels[index].g = fbuf[x][y][1];
pixels[index].b = fbuf[x][y][2];
++index;
}
}
display.update( pixels );
}
}
U and V are the axes along two of the sides, and W is the inverse depth. All three coordinates are scaled by 4096, so integers are sufficient.
[EDIT]
The following code works for me (also does basic perspective divide):
void rasterizeCnvTri(int x1,int x2,int x3,int y1,int y2,int y3,int w1,int w2,int w3,int r,int g,int b)
{
int xp1 = (((x1-128)*w1)>>8)+128;
int yp1 = (((y1-128)*w1)>>8)+128;
int xp2 = (((x2-128)*w2)>>8)+128;
int yp2 = (((y2-128)*w2)>>8)+128;
int xp3 = (((x3-128)*w3)>>8)+128;
int yp3 = (((y3-128)*w3)>>8)+128;
int xd2 = xp2-xp1;
int xd3 = xp3-xp1;
int yd2 = yp2-yp1;
int yd3 = yp3-yp1;
int wd2 = w2-w1;
int wd3 = w3-w1;
int plna = (yd2*wd3)-(yd3*wd2);
int plnb = (wd2*xd3)-(wd3*xd2);
int plnc = (xd2*yd3)-(xd3*yd2);
int plnd = -(plna*xp1)-(plnb*yp1)-(plnc*w1);
int invdet = (xd2*yd3)-(yd2*xd3);
int dudx = (-yd3<<12)/invdet;
int dudy = (yd2<<12)/invdet;
int u = (-xp1*dudx)-(yp1*dudy);
int dvdx = (xd3<<12)/invdet;
int dvdy = (-xd2<<12)/invdet;
int v = (-xp1*dvdx)-(yp1*dvdy);
rasterizeTriangle(-u,-dudx,-dudy,-v,-dvdx,-dvdy,-plnd/plnc,-plna/plnc,-plnb/plnc,r,g,b);
}
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