Processing using angles - for-loop

Hi: I'm trying to use angles in my code but am very unclear on how to use them as variables. I want to make this tree root-looking sketch and need this last piece to complete it.
The error occurs in this for loop in the draw function. I'd like the angle to change on each frame, as well as the color to provide dimension. Here is the for loop:
for (int x=0; x<width; x++) {
angle=0;
pins (int p=>angle+=atan2(p.y-y, p.x-x));
color=map(sin(angle), -1, 1, 0, 256);
stroke(color);
line(int x, int y, int x, int y+color);
}
This is my full code below.
float[] pins= new float[0];
float pins_num= 150;
float y, x;
void setup (){
size(1920, 1080);
float y=0;
for (int i=0; i<pins_num; i++ ) {
pins[i]=createVector(random(width), random(height));
}
}
void draw (){
if (y<height) {
for (int x=0; x<width; x++) {
angle=0;
pins (int p=>angle+=atan2(p.y-y, p.x-x));
color=map(sin(angle), -1, 1, 0, 256);
stroke(color);
line(int x, int y, int x, int y+color);
}
y++
}
}

It seems you've mixing p5.js (createVector , int p=>angle...) syntax and Processing syntax. If you're porting a p5.js sketch to Processing you should include the original p5.js code in your question as well.
A few things that stand out:
float[] pins= new float[0]; looks like a static array storing a single float value, however pins[i]=createVector(random(width), random(height)); implies it should be a PVector array, for example: PVector[] pins= new PVector[pins_num];
float pins_num= 150; is declared/initialsed after pins: I suspect the intention was to use this as size of the pins array and it should be added before the pins array.
y,x are declared at the top as floats, however, incremented as a integers in draw(x++, y++).
pins (int p=>angle+=atan2(p.y-y, p.x-x)); looks really confusing. Maybe the intension is to access each pin (maybe it was pins.forEach in js) and increment angle with the the rotation between each random PVector allocated in setup() and current x,y location (top to bottom) ? Something like: for(PVector p : pins) angle += atan2(p.y-y, p.x-x); in Processing (Java)
color=map(sin(angle), -1, 1, 0, 256); this looks like p5.js, in Processing you need to use both a variable type and the name (not just the type) (and minor details, the range for colors is 0 to 255, not 0 to 256 (as that adds up to 256 values in to total, starting the count at 0, not at 1). In Processing this could look like: color mappedColor = color(map(sin(angle), -1.0, 1.0, 0, 255));
line(int x, int y, int x, int y+color); looks like you tried to add variable types (as you do in Processing vs p5.js), however, you only need to specify the types when you declare a function, not when you call it. This should be line(x, y, x, y + color);
It's a bit of a wild guess, but inferring only from existing code, a fully ported Processing version of your code might look like this:
int numPins = 150;
PVector[] pins= new PVector[numPins];
int x, y;
void setup () {
size(1920, 1080);
for (int i = 0; i < numPins; i++ ) {
pins[i] = new PVector(random(width), random(height));
}
}
void draw () {
float angle = 0;
if (y < height) {
for (int x = 0; x < width; x++) {
for(PVector p : pins) angle += atan2(p.y-y, p.x-x);
color mappedColor = color(map(sin(angle), -1.0, 1.0, 0, 255));
stroke(mappedColor);
line(x, y, x, y + mappedColor);
}
y++;
}
}

Related

Processing Square Stacking loop

This is my first time writing here so i'll be direct, i've been trying to recreate this image:
and so far all the code i've got is:
void setup() {
size(500, 500);
}
void draw() {
rectMode(CENTER);
recta();
}
void recta() {
noFill();
int a = 10;
int y = 250;
for (int x = 0; x<20; x++) {
pushMatrix();
translate(y, y);
rect(0, 0, a, a);
popMatrix();
rotate(radians(2.0*PI));
stroke(0, 0, 0);
a= a - 20;
}
}
And i have no idea what to do next since this is what i get from it:
So i'd like to ask for help on how to get the same result as the image.
You are so close !
You're absolutely on the right track using pushMatrix()/popMatrix() to isolate coordinate systems, however you might have accidentally placed the rotation after popMatrix() which defeats the purpose. You probably meant to for each square to have an independent rotation from each other and not accumulate 2 * PI to the global rotation.
The other catch is that you're rotating by the same angle (2 * PI) for each iteration in your for loop and that rotation is 360 degrees so even if you fix rotation like this:
pushMatrix();
translate(y, y);
rotate(radians(2.0*PI));
rect(0, 0, a, a);
popMatrix();
you'll get a scaling effect:
(Minor note 2.0 * PI already exists in Processing as the TWO_PI constant)
To get that spiral looking effect is to increment the angle for each iteration (e.g. x = 0, rotation = 0, x = 1, rotation = 5, x = 2, rotation = 10, etc.). The angle increment is totally up to you: depending on how you map the x increment to a rotation angle angle you'll get a tighter or looser spiral.
Speaking of mapping, Processing has a map() function which makes it super easy to map from one range of numbers (let's say x from 0 to 19) to another (let's say 0 radians to PI radians):
for (int x = 0; x < 20; x++) {
pushMatrix();
translate(y, y);
rotate(map(x, 0, 19, 0, PI));
rect(0, 0, a, a);
popMatrix();
a = a - 20;
}
Here's a basic sketch based on your code:
int a = 10;
int y = 250;
void setup() {
size(500, 500);
rectMode(CENTER);
noFill();
background(255);
recta();
}
void recta() {
for (int x = 0; x < 20; x++) {
pushMatrix();
translate(y, y);
rotate(map(x, 0, 19, 0, PI));
rect(0, 0, a, a);
popMatrix();
a = a - 20;
}
}
I've removed draw() because it was rendering the same frame without any change: drawing once in setup() achieves the same visual effect using less CPU/power.
You can use draw(), but might as add some interactivity or animation to explore shapes. Here's a tweaked version of the above with comments:
int y = 250;
void setup() {
size(500, 500);
rectMode(CENTER);
noFill();
}
void draw(){
background(255);
recta();
}
void recta() {
// map mouse X position to -180 to 180 degrees (as radians)
float maxAngle = map(mouseX, 0, width, -PI, PI);
// reset square size
int a = 10;
// for each square
for (int x = 0; x < 20; x++) {
// isolate coordinate space
pushMatrix();
// translate first
translate(y, y);
// then rotate: order matters
// map x value to mouse mapped maximum rotation angle
rotate(map(x, 0, 19, 0, maxAngle));
// render the square
rect(0, 0, a, a);
popMatrix();
// decrease square size
a = a - 20;
}
}
Remember transformation order matters (e.g. translate() then rotate() would produce different effects compared to rotate() then translate()). Have fun!

Sierpinski carpet in processing

So I made the Sierpinski carpet fractal in processing using a Square data type which draw a square and has a function generate() that generates 9 equal squares out of itself and returns an ArrayList of (9-1)=8 squares removing the middle one (it is not added to the returned ArrayList) in order to generate the Sierpinski carpet.
Here is the class Square -
class Square {
PVector pos;
float r;
Square(float x, float y, float r) {
pos = new PVector(x, y);
this.r = r;
}
void display() {
noStroke();
fill(120,80,220);
rect(pos.x, pos.y, r, r);
}
ArrayList<Square> generate() {
ArrayList<Square> rects = new ArrayList<Square>();
float newR = r/3;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
if (!(i==1 && j==1)) {
Square sq = new Square(pos.x+i*newR, pos.y+j*newR, newR);
rects.add(sq);
}
}
}
return rects;
}
}
This is the main sketch which moves forward the generation on mouse click -
ArrayList<Square> current;
void setup() {
size(600, 600);
current = new ArrayList<Square>();
current.add(new Square(0, 0, width));
}
void draw() {
background(255);
for (Square sq : current) {
sq.display();
}
}
void mousePressed() {
ArrayList<Square> next = new ArrayList<Square>();
for(Square sq: current) {
ArrayList<Square> rects = sq.generate();
next.addAll(rects);
}
current = next;
}
The problem :
The output that I am getting has very thin white lines which are not supposed to be there :
First generation -
Second generation -
Third generation -
My guess is that these lines are just the white background that shows up due to the calculations in generate() being off by a pixel or two. However I am not sure about how to get rid of these. Any help would be appreciated!
Here's a smaller example that demonstrates your problem:
size(1000, 100);
noStroke();
background(0);
float squareWidth = 9.9;
for(float squareX = 0; squareX < width; squareX += squareWidth){
rect(squareX, 0, squareWidth, height);
}
Notice that the black background is showing through the squares. Please try to post this kind of minimal example instead of your whole sketch in the future.
Anyway, there are three ways to fix this:
Option 1: Call the noSmooth() function.
By default, Processing uses anti-aliasing to make your drawings look smoother. Usually this is a good thing, but it can also add some fuzziness to the edges of shapes. If you disable anti-aliasing, your shapes will be more clear and you won't see the artifacts.
Option 2: Use a stroke with the same color as the fill.
As you've already discovered, this draws an outline around the shape.
Option 3: Use int values instead of float values.
You're storing your coordinates and sizes in float values, which can contain decimal places. The problem is, the screen (the actual pixels on your monitor) don't have decimal places (there is no such thing as half a pixel), so they're represented by int values. So when you convert a float value to an int, the decimal part is dropped, which can cause small gaps in your shapes.
If you just switch to using int values, the problem goes away:
size(1000, 100);
noStroke();
background(0);
int squareWidth = 10;
for(int squareX = 0; squareX < width; squareX += squareWidth){
rect(squareX, 0, squareWidth, height);
}

Having trouble drawing Sierpinski's Triangle in Processing

I was trying to draw Sierpinski's Triangle in Processing 3, and managed to get it to run the first two layers. However, when it tries to draw the third and any later layers, it only draws more triangles in some of the triangles.
Here's the code
ArrayList<PVector> initPoints;
int level;
void setup() {
size(400, 400);
noFill();
initPoints = new ArrayList<PVector>();
initPoints.add(new PVector(width/2, height/4));
initPoints.add(new PVector(width/4, 3 * height/4));
initPoints.add(new PVector(3 * width/4, 3 * height/4));
}
void draw() {
triangle(initPoints.get(0).x, initPoints.get(0).y, initPoints.get(1).x, initPoints.get(1).y, initPoints.get(2).x, initPoints.get(2).y);
for (int i = 0; i < 3; i++) {
level = 1;
drawTri(i, initPoints, level);
}
}
PVector findMid(PVector a, PVector b) {
int midX = floor((a.x + b.x)/2);
int midY = floor((a.y + b.y)/2);
return new PVector(midX, midY);
}
void drawTri(int vertex, ArrayList<PVector> basePoints, int layer) {
level = layer + 1;
ArrayList<PVector> points = new ArrayList<PVector>();
points.add(basePoints.get(vertex % 3));
points.add(findMid(basePoints.get(vertex % 3), basePoints.get((vertex + 1) % 3)));
points.add(findMid(basePoints.get(vertex % 3), basePoints.get((vertex + 2) % 3)));
triangle(points.get(0).x, points.get(0).y, points.get(1).x, points.get(1).y, points.get(2).x, points.get(2).y);
if (level < 4) {
for (int i = 0; i < 3; i++) {
drawTri(i, points, level);
}
}
}
Any tips? I think it's something to do with how I'm running the for loops but I'm not sure.
Like I said in my comment, please try to debug your program before you post a question. You need to isolate the problem and understand exactly what the code is doing, and you can do that using print statements and the debugger that comes with the Processing editor.
But just looking at your code, I'm suspicious of the fact that you have a sketch-level level variable as well as a level variable that you're passing into the drawTri() function.
Think about the value of that sketch-level level variable as your code executes. Add print statements to see exactly what it's doing.
If I get rid of the sketch-level level variable, I get this, which I'm guessing is closer to what you wanted:
float x = int(random(0,1024));
float y = int(random(0,600));
float ax=512;
float ay=0;
float bx=0;
float by=600;
float cx=1024;
float cy=600;
void setup()
{
size(1024, 600);
background(0);
}
void nextPoint()
{
int r = int(random(1,7));
float X;
float Y;
if(r==1||r==2)
{
X = lerp(x, ax, 0.5) ;
Y= lerp(y, ay, 0.5);
}
else if(r==3||r==4)
{
X = lerp(x, bx, 0.5) ;
Y= lerp(y, by, 0.5);
}
else
{
X = lerp(x, cx, 0.5) ;
Y= lerp(y, cy, 0.5);
}
x=X;
y=Y;
}
void drawPoint()
{
colorMode(HSB,255,255,255);
stroke(map(y, 0, 15000,100,4000),200,255,10);
strokeWeight(1);
point(ax,ay);
point(bx,by);
point(cx,cy);
point(x, y);
}
void draw()
{
for(int i=0;i<100;++i)
{
drawPoint();
nextPoint();
}
}

Displaying arrays with processing?

So the code I'm writing is to output an array on the screen. The example I have been basing off my problem is here in which there are dots that are an equal distance from each other. If you're too lazy to click the link, this is the code:
float[][] distances;
float maxDistance;
int spacer;
void setup() {
size(640, 360);
maxDistance = dist(width/2, height/2, width, height);
distances = new float[width][height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float distance = dist(width/2, height/2, x, y);
distances[x][y] = distance/maxDistance * 255;
}
}
spacer = 10;
noLoop(); // Run once and stop
}
void draw() {
background(0);
// This embedded loop skips over values in the arrays based on
// the spacer variable, so there are more values in the array
// than are drawn here. Change the value of the spacer variable
// to change the density of the points
for (int y = 0; y < height; y += spacer) {
for (int x = 0; x < width; x += spacer) {
stroke(distances[x][y]);
point(x + spacer/2, y + spacer/2);
}
}
}
What I have coded only returns a white window. This is that code:
float [] arrays = {1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0};;
int spacer=50;
PFont font;
int row;
int col;
void setup(){
size(640,360);
font = createFont("Arial",1);
textFont(font,50);
}
void draw(){
background(255,255,255);
for(int i = 0; i<col; i++){
for(int j=0;j<row;j++){
String myArray = nfp(arrays[i*col+j],1,2);
fill(0,0,0);
text(myArray, i+spacer/2, j+spacer/2);
}
}
}
I'm super new to processing, and stuff. Thanks ahead of time!
In your code, i don't see your col and row initializated.
You should do it in void setup()
Maybe that's the reason why you are not seeing anything on your window, because if this two variables has no value your two loops doesn't execute. In the example you provide, use width and height that are "system variables" that return the size of the window (640x360 in the example)
Also, watch out this:
float [] arrays = {1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0};; (two semicolons)

make curtain like behaviour in drawing of lines

I am new to Processing.js and need a little bit support with this issue. I have made a HTML-Canvas animation where I have lines with a curtain like behavior which can be seen here:
Click
this is made with a canvas plugin called Paper.js
I now want to get similar effect on processing but don't really know how to figure it out. My attempt was:
float x;
float y;
void setup() {
size(1024, 768);
strokeWeight(2);
background(0, 0, 0);
}
void mouseMoved() {
x = mouseX;
y = mouseY;
}
void draw() {
background(0);
line(50, 50, x += x - x/5, y += y - y/5);
stroke(255, 255, 255);
line(50, 700, x += x - x/15, y += y - y/15);
stroke(255, 255, 255);
line(75, 50, x += x - x/25, y += y - y/25);
stroke(255, 255, 255);
line(75, 700, x += x - x/35, y += y - y/35);
// and so on, would create it within a loop
}
So what I am trying to do is basically get the same effect which I have done in HTML and adapt it in Processing.js.
Thanks in advance.
I'd strongly recommend ignoring the paper.js and reimplementing this properly. We're seeing a sequence of lines that connect to a historical line of coordinates, based on mouse position, so let's just implement that:
class Point {
float x, y;
Point(float _x, float _y) { x=_x; y=_y; }}
// our list of historical points
ArrayList<Point> points;
// the horizontal spacing of our lines has fixed interval
float interval;
// how many lines do we want to draw?
int steps = 50;
void setup() {
size(500, 500);
// initialise the "history" as just the midpoint
points = new ArrayList<Point>();
for (int i=0; i<steps; i++) {
points.add(new Point(width/2, height/2));
}
// compute the horizontal interval, because it's
// width-dependent. Never hard code dependent values.
interval = width/(float)steps;
// the lower we set this, the slower it animates.
frameRate(60);
}
void draw() {
// white background, black lines
background(255);
stroke(0);
// for each historic point, draw two
// lines. One from height 0 to the point,
// another from height [max] to the point.
Point p;
for (int i=0; i<steps; i++) {
p = points.get(i);
line(interval/2 + i*interval, 0, p.x, p.y);
line(interval/2 + i*interval, height, p.x, p.y);
}
// when we move the mouse, that counts as a new historic point
points.remove(0);
points.add(new Point(mouseX, mouseY));
}
Sketch running in the browser: http://jsfiddle.net/M2LRy/1/
(You could speed this up by using a round-robin array instead of an ArrayList, but ArrayLists are pretty convenient here)

Resources