How can I adjust this code to include vertexes in the for loops? - for-loop

//Study and use beginShape() and endShape() to draw 3 separate sketches. Each sketch must contain vertices ( vertex() ). tools you will need: beginShape(), endShape(), vertex(), for loop.
//We are supposed to be making Moire patterns. I have gotten the desired result with the code below but it does not include vertexes as the assignment asks. How can I edit adjust this code to include vertices but give the same output?
var theta = 0.0;
var circWidthMultiplier = 17.5;
var circHeightMultiplier = 12.5;
var rectWidthMultiplier = 12.5;
var rectHeightMultiplier =17.5;
var rotationSpeed = 0.005;
function setup() {
createCanvas(windowWidth,windowHeight);
rectMode(CENTER);
}
function draw() {
background(100);
noFill();
push();
beginShape();
translate(width/2, height/2);
for(var i =0; i < 50; i+=5){
ellipse(0, 0,
i*rectWidthMultiplier,
i*rectHeightMultiplier);
}
endShape();
pop();
push();
beginShape();
translate(width/2, height/2);
rotate(theta);
for(var i =0; i < 50; i+=5){
ellipse(0, 0,
i*circWidthMultiplier,
i*circHeightMultiplier);
}
endShape();
pop();
beginShape();
translate(width/2, height/2);
for(var i =0; i < 50; i+=2){
rect(0, 0,
i*circWidthMultiplier,
i*circHeightMultiplier);
}
endShape();
pop();
theta += rotationSpeed;
}

Right now you're using functions like ellipse() and rect() to draw your shapes. You could use beginShape(), vertex(), and endShape() to draw your shapes instead.
Start with replacing the rect() function. You already know the position and size of the rectangle. So it should be pretty easy to replace that with four calls to the vertex() function.
The circles are a little bit trickier, but still doable. You'd need to use basic trigonometry to figure out the vertexes around the circle. Google is your friend here.
But honestly, this seems a little bit pointless. Why bother using vertex() to draw shapes that Processing already draws for you? You might want to check with your instructor to make sure that you're understanding the assignment correctly.

Related

How to draw a fading object trail? Without background manipulation

I have a simple ellipse, moving across the screen, is there any simple code I could implement to have this ellipse draw a trail behind it that has its alpha fade over time to a certain extent? I still want the trail visible in the end but less bright than the casting ellipse.
You could also do something like this:
let positions = [];
function draw(){
positions.push(mouseX);
positions.push(mouseY);
for(let i in positions){
let x = positions[i];
let y = positions[i + 1];
fill(255, 255 - i * 10); noStroke();
ellipse(mouseX, mouseY, x, y)
}
if(positions.length > 20){
positions.shift();
positions.shift();
}
}
Assuming the ellipse is the only thing being drawn then there is a simple solution which is to, instead of drawing a fully opaque background on each frame, draw a semi-transparent background:
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(0, 35);
ellipse(mouseX, mouseY, 20, 20);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
However, there are some caveats, namely that for certain colors/transparency levels you will be left with permanent "ghost" of the trails due to some weird alpha blending math anomalies.

P3D camera orientation

I've got a big sphere. There is a red dot that moves around the sphere. I want to follow that red dot as it moves around to sphere. So my camera has to move with the red dot. But there is a problem. Right now, what I'm experiencing is what is shown in exhibit B. I want my animation to realize the point of view shown in exhibit A.
Here is the code I have so far. I think it's pretty simple. I have 3 variables that control where my eye is, and I have 3 variables that control where the target is. The red dot is also located at the target position. I added 2 planes in x-y which helped me not get too confused as the thing was spinning.
Here is a fiddle:
https://jsfiddle.net/da8nza6y/
float radius = 1000;
float view_elevation = 1500;
float target_elevation = 300;
float x_eye;
float y_eye;
float z_eye;
float x_aim;
float y_aim;
float z_aim;
float h;
float theta;
void setup() {
size(600, 600, P3D);
theta = 0;
h = 30;
}
void draw() {
theta += 0.5;
theta = theta%360;
x_eye = (radius+view_elevation)*cos(theta*PI/180);
y_eye = 0;
z_eye = (radius+view_elevation)*sin(theta*PI/180);
x_aim = (radius+target_elevation)*cos((theta+h)*PI/180);
y_aim = 0;
z_aim = (radius+target_elevation)*sin((theta+h)*PI/180);
camera(x_eye, y_eye, z_eye, x_aim, y_aim, z_aim, 0, 0, -1);
background(255);
// the red dot
pushMatrix();
translate(x_aim, y_aim, z_aim);
fill(255, 0, 0, 120);
noStroke();
sphere(10);
popMatrix();
// the big sphere
noStroke();
fill(205, 230, 255);
lights();
sphere(radius);
// the orange plane
pushMatrix();
translate(0, 0, 10);
fill(255, 180, 0, 120);
rect(-2000, -2000, 4000, 4000);
popMatrix();
// the green plane
pushMatrix();
translate(0, 0, -10);
fill(0, 180, 0, 120);
rect(-2000, -2000, 4000, 4000);
popMatrix();
}
So the pickle is that, it seems like the moment the red dot (whose location in the x-z plane is given by the angle (theta+h) and distance (radius+target_elevation) from the origin) crosses the x-y plane, everything gets flipped upside-down and backwards.
Now, I have tried to control the last 3 variables in the camera() function but I'm getting confused. The documentation for the function is here:
https://processing.org/reference/camera_.html
Can anyone see a solution to this problem?
Also, I'm sure I could just rotate the sphere (which I can do) and not have these problems, but I'm sure where I'm going with this animation and I feel like there will be things to come that will be easier with this method. Though I could be mistaken.
I believe I've solved my own problem.
I've added the following lines in draw, before calling the camera() function:
if ((x_eye- x_aim) < 0) {
z_orientation = 1;
} else {
z_orientation = -1;
}
I noticed that it wasn't (theta+h) that was triggering the flip, but the relative positions of the view and target.
Here is an updated fiddle:
https://jsfiddle.net/da8nza6y/1/

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.

How to draw string objects at an angle in Processing?

The code below draws a spiral using objects from a string array. Everything is fine, except that I would like the text objects to be drawn at a roughly 45 degree angle at each instance (based on the current x, y coordinates in the code below) rather than being drawn horizontally (when the text is horizontally drawn, it naturally overlaps with other text at concentrated points along the top & bottom of the curve). I researched some methods, but I'm still very new to all of this, and potential solutions have all evaded me.
String example = "";
String[] wordSet = split(example, " ");
float x, y;
float angle = 0;
float radiusSpiralLine = 10;
size (800, 800);
translate(width/2, height/2);
background(#ffffff);
smooth();
fill(0);
for (int i = 0; i < wordSet.length; i++) {
angle += .05;
radiusSpiralLine += .5;
x = cos(angle) * radiusSpiralLine;
y = sin(angle) * radiusSpiralLine;
textSize(9);
text(wordSet[i], x, y);
}
Here is tutorial to very similar problem. In basic you need to store projection matrix by pushMatrix() then translate and rotate according to position of letter on curve and then restore matrix by popMatrix(). I don't know how exactly do you want to rotate you text but just fold round your text() function like this maybe it will help you:
pushMatrix();
translate(x, y);
rotate(angle);
text(wordSet[i], 0, 0);
popMatrix();
First, you should start getting in the habit of wrapping code in the setup() and draw() functions. Since you're drawing a static image you don't need the draw() function, but I think it's good practice to have those two.
Now, what you are doing now is simply translating the words by a very small amount. Do the math:
x = cos(angle) * radiusSpiralLine; //cos(.05)*.5 = .499
y = sin(angle) * radiusSpiralLine; //sin(.05)*.5 = .024
That means they move less than a pixel, and they're not rotating at all.
What you need is your good ol' friend, the rotate() function.
Let's re-write code:
String example = "These are a bunch of words going around!";
String[] wordSet = split(example, " ");
float x, y;
float angle = 0;
void setup() {
size (800, 800);
background(#ffffff);
smooth();
fill(0);
pushMatrix();
translate(width/2, height/2); //Translate when you need to translate, not before
for (int i = 0; i < wordSet.length; i++) {
angle = PI/5; //Our good friends, radians
textSize(20); //What is this, text for ants? Change to 20
rotate(angle);
text(wordSet[i], 20, 0);
}
popMatrix();
}
void draw() {
}
First notice, the setup() and draw(). I like them there. It looks nicer, I think.
A couple of important things to note.
The effects of rotate() and translate() are on the canvas are cumulative.
We could have had the same effect in different ways:
for (int i = 0; i < wordSet.length; i++) {
angle = PI/5;
textSize(20);
rotate(angle); //always rotating by PI/5 ON TOP of previous rotation
text(wordSet[i], 20, 0);
}
//Everything from now on will still be rotated, we don't want that!
Slightly better, but not there yet:
for (int i = 0; i < wordSet.length; i++) {
angle += PI/5; //constantly increasing the angle
textSize(20);
pushMatrix(); //push a new canvas on top of everything
rotate(angle); //rotate by angle (which increases every loop)
text(wordSet[i], 20, 0);
popMatrix(); //pop the rotated canvas out, go back to original canvas
} //Things won't be rotated, but they'll still be translated, since translate() is outside of pushMatrix and popMatrix
Hope this helps.

Continuous rotation in Processing

I wrote a program in Procesisng that renders opaque cubes with random colour and rotation on top of each other, but I'm looking to individually continuously spin each cube while the program is running. Here's my code at the moment,
int boxval = 1;
void setup(){
size (640, 320, P3D);
frameRate(60);
}
void draw(){
for (int i = 0; i < boxval; i++){
translate(random(0,640), random(0,320), 0);
rotateY(random(0,360));
rotateX(random(0,360));
rotateZ(random(0,360));
fill(random(0,255),random(0,255),random(0,255),50);
noStroke();
box(64,64,64);
}
}
Here's a screenshot if it helps at all,
This is a great time to use Object Oriented Programming! If I understand the question correctly, you would like each cube to rotate independently of the other cubes. Let's make a Cube class. Think of each cube as an object that we will handle individually.
class Cube {
float x, y, z; // position of the cube
float size; // size of cube
color c; // color of cube
float xAngle, yAngle, zAngle; // current rotation amount of cube's x, y, z axes
float xSpeed, ySpeed, zSpeed; // how quickly the cube is rotated in the x, y, z axes
// Cube constructor - create the cube and all of its parameters
Cube(float x_, float y_, float z_, float size_, color c_, float xSpeed_, float ySpeed_, float zSpeed_) {
x = x_;
y = y_;
z = z_;
size = size_;
c = c_;
xSpeed = xSpeed_;
ySpeed = ySpeed_;
zSpeed = zSpeed_;
xAngle = yAngle = zAngle = 0; // starting position
}
// update the cube
// all we're doing is rotating each axis
void update() {
xAngle += xSpeed;
yAngle += ySpeed;
zAngle += zSpeed;
}
// draw the cube to the screen
void display() {
pushMatrix(); // need this
translate(x, y, z); // position on screen
rotateX(xAngle); // rotation amounts
rotateY(yAngle);
rotateZ(zAngle);
fill(c);
noStroke();
box(size);
popMatrix(); // and this
// push and pop matrix allows for individual cube rotation
// otherwise you would rotate the whole draw window, which isn't what you're looking for
}
}
If you would like each cube to change color and position on screen but still rotate independently, the display() function could be something like this instead:
void display() {
pushMatrix();
translate(random(0, width), random(0, height), random(-100, 100)); // random position on screen
rotateX(xAngle);
rotateY(yAngle);
rotateZ(zAngle);
fill(random(255), random(255), random(255), 50); // random color
noStroke();
box(size);
popMatrix();
}
Understanding rotation and translation of elements in Processing is really key. I highly recommend this tutorial from the Processing website if you have not read it. I incorporated some concepts into the Cube class.
Since you would like to have more than one Cube drawn on the screen, let's make an array of Cubes. I chose 25 as an arbitrary number.
Cube[] cube = new Cube[25];
Now in setup(), we'll need to actually create each Cube and give it certain parameters, like position on screen, color, etc. Here is how that is accomplished.
for (int i = 0; i < cube.length; i++) {
cube[i] = new Cube(random(0, width), random(0, height), 0, // x, y, z position
random(30, 80), color(random(255), random(255), random(255), 50), // size, color
random(0.001, 0.020), random(0.001, 0.020), random(0.001, 0.020)); // xSpeed, ySpeed, zSpeed
}
Now we just need to draw the Cubes to the screen and update the rotation of each one, which simply happens in the draw() loop.
for (int i = 0; i < cube.length; i++) {
cube[i].update();
cube[i].display()
}
Here is whole program. It's important to call background() each time through the draw() loop so the display window will be cleared each frame. Comment it out to see what will happen, but I noticed that was not in the code snippet you provided above. I guess it can be an effect though!
Cube[] cube = new Cube[25];
void setup() {
size(640, 320, P3D);
smooth();
frameRate(60);
for (int i = 0; i < cube.length; i++) {
cube[i] = new Cube(random(0, width), random(0, height), 0,
random(30, 80), color(random(255), random(255), random(255), 50),
random(0.001, 0.020), random(0.001, 0.020), random(0.001, 0.020));
}
}
void draw() {
camera();
lights();
background(50);
for (int i = 0; i < cube.length; i++) {
cube[i].update();
cube[i].display();
}
}
I'm not sure what your programming background is, but getting a hang of Object Oriented Programming is really helpful in Processing (and other OOP languages), so I'd recommend this OOP tutorial from the Processing website if you need a crash course. My programming life changed when OOP finally made sense.

Resources