#pvector
Explore tagged Tumblr posts
Text
// Az aranymetszés aránya final float PHI = 1.618; int saveCount = 0; // Mentések számlálója String savePath = "C:\Users\hp\Desktop\sketch_220317a\ixek\"; // Mentési mappa ArrayList positions = new ArrayList<>(); // Tárolja az X-ek helyét void setup() { size(400, 570); // Ablak mérete background(255); // Fehér háttér textSize(32); // Az "X" mérete textAlign(CENTER, CENTER); // Középre igazítás fill(10); // X szín noLoop(); // Csak egyszer fut le, kivéve ha újraindítjuk generateImage(); } void draw() { // A kép generálása a setup() vagy a space lenyomásakor történik } void generateImage() { background(255); // Új háttér, hogy ne rajzoljon egymásra positions.clear(); // Töröljük az előző pozíciókat for (int i = 0; i < 6; i++) { PVector pos; do { float x = generateGoldenRatio(width); float y = generateGoldenRatio(height); pos = new PVector(x, y); } while (isOverlapping(pos)); // Ha fedésben van másik X-szel, új helyet keres positions.add(pos); // Hozzáadjuk a listához text("X", pos.x, pos.y); // Kirajzoljuk az X-et // A távolság kiírása úgy, hogy ne lógjon ki a képből String distanceText = "(" + int(pos.x) + " px, " + int(pos.y) + " px)"; PVector textPos = adjustTextPosition(pos); textSize(16); // Kisebb betűméret a távolság kiírásához text(distanceText, textPos.x, textPos.y); positions.add(textPos); // A szöveg pozícióját is mentjük, hogy ne legyen fedés textSize(32); // Visszaállítjuk az X méretét } } void keyPressed() { if (key == ' ') { // Space lenyomására újragenerálja a képet generateImage(); } else if (key == ENTER || key == RETURN) { // Enter lenyomására menti a képet saveImage(); } } // Generál egy pozíciót az aranymetszés szabályai szerint float generateGoldenRatio(float max) { float goldenSection = max / PHI; return random(1) > 0.5 ? random(goldenSection, max) : random(0, goldenSection); } // Ellenőrzi, hogy egy adott pozíció túl közel van-e másik X-hez vagy szöveghez boolean isOverlapping(PVector newPos) { float minDist = 40; // Minimum távolság az X-ek és szövegek között for (PVector pos : positions) { if (newPos.dist(pos) < minDist) { return true; // Fedés van } } return false; } // Beállítja a távolság szöveg helyét úgy, hogy ne lógjon ki a képből PVector adjustTextPosition(PVector pos) { float textOffsetY = 30; // Alapból az X alá írjuk float textX = pos.x; float textY = pos.y + textOffsetY; // Ha túl közel van az alsó széléhez, akkor fölé írjuk if (textY > height - 10) { textY = pos.y - textOffsetY; } // Ha túl közel van a bal oldalhoz, jobbra toljuk if (textX < 40) { textX += 20; } // Ha túl közel van a jobb oldalhoz, balra toljuk if (textX > width - 40) { textX -= 20; } return new PVector(textX, textY); } // Kép mentése megadott könyvtárba void saveImage() { String filename = savePath + "generated_image_" + saveCount + ".jpg"; save(filename); println("Kép elmentve ide: " + filename); saveCount++; }
0 notes
Text
Asteroids and Planets
The Prompt: Create a sketch that would simulate an existing natural system - look at physics, biology, and other natural sciences for good examples. Start with the environment - where is the system situated? What are the forces the environment might exert on the system? Examine the agents in the system, their relationships to each other and the environment they are in. The look at how this system would develop over time. What are the rules that you are going to come up with, what are the parameters you are going to feed into them and what effect will the changes have on the development of the system.
I created a sketch of a solar system

My idea was to have a sun in the center, the sun creates planets that orbit it and there are asteroids that when they touch a planet the asteroids and planets are destroyed, if an asteroid touches the sun then the sun explodes
I started by first creating all of my elements, the sun, the planets that orbit it and the falling asteroids
With the help of chatgpt I asked it to make the planets spawn from the sun using the mouse pressed function From my understanding the orbit radius chooses how big the radius the planet is orbiting is, the sun position makes sure that the planet will spawn only when the sun is clicked
I then asked chat gpt to help once again, if an asteroid hit a planet I wanted it to destroy itself and the planet, I went back and forth with it for a bit and the code changed, I wish I got some more process pictures here but it took me a few questions before it understood what I wanted I did copy the code onto a new processing sketch, but the concept remained the same, however chat gpt changed the code adding pvector gravitational force function and I wasn't able to mix my code with the new code to make it work so I started working with this new code, and this is the final result The code
I couldn't figure out how to change the code so that the planets orbited the sun, I edited the numbers, but things would start breaking, I did mange to get the asteroids to destroy the planets and to get and if an asteroid touched the sun in a certain spot it would explode (aka grow to a very large size) sign to restart the sketch
Look at the code here
0 notes
Text
Infection Simulation
Assignment: Create an interactive simulation using processing.exe
My original idea was too grand in scope because I got excited (classic). I can see the potential for making all kinds of games using processing! So here's a simplified sketch.

Basic concept is that there are several sections where little dots will be bouncing around off the walls, and there are gaps where the dots can pass through from one section to the next. One infected dot will bounce around and when the others are in proximity, it will have a high chance of infecting them. After a certain amount of time being infected, a dot will either become "immune" -- where it has a slightly less chance of becoming infected -- or it will die", i.e., dissappear completely. After a certain amount of time, an "immune" dot will return to a normal, "uninfected" state.
An idea if I had extra time, would be a a "doctor" dot, which will turn "infected" dots "immune" immediately upon contact.
The user would have control over the size of the gaps. The "game" can end in two ways: either all the dots have died, or all the dots have been cured!
Time to get to work.
I played around a lot with how I wanted it to look, but could really only get the growing borders to work in this column-like structure. I then had an epiphany that rather than doing something like this, it might be more fun to do a pong-like structure where the user controlled two individual lines and could try and "trap" dots that way.
Thinking ahead/remembering what Maxim said in class about how it might be easier to have the information formatted as PVectors for the sake of simplicity, I created a "border" class with PVectors representing the x and y positions of each end of the line. I created two instances of a "border": Horz and Vert, passing information into them in the setup.
To make them reactive to the user, I set up a "speed" variable, and set it so that when the user presses the left and right keys, the Horz's x positions would change (to newx1 instead of _x1, etc) and the Vert's y positions would change (to newy1 instead of _y1, etc).
Looks pretty good. Now comes the tough part: making the infection simulation.
First part is trying to get my "people" to stay inside the window and bounce off the borders which... proved difficult. They bounce off the edges of the window well enough but getting them to respond to the borders is tricky, they have a tendancy to freak out and just vibrate in place when vaguely near the borders... hmm.

The solution: turn the lines into very thin rectangles. I think the people were getting confused trying to bounce off a single line of pixels, maybe. Either way, working great now! I did have to do a whole sketch to do some basic math but ... part of the process.
But now the actual simulation bit: making the INFECTION....
The struggle is real.
I finally got somewhere with the dots changing color by creating a an "infect" function and an "update infection" function that responds to the time elapsed in the simulation. However, I couldn't get dots to infect eachother correctly or change to their "immune" or "dead" colors; they were only able to change from "infected" to "uninfected" colors (even when the immune or dead boolean was true). This led me to believe that a series of booleans was not the correct approach, and instead of each status being a boolean, a set of "enumerated types" would be more appropriate (shout out chatgpt).
Success! In one aspect that is. The colors were now changing appropriately according to status. However, the "infected" dot was still not infecting the ones around it...
The issue was this line! It was only checking each individual's contact against istelf rather than other people in the array. Here is the adjusted line:
And now it works great!
I received some feedback from Maxim in class about using a noise generator to change the infection rate and length... maybe I'll try that later but I have a double feature to catch at the New Beverly right now!
Here is the code, try it out for yourself!
0 notes
Text
Broken Collisions
Particles universe;
void setup() {
size(1552,739);
frameRate(60);
universe = new Particles(100);
Particle p;
for(int i=0; i < universe.numberOfParticles(); i++) {
p = universe.particleAt(i);
p.volume = 50.0;
}
}
void draw() {
background(0);
universe.update();
universe.draw();
}
class Particles {
ArrayList particles;
Particles(int numParticles) {
particles = new ArrayList();
for(int i=0; i < numParticles; i++) {
particles.add(new Particle(i, random(width), random(height), this));
}
}
void update() {
Particle p;
for(int i=0; i < numberOfParticles(); i++) {
particleAt(i).updateVelocity();
}
// going backwards, because we may delete particles
for(int i=numberOfParticles() - 1; i >= 0; i--) {
p = particleAt(i);
if(p.destroyed) {
particles.remove(i);
}
else {
p.updatePosition();
}
}
}
void draw() {
for(int i=0; i < numberOfParticles(); i++) {
Particle p = particleAt(i);
p.draw();
}
}
int numberOfParticles() {
return particles.size();
}
Particle particleAt(int i) {
return particles.get(i);
}
void addNewParticle(Particle p) {
particles.add(p);
p.myId == numberOfParticles() - 1;
}
}
class Particle {
int myId;
float mass = 100;
float volume = 20;
float minVolume = 1;
PVector acceleration;
PVector velocity;
PVector position;
Particles universe;
boolean destroyed;
boolean collided;
color myColor = color(random(255), random(255), random(255));
Particle(int inMyId, float positionX, float positionY, Particles inUniverse) {
myId = inMyId;
universe = inUniverse;
destroyed = false;
acceleration = new PVector(0,0);
velocity = new PVector(0,0);
position = new PVector(positionX, positionY);
}
void updateVelocity() {
acceleration.set(0,0,0);
for(int i=0; i < universe.numberOfParticles(); i++) {
if(i != myId) {
Particle other = universe.particleAt(i);
float diffX = other.position.x - position.x;
float diffY = other.position.y - position.y;
float distance = abs(PVector.dist(position, other.position));
if((distance) < volume && !collided && !other.collided)
{
hitOtherParticle(other);
}
PVector attraction = new PVector(diffX, diffY);
attraction.normalize(); // make it a unit vector
// we'll figure out how to handle collision in a later post
// attraction to the other object is inverse to the
// square of the distance to the other object.
attraction.mult(other.mass / sq(distance));
acceleration.add(attraction);
}
}
velocity.add(acceleration);
velocity.limit(20);
}
void hitOtherParticle(Particle other) {
PVector v1 = velocity;
PVector v2 = other.velocity;
PVector v1f = new PVector();
PVector v2f = new PVector();
// Apply the formula for elastic collision
v1f.x = (v1.x - v2.x) / 2 + v2.x; // Final velocity
v2f.x = (v2.x - v1.x) / 2 + v1.x; // Final velocity
velocity.set(v1f);
other.velocity.set(v2f);
collided = true;
other.collided = true;
}
void updatePosition() {
position.add(velocity);
if(position.x < 0) {
position.x = 0;
velocity.set(-velocity.x, velocity.y, velocity.z);
}
else if(position.x > width) {
position.x = width;
velocity.set(-velocity.x, velocity.y, velocity.z);
}
if(position.y < 0) {
position.y = 0;
velocity.set(velocity.x, -velocity.y, velocity.z);
}
else if(position.y > height) {
position.y = height;
velocity.set(velocity.x, -velocity.y, velocity.z);
}
collided = false;
}
void draw() {
drawPosition();
}
void drawPosition() {
stroke(myColor);
strokeWeight(volume);
point(position.x, position.y);
}
void drawVelocity() {
stroke(255,0,0);
strokeWeight(1);
line(position.x, position.y,
position.x + velocity.x,
position.y + velocity.y);
}
void drawAcceleration() {
stroke(0,0,255);
strokeWeight(1);
line(position.x, position.y,
position.x + acceleration.x,
position.y + acceleration.y);
}
}
0 notes
Photo
// .pde // Processing 3.4 ParticleSystem ps; void setup() { size(540, 750); background(0); ps = new ParticleSystem(); } void draw() { noStroke(); fill(0,10); rect(0,0,width,height); ps.addParticle(); ps.run(); } class ParticleSystem { ArrayList<Particle> particles; ParticleSystem() { particles = new ArrayList<Particle>(); } void addParticle() { for (int i = 0; i < 10; i++) { particles.add(new Particle(random(width), random(height))); } } void run() { for (int i = particles.size()-1; i >= 0; i--) { Particle p = particles.get(i); p.run(); if (p.isDead()) { particles.remove(i); } } } } class Particle { PVector location; PVector velocity; float lifespan; Particle(float x, float y) { location = new PVector(x,y); lifespan = 255.0; } void run() { update(); display(); } void update() { float angle = noise(location.x*.01,location.y*.01)*TAU; velocity = new PVector(sin(angle), cos(angle)); location.add(velocity); lifespan -= 1.0; } void display() { strokeWeight(2); stroke(255, lifespan); point(location.x, location.y); } boolean isDead() { if(location.x > width-120 || location.x < 120){ return true; } if(location.y > height-20 || location.y < 20){ return true; } if (lifespan < 0.0) { return true; } else { return false; } } }
152 notes
·
View notes
Text
Episode 1 of James Learns Programming!
Who knows if this will lead to a whole blog series or my laziness will render this to be an embarrassing standalone post but oh well... I deleted my games so I may as well post about it with all the free time I have (not much actually). I don’t know why I mentioned that or why I am still narrating my thought process but ANYWAYS!
Tonight, I have decided to finally tackle Assignment 2 for my programming class which requires me to simulate a certain number of balls (hopefully three) bouncing around a canvas. And so that when they collide with each other, they stick together and continue to bounce around in unison.

The epitome of contentment or perhaps postception...
I began by setting up the canvas, setting the ellipse mode to center cause why not and before I do anything else, I’m gonna teach myself how to do OOP (Object Oriented Programming I think??) and to use PVectors.
Here is the video I am currently watching to accomplish the latter:
https://www.youtube.com/watch?v=7nTLzLf7jUg
Let’s see where this goes...
__________________________________________
PVector location;
location = new PVector (100, 50);
___________________________________________
Oh... wow. So here’s what I learnt:
PVector is a class that stores two variables (three but we shall not tread into the 3D realm yet): x and y
It’s used so you don’t have to keep on typing x and y all the time and also so that you know what the x and y are for (eg. the x and y components of velocity, location, etc)
The video contains code that does everything except collision detection... but I won’t abuse it cause learning is gud
Now that’s done, I shall attempt to replicate the code from scratch... right after I figure out how to make a class (hahaha siiiiigh I’m so far behind).
Important Stuff to Keep Note of While I Read That I’ll Forget After Reading:
Class: a description of the structure of an object
Instance: a specific example from a class
After you define a class, you can use it as a new variable type
Okay reading sucks here’s a video(s) on Classes in Processing:
https://www.youtube.com/watch?v=lmgcMPRa1qw (defining a class part I)
https://www.youtube.com/watch?v=XwfOVFelLoo (defining a class part II)
A lot of the info about defining a class has gone way over my head especially the constructor part of it so I’m going to play around with it in processing now.
An hour later...
HEY! So I kinda got it, I managed to create a class for balls and had their locations and radii successfully randomized upon generation.
And now I have managed to get them bouncing around the screen.
It is now time for me to go to bed as I have some random class at 9 am tomorrow to go to.
Tonight was a lot of fun :).
1 note
·
View note
Text
Particle[] particles;
PVector[] flowField;
0 notes
Text
DES 240
Topic: LIFE BELOW WATER
60 percent of lakes and rivers are too polluted for swimming in New Zealand
Miro link:https://miro.com/app/board/o9J_l2OFWEk=/
Drafts:
Process photos:
The first one was selected and modified.

The rise of the water is reduced and a splash effect is added.
Final code:
//Floating
float gravity = 9; // The falling acceleration of each object
float timeFactor = 0.2; // The speed of animation
int dropInterval = 1; // Drop a random shape in this amount of seconds
int maximumObject = 10; // Maximum floating object on the screen
ArrayList<FloatingObject> shapes;
ArrayList<WaterDot> dots; // water splash dots
void setup() {
size(1000, 1000);
shapes = new ArrayList<FloatingObject>();
dots = new ArrayList<WaterDot>();
}
void draw() {
if (frameCount % (dropInterval*60) == 0){ // Attempt to create an object every dropInterval seconds
if (shapes.size() < maximumObject){ // Only add an object if the total number of objects are under the maximum
addObject();
}
}
// Update positions of the floating objects
for (int i=0; i<shapes.size(); i++) {
FloatingObject obj = shapes.get(i);
obj.update();
}
background(255);
// draw floating objects that are behind the water
for (int i=0; i<shapes.size(); i++) {
FloatingObject obj = shapes.get(i);
if (obj.behindWater)
obj.drawMe();
}
fill(0);
rectMode(CORNER);
rect(0, height*0.4, width, height);
// draw floating objects that are in front of the water
for (int i=0; i<shapes.size(); i++) {
FloatingObject obj = shapes.get(i);
if (!obj.behindWater)
obj.drawMe();
}
for (int i=0; i<dots.size(); i++){
WaterDot dot = dots.get(i);
dot.drawMe();
if (!dot.isAlive)
dots.remove(i);
}
}
void addObject(){
float randNum = random(100);
PVector position = new PVector(random(50, width-50), -50);
if (randNum < 33) {
shapes.add(new Circle(position));
} else if (randNum < 66) {
shapes.add(new Rectangle(position));
} else {
shapes.add(new Triangle(position));
}
}
void mousePressed() {
// Add a shape at mouse position on every click
float randNum = random(100);
if (randNum < 33) {
shapes.add(new Circle(new PVector(mouseX, mouseY)));
} else if (randNum < 66) {
shapes.add(new Rectangle(new PVector(mouseX, mouseY)));
} else {
shapes.add(new Triangle(new PVector(mouseX, mouseY)));
}
}
//Floating object
class FloatingObject{
PVector pos;
PVector vel;
float damp = 0.95;
float floatingHeight = random(0.25, 0.4);
boolean behindWater = false;
boolean touchedWater = false;
FloatingObject(PVector pos, PVector vel){
this.pos = pos;
this.vel = vel;
if (random(100) < 30){
behindWater = true; // Make this object behind the water
}
}
void move(){
// Updates the shape's position
pos.add(vel);
vel.mult(damp);
if (abs(vel.y) < 0.2) vel.y = 0;
}
void accelerate(PVector acc){
vel.add(acc);
}
void update(){
move();
accelerate(new PVector(0, gravity*timeFactor));
// Handle gravity
if (pos.y < height*floatingHeight){ // Object free falls when above 40% of the screen
return;
} else {
if (!touchedWater){ // Create water splash when first time touch the water
touchedWater = true;
for (int i=0; i<20; i++)
dots.add(new WaterDot(pos.copy(), new PVector(random(-10, 10), -random(10, 20))));
}
float buoyancy = map(pos.y, height*floatingHeight, height, 0, 50*timeFactor); // Below the screen will have increasing buoyancy
buoyancy = constrain(buoyancy, 0, 50);
accelerate(new PVector(0, -buoyancy));
}
}
void drawMe(){
// Dummy draw method
}
}
// A circle shape
class Circle extends FloatingObject{
float radius = random(100, 180);
Circle(PVector pos){
super(pos, new PVector(0, 0));
}
void drawMe(){
stroke(0);
strokeWeight(8);
fill(255);
ellipse(pos.x, pos.y, radius, radius);
}
}
// A rectangle shape
class Rectangle extends FloatingObject{
float rotation = random(0, PI);
float w = random(60, 180);
float h = random(60, 180);
Rectangle(PVector pos){
super(pos, new PVector(0, 0));
}
void drawMe(){
stroke(0);
strokeWeight(8);
fill(255);
rectMode(CENTER);
pushMatrix();
translate(pos.x, pos.y);
rotate(rotation);
rect(0, 0, w, h);
popMatrix();
}
}
// A triangle shape
class Triangle extends FloatingObject {
float rotation = random(0, PI);
float x1, y1, x2, y2, x3, y3;
Triangle(PVector pos) {
super(pos, new PVector(0, 0));
x1 = random(-50, 20);
y1 = random(-80, -20);
x2 = random(60, 180);
y2 = random(-80, -20);
x3 = x1/2 + x2/2;
y3 = random(60, 100);
}
void drawMe() {
stroke(0);
strokeWeight(8);
fill(255);
rectMode(CENTER);
pushMatrix();
translate(pos.x, pos.y);
rotate(rotation);
triangle(x1, y1, x2, y2, x3, y3);
popMatrix();
}
}
// Describes a single water in a splash
class WaterDot{
PVector pos;
PVector vel;
boolean isAlive = true;
float diameter = random(5, 15);
WaterDot(PVector pos, PVector vel){
this.pos = pos;
this.vel = vel;
}
void drawMe(){
pos.add(vel);
vel.add(new PVector(0, gravity/2*timeFactor));
if (pos.y > height) // Remove the dot if outside the screen
isAlive = false;
fill(0);
strokeWeight(0);
ellipse(pos.x, pos.y, diameter, diameter);
}
}
Final animated:
Statement of intent:
Sixty percent of the water in New Zealand's rivers and lakes is heavily polluted. So I have divided the image into two parts, the black part representing the rivers that make up 60 per cent of the image. The various geometric shapes represent different kinds of pollution, such as land pollution, waste pollution, sewage discharge and so on. In the animation, the geometric shapes are made to float on the surface of the river, which means that these actions will cause serious pollution to the river and the lake, which will not disappear on its own, but will only accumulate in the river water. And I added a mouse click condition to the code, partly to make the piece interactive, and partly to simulate the process of pollution caused by humans.I hope that after watching this animation, you will know that we all have a responsibility for the pollution of rivers and lakes.
0 notes
Text
Path tracking code
Find the skeleton and the pantograph codes below:
SKELETON
/** ********************************************************************************************************************** * @file sketch_2_Hello_Wall.pde * @author Steve Ding, Colin Gallacher, Antoine Weill--Duflos * @version V1.0.0 * @date 09-February-2021 * @brief PID example with random position of a target ********************************************************************************************************************** * @attention * * ********************************************************************************************************************** */
/* library imports *****************************************************************************************************/ import processing.serial.*; import static java.util.concurrent.TimeUnit.*; import java.util.concurrent.*; import controlP5.*; /* end library imports *************************************************************************************************/
/* scheduler definition ************************************************************************************************/ private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); /* end scheduler definition ********************************************************************************************/
ControlP5 cp5;
/* device block definitions ********************************************************************************************/ Board haplyBoard; Device widgetOne; Mechanisms pantograph;
byte widgetOneID = 5; int CW = 0; int CCW = 1; boolean renderingForce = false; /* end device block definition *****************************************************************************************/
/* framerate definition ************************************************************************************************/ long baseFrameRate = 120; /* end framerate definition ********************************************************************************************/
/* elements definition *************************************************************************************************/
/* Screen and world setup parameters */ float pixelsPerMeter = 4000.0; float radsPerDegree = 0.01745;
/* pantagraph link parameters in meters */ float l = 0.07; float L = 0.09;
/* end effector radius in meters */ float rEE = 0.006;
/* generic data for a 2DOF device */ /* joint space */ PVector angles = new PVector(0, 0); PVector torques = new PVector(0, 0); PVector oldangles = new PVector(0, 0); PVector diff = new PVector(0, 0);
/* task space */ PVector posEE = new PVector(0, 0); PVector fEE = new PVector(0, 0);
/* device graphical position */ PVector deviceOrigin = new PVector(0, 0);
/* World boundaries reference */ final int worldPixelWidth = 1000; final int worldPixelHeight = 650;
float x_m,y_m;
// used to compute the time difference between two loops for differentiation long oldtime = 0; // for changing update rate int iter = 0;
/// PID stuff
float P = 0.0; // for I float I = 0; float cumerrorx = 0; float cumerrory = 0; // for D float oldex = 0.0f; float oldey = 0.0f; float D = 0;
//for exponential filter on differentiation float diffx = 0; float diffy = 0; float buffx = 0; float buffy = 0; float smoothing = 0.80;
float xr = 0; float yr = 0; float xO = 0; float yO = 0; int last = 0; int m = 0 ;
// checking everything run in less than 1ms long timetaken= 0;
// set loop time in usec (note from Antoine, 500 is about the limit of my computer max CPU usage) int looptime = 500;
/* graphical elements */ PShape pGraph, joint, endEffector; PShape wall; PShape target; PFont f; /* end elements definition *********************************************************************************************/
/* setup section *******************************************************************************************************/ void setup(){ /* put setup code here, run once: */
/* screen size definition */ size(1000, 700);
/* GUI setup */ smooth(); cp5 = new ControlP5(this); cp5.addTextlabel("Prop") .setText("Gain for P(roportional)") .setPosition(0,0) .setColorValue(color(255,0,0)) .setFont(createFont("Georgia",20)) ; cp5.addKnob("P") .setRange(0,2) .setValue(0) .setPosition(50,25) .setRadius(50) .setDragDirection(Knob.VERTICAL) ; cp5.addTextlabel("Int") .setText("Gain for I(ntegral)") .setPosition(0,125) .setColorValue(color(255,0,0)) .setFont(createFont("Georgia",20)) ; cp5.addKnob("I") .setRange(0,2) .setValue(0) .setPosition(50,150) .setRadius(50) .setDragDirection(Knob.VERTICAL) ; cp5.addTextlabel("Deriv") .setText("Gain for D(erivative)") .setPosition(0,250) .setColorValue(color(255,0,0)) .setFont(createFont("Georgia",20)) ; cp5.addKnob("D") .setRange(0,4) .setValue(0) .setPosition(50,275) .setRadius(50) .setDragDirection(Knob.VERTICAL) ; cp5.addTextlabel("Deriv filt") .setText("Exponential filter for Diff") .setPosition(0,375) .setColorValue(color(255,0,0)) .setFont(createFont("Georgia",20)) ; cp5.addSlider("smoothing") .setPosition(10,400) .setSize(200,20) .setRange(0,1) .setValue(0.8) ; cp5.addTextlabel("Loop time") .setText("Loop time") .setPosition(0,420) .setColorValue(color(255,0,0)) .setFont(createFont("Georgia",20)) ; cp5.addSlider("looptime") .setPosition(10,450) .setWidth(200) .setRange(250,4000) // values can range from big to small as well .setValue(500) .setNumberOfTickMarks(16) .setSliderMode(Slider.FLEXIBLE) ; cp5.addButton("RandomPosition") .setValue(0) .setPosition(10,500) .setSize(200,50) ; cp5.addButton("ResetIntegrator") .setValue(0) .setPosition(10,560) .setSize(200,50) ; cp5.addButton("ResetDevice") .setValue(0) .setPosition(10,620) .setSize(200,50) ;
/* device setup */
/** * The board declaration needs to be changed depending on which USB serial port the Haply board is connected. * In the base example, a connection is setup to the first detected serial device, this parameter can be changed * to explicitly state the serial port will look like the following for different OS: * * windows: haplyBoard = new Board(this, "COM10", 0); * linux: haplyBoard = new Board(this, "/dev/ttyUSB0", 0); * mac: haplyBoard = new Board(this, "/dev/cu.usbmodem1411", 0); */ haplyBoard = new Board(this, "COM3", 0); widgetOne = new Device(widgetOneID, haplyBoard); pantograph = new Pantograph();
widgetOne.set_mechanism(pantograph);
widgetOne.add_actuator(1, CCW, 2); widgetOne.add_actuator(2, CW, 1);
widgetOne.add_encoder(1, CCW, 241, 10752, 2); widgetOne.add_encoder(2, CW, -61, 10752, 1);
widgetOne.device_set_parameters();
/* visual elements setup */ background(0); deviceOrigin.add(worldPixelWidth/2, 0);
/* create pantagraph graphics */ create_pantagraph();
target = createShape(ELLIPSE, 0,0, 20, 20); target.setStroke(color(0));
/* setup framerate speed */ frameRate(baseFrameRate); f = createFont("Arial",16,true); // STEP 2 Create Font
/* setup simulation thread to run at 1kHz */ thread("SimulationThread"); } /* end setup section ***************************************************************************************************/
public void RandomPosition(int theValue) {
xO = random(-0.3,0.3); yO = random(-0.3,0.3);
} public void ResetIntegrator(int theValue) { cumerrorx= 0; cumerrory= 0; } public void ResetDevice(int theValue) { widgetOne.device_set_parameters();
}
/* Keyboard inputs *****************************************************************************************************/
/// Antoine: this is specific to qwerty keyboard layout, you may want to adapt
void keyPressed() { if (key == 'q') { P += 0.005; } else if (key == 'a') { P -= 0.005; } else if (key == 'w') { I += 0.00001; } else if (key == 's') { I -= 0.00001; } else if (key == 'e') { D += 0.1; } else if (key == 'd') { D -= 0.1; } else if (key == 'r') { looptime += 100; } else if (key == 'f') { looptime -= 100; } else if (key == 't') { smoothing += 0.01; } else if (key == 'g') { smoothing -= 0.01; } else if (key == ' ') { cumerrorx= 0; cumerrory= 0; } else if (key == 'i') { widgetOne.device_set_parameters(); } else if (key == 'b') { xr = random(-0.5,0.5); yr = random(-0.5,0.5); } }
/* draw section ********************************************************************************************************/ void draw(){ /* put graphical code here, runs repeatedly at defined framerate in setup, else default at 60fps: */ if(renderingForce == false){ background(255); update_animation(angles.x*radsPerDegree, angles.y*radsPerDegree, posEE.x, posEE.y);
} } /* end draw section ****************************************************************************************************/
int noforce = 0; long timetook = 0; long looptiming = 0;
/* simulation section **************************************************************************************************/ public void SimulationThread(){ while(1==1) { long starttime = System.nanoTime(); long timesincelastloop=starttime-timetaken; iter+= 1; // we check the loop is running at the desired speed (with 10% tolerance) if(timesincelastloop >= looptime*1000*1.1) { float freq = 1.0/timesincelastloop*1000000.0; println("caution, freq droped to: "+freq + " kHz"); } else if(iter >= 1000) { float freq = 1000.0/(starttime-looptiming)*1000000.0; println("loop running at " + freq + " kHz"); iter=0; looptiming=starttime; }
timetaken=starttime;
renderingForce = true;
if(haplyBoard.data_available()){ /* GET END-EFFECTOR STATE (TASK SPACE) */ widgetOne.device_read_data();
noforce = 0; angles.set(widgetOne.get_device_angles());
posEE.set(widgetOne.get_device_position(angles.array()));
posEE.set(device_to_graphics(posEE));
//m = (millis()-last); // if(millis() > last+20000){ // last = millis(); //}
//if (m <= 2000){ // xr = xO ; // yr = yO ; //}
//if (m > 2000 & m <= 8000){ // xr = xr + 0.0001 ; // yr = yr ; //}
//if (m > 8000 & m <= 11000){ // xr = xr ; // yr = yr - 0.00012; //}
//if (m > 11000 & m <= 17000){ // xr = xr - 0.0001 ; // yr = yr ; //}
//if (m > 17000){ // xr = xr ; // yr = yr + 0.00012; //}
x_m = xO*300 ; y_m = yO*300+350;
// Torques from difference in endeffector and setpoint, set gain, calculate force float xE = pixelsPerMeter * posEE.x; float yE = pixelsPerMeter * posEE.y; long timedif = System.nanoTime()-oldtime;
float dist_X = x_m-xE; cumerrorx += dist_X*timedif*0.000000001; float dist_Y = y_m-yE; cumerrory += dist_Y*timedif*0.000000001; //println(dist_Y*k + " " +dist_Y*k); // println(timedif); if(timedif > 0) { buffx = (dist_X-oldex)/timedif*1000*1000; buffy = (dist_Y-oldey)/timedif*1000*1000;
diffx = smoothing*diffx + (1.0-smoothing)*buffx; diffy = smoothing*diffy + (1.0-smoothing)*buffy; oldex = dist_X; oldey = dist_Y; oldtime=System.nanoTime(); }
// Forces are constrained to avoid moving too fast
fEE.x = constrain(P*dist_X,-4,4) + constrain(I*cumerrorx,-4,4) + constrain(D*diffx,-8,8);
fEE.y = constrain(P*dist_Y,-4,4) + constrain(I*cumerrory,-4,4) + constrain(D*diffy,-8,8);
if(noforce==1) { fEE.x=0.0; fEE.y=0.0; } widgetOne.set_device_torques(graphics_to_device(fEE).array()); //println(f_y); /* end haptic wall force calculation */
}
widgetOne.device_write_torques();
renderingForce = false; long timetook=System.nanoTime()-timetaken; if(timetook >= 1000000) { println("Caution, process loop took: " + timetook/1000000.0 + "ms"); } else { while(System.nanoTime()-starttime < looptime*1000) { //println("Waiting"); } }
} }
/* end simulation section **********************************************************************************************/
/* helper functions section, place helper functions here ***************************************************************/ void create_pantagraph(){ float lAni = pixelsPerMeter * l; float LAni = pixelsPerMeter * L; float rEEAni = pixelsPerMeter * rEE;
pGraph = createShape(); pGraph.beginShape(); pGraph.fill(255); pGraph.stroke(0); pGraph.strokeWeight(2);
pGraph.vertex(deviceOrigin.x, deviceOrigin.y); pGraph.vertex(deviceOrigin.x, deviceOrigin.y); pGraph.vertex(deviceOrigin.x, deviceOrigin.y); pGraph.vertex(deviceOrigin.x, deviceOrigin.y); pGraph.endShape(CLOSE);
joint = createShape(ELLIPSE, deviceOrigin.x, deviceOrigin.y, rEEAni, rEEAni); joint.setStroke(color(0));
endEffector = createShape(ELLIPSE, deviceOrigin.x, deviceOrigin.y, 2*rEEAni, 2*rEEAni); endEffector.setStroke(color(0,0,255)); strokeWeight(5);
}
PShape create_wall(float x1, float y1, float x2, float y2){ x1 = pixelsPerMeter * x1; y1 = pixelsPerMeter * y1; x2 = pixelsPerMeter * x2; y2 = pixelsPerMeter * y2;
return createShape(LINE, deviceOrigin.x + x1, deviceOrigin.y + y1, deviceOrigin.x + x2, deviceOrigin.y+y2); }
void update_animation(float th1, float th2, float xE, float yE){ background(255); pushMatrix(); float lAni = pixelsPerMeter * l; float LAni = pixelsPerMeter * L;
xE = pixelsPerMeter * xE; yE = pixelsPerMeter * yE;
th1 = 3.14 - th1; th2 = 3.14 - th2;
pGraph.setVertex(1, deviceOrigin.x + lAni*cos(th1), deviceOrigin.y + lAni*sin(th1)); pGraph.setVertex(3, deviceOrigin.x + lAni*cos(th2), deviceOrigin.y + lAni*sin(th2)); pGraph.setVertex(2, deviceOrigin.x + xE, deviceOrigin.y + yE);
shape(pGraph); shape(joint); float[] coord;
translate(xE, yE); shape(endEffector); popMatrix(); arrow(xE,yE,fEE.x,fEE.y); textFont(f,16); // STEP 3 Specify font to be used fill(0); // STEP 4 Specify font color
x_m = xO*300+500; y_m = yO*300+350;//mouseY; pushMatrix(); translate(x_m, y_m); shape(target); popMatrix();
}
PVector device_to_graphics(PVector deviceFrame){ return deviceFrame.set(-deviceFrame.x, deviceFrame.y); }
PVector graphics_to_device(PVector graphicsFrame){ return graphicsFrame.set(-graphicsFrame.x, graphicsFrame.y); }
void arrow(float x1, float y1, float x2, float y2) { x2=x2*10.0; y2=y2*10.0; x1=x1+500; x2=-x2+x1; y2=y2+y1;
line(x1, y1, x2, y2); pushMatrix(); translate(x2, y2); float a = atan2(x1-x2, y2-y1); rotate(a); line(0, 0, -10, -10); line(0, 0, 10, -10); popMatrix(); }
/* end helper functions section ****************************************************************************************/
PANTOGRAPH
/** ********************************************************************************************************************** * @file Pantograph.java * @author Steve Ding, Colin Gallacher * @version V3.0.0 * @date 15-January-2021 * @brief Mechanism extension example ********************************************************************************************************************** * @attention * * ********************************************************************************************************************** */
import static java.lang.Math.*;
public class Pantograph extends Mechanisms{
private float l, L, d; private float th1, th2; private float tau1, tau2; private float f_x, f_y; private float x_E, y_E; private float pi = 3.14159265359f; private float JT11, JT12, JT21, JT22; private float gain = 1.0f;
public Pantograph(){ this.l = 0.07f; this.L = 0.09f; this.d = 0.0f; } public void torqueCalculation(float[] force){ f_x = force[0]; f_y = force[1];
tau1 = JT11*f_x + JT12*f_y; tau2 = JT21*f_x + JT22*f_y; tau1 = tau1*gain; tau2 = tau2*gain; } public void forwardKinematics(float[] angles){ float l1 = l; float l2 = l; float L1 = L; float L2 = L;
th1 = pi/180*angles[0]; th2 = pi/180*angles[1];
// Forward Kinematics float c1 = (float)cos(th1); float c2 = (float)cos(th2); float s1 = (float)sin(th1); float s2 = (float)sin(th2); float xA = l1*c1; float yA = l1*s1; float xB = d+l2*c2;
float yB = l2*s2; float hx = xB-xA; float hy = yB-yA; float hh = (float) pow(hx,2) + (float) pow(hy,2); float hm = (float)sqrt(hh); float cB = - ((float) pow(L2,2) - (float) pow(L1,2) - hh) / (2*L1*hm);
float h1x = L1*cB * hx/hm; float h1y = L1*cB * hy/hm; float h1h1 = (float) pow(h1x,2) + (float) pow(h1y,2); float h1m = (float) sqrt(h1h1); float sB = (float) sqrt(1-pow(cB,2));
float lx = -L1*sB*h1y/h1m; float ly = L1*sB*h1x/h1m;
float x_P = xA + h1x + lx; float y_P = yA + h1y + ly;
float phi1 = (float)acos((x_P-l1*c1)/L1); float phi2 = (float)acos((x_P-d-l2*c2)/L2);
float c11 = (float) cos(phi1); float s11 =(float) sin(phi1); float c22= (float) cos(phi2); float s22 = (float) sin(phi2);
float dn = L1 *(c11 * s22 - c22 * s11); float eta = (-L1 * c11 * s22 + L1 * c22 * s11 - c1 * l1 * s22 + c22 * l1 * s1) / dn; float nu = l2 * (c2 * s22 - c22 * s2)/dn;
JT11 = -L1 * eta * s11 - L1 * s11 - l1 * s1; JT12 = L1 * c11 * eta + L1 * c11 + c1 * l1; JT21 = -L1 * s11 * nu; JT22 = L1 * c11 * nu;
x_E = x_P; y_E = y_P; } public void forceCalculation(){ } public void positionControl(){ } public void inverseKinematics(){ } public void set_mechanism_parameters(float[] parameters){ this.l = parameters[0]; this.L = parameters[1]; this.d = parameters[2]; } public void set_sensor_data(float[] data){ } public float[] get_coordinate(){ float temp[] = {x_E, y_E}; return temp; } public float[] get_torque(){ float temp[] = {tau1, tau2}; return temp; } public float[] get_angle(){ float temp[] = {th1, th2}; return temp; }
}
0 notes
Video
tumblr
Processing Development
This development output was quite fun to make. I found an example on the Processing website, and then stripped it back, then added to it. This created the bounding ball effect. I then added in different shapes. However this design used PVectors, which Im still not 100% sure what this does so decided agains using it. One thing I do like is how the size of the shapes changed depending on where the mouse is positioned. again, I added in text and a whenPressed code to change the colour of the background.
int col = 0; PVector location; // Location of shape PVector velocity; // Velocity of shape PVector gravity; // Gravity acts at the shape's acceleration PVector location1; // Location of shape PVector velocity1; // Velocity of shape PVector gravity1; // Gravity acts at the shape's acceleration PVector location2; // Location of shape PVector velocity2; // Velocity of shape PVector gravity2; // Gravity acts at the shape's acceleration PVector location3; // Location of shape PVector velocity3; // Velocity of shape PVector gravity3; // Gravity acts at the shape's acceleration
void setup() { //size(800,600); fullScreen(); location = new PVector(0,0); velocity = new PVector(1,5); gravity = new PVector(0,1);
location1= new PVector(1,5); velocity1 = new PVector(10,10); gravity1 = new PVector(0,1);
location2= new PVector(60,60); velocity2 = new PVector(23,23); gravity2 = new PVector(0,1);
location3= new PVector(60,60); velocity3 = new PVector(23,23); gravity3 = new PVector(0,1);
colorMode(HSB); noCursor(); frameRate(120);
}
void draw() {
background(col%255,128,255);
// TEXT fill(255,191); PFont font; font = loadFont("Gilroy-Regular-48.vlw"); textFont(font, 32); textAlign(CENTER, CENTER); text("CLICK TO CHANGE COLOUR",width/2, height/2);
// moves shape location.add(velocity); location1.add(velocity1); location2.add(velocity2); location3.add(velocity3);
// limits to top of screen velocity.add(gravity); velocity1.add(gravity1); velocity2.add(gravity2); velocity3.add(gravity3);
// Limits to side of screen if ((location.x > width) || (location.x < 0)) { velocity.x = velocity.x * -1;} if ((location1.x > width) || (location1.x < 0)) { velocity1.x = velocity1.x * -1;} if ((location2.x > width) || (location2.x < 0)) { velocity2.x = velocity2.x * -1;} if ((location3.x > width) || (location3.x < 0)) { velocity3.x = velocity3.x * -1;}
// limits fall to bottom of screen if (location.y > height) { velocity.y = velocity.y * -0.99; location.y = height;} if (location1.y > height) { velocity1.y = velocity1.y * -0.99; location1.y = height;} if (location2.y > height) { velocity2.y = velocity.y * -0.99; location2.y = height;} if (location3.y > height) { velocity3.y = velocity3.y * -0.99; location3.y = height;}
noStroke(); fill(255,127); ellipse(location.x,location.y,mouseX/2,mouseX/2); rect(location1.x,location1.y,mouseX/3,mouseX/3, 20); ellipse(location2.x,location2.y,75,75); //yuck bounce rect(location3.x,location3.y,mouseX/3,mouseX/3, 20);
}
//Change Colour void mousePressed(){col+=15;}
0 notes
Text
Five Quick Tips For Panint | Panint
These attending like action prototypes and implementations. Is that your intent?
If so, it looks accept to me. I anticipate your affair is advancing from your main(). Booty addition attending at the aboriginal line: *pVector(); What does this band do? It absolutely doesn’t do annihilation useful. The botheration is that you are attempting to, able-bodied I’m not abiding what you’re aggravating to do. As far as I know, this isn’t alike accurate syntax.
Anticipate a little added carefully about how variables and pointers work. You charge to accommodate a dataType, an Identifier, and (optionally) an initialization value:
Your acknowledgment in main() is missing the dataType, and additionally is formatted added like a action call. You could do article like this:
But not what you’ve done. You didn’t complete the statement.
0 0
Edited 8 Years Ago by
Five Quick Tips For Panint | Panint – panint | Welcome to my personal website, in this occasion I am going to demonstrate about keyword. And today, this is the 1st impression:

Panint Stories – Wattpad – panint | panint
What about picture over? can be that remarkable???. if you think so, I’l l provide you with many impression all over again below:
So, if you like to receive all these outstanding shots regarding (Five Quick Tips For Panint | Panint), click on save button to store the pics to your personal computer. There’re available for down load, if you’d rather and want to obtain it, click save badge in the web page, and it’ll be directly downloaded to your home computer.} Finally if you wish to grab new and latest picture related with (Five Quick Tips For Panint | Panint), please follow us on google plus or bookmark this page, we attempt our best to present you regular update with all new and fresh shots. Hope you love keeping right here. For most updates and recent news about (Five Quick Tips For Panint | Panint) images, please kindly follow us on tweets, path, Instagram and google plus, or you mark this page on bookmark section, We attempt to offer you update regularly with fresh and new shots, like your browsing, and find the perfect for you.
Thanks for visiting our site, contentabove (Five Quick Tips For Panint | Panint) published . Today we’re delighted to declare we have found an awfullyinteresting nicheto be reviewed, that is (Five Quick Tips For Panint | Panint) Lots of people attempting to find details about(Five Quick Tips For Panint | Panint) and certainly one of them is you, is not it?

Panint #18 картинки, Фотографии и изображения – 1823RF – panint | panint

*Ac*New panint *New Test *All chrome acesaries*New tyre*new seat cover – panint | panint

Panint Jhonlerkieat on Twitter: “#asniworkshop #aimstar .. | panint

diy panINT TABLE TOP – Google Search | Arts and crafts .. | panint

Vintage primitive side table in Miss Mustard Seed Milk Paint with folk art bird design – panint | panint

panint hashtag on Twitter – panint | panint
Surface SEM micrograph of the nanostructured PANINT´s based PGLD .. | panint

panint hashtag on Twitter – panint | panint
The pattern of the PANINT–IL/chitosan/AuNP SPE and the structure .. | panint

Оклеивания Авто С Эффектом Хромирования Пленка Виниловые Наклейки На Авто Кузова Panint Защита Наклейка – Buy Автомобильная Упаковка,Виниловая Пленка .. | panint

Panint – panint | panint

diy panINT TABLE TOP TRIPPY – Google Search | Upcycle diy .. | panint

paint-mixing-cups – Tyre Changers|Spray Paint Booth .. | panint

Panint Manufacturing – Electrical, Electronic & Consumer .. | panint

Vintage primitive side table in Miss Mustard Seed Milk Paint with folk art bird design – panint | panint

Galon Kwok – panint | panint

Panint | Naruto | Pinterest | Naruto, Anime and Naruto uzumaki – panint | panint
from WordPress https://www.bleumultimedia.com/five-quick-tips-for-panint-panint/
0 notes
Photo
PVector Mandala animation using floating points
0 notes
Text
More processing rain
To simulate the experience of a storm outside from behind a window, a big part of that is the rain on the glass. We’ve already got a simple ‘rain droplet’ sketch that just generates circles randomly that then fade away. Another key visual element is the trails of rain running down the window, and I have started trying to simulate this in processing.

I started working on a way to simulate rain trails moving down a window. I started by just having drops create trails as the move downward, and set up 10 to move from the same spot. The squares left on the tail are dropped every time the rotation of the downwards velocity is adjusted, and lines are drawn between them.
This sketch uses PVectors and slight rotations every half second, and adds trail points into an array. The size and frequencies of rotation, speed and placement need to be randomized, and the droplets need to have a proper display that makes them look more realistic. This is the code for the first rain drop, with some brief comments describing each section.
I also want to add collisions between them, so that droplets can run into each other and have some realistic interactions. Below is a rough test for some droplet interactions; when a droplet touches another path it stops moving and the velocity of the collided drop increases. In this version that just results in the drop moving straight downwards because of the velocity limit.
3 notes
·
View notes
Text
Grid Balls
float massMax = 2000.0;
Grid grid;
Particles universe;
void setup() {
size(1558,743);
grid = new Grid(64);
frameRate(60);
universe = new Particles(100);
colorMode(HSB, 100, 255, 255, 255);
Particle p;
for(int i=0; i < universe.numberOfParticles(); i++) {
p = universe.particleAt(i);
p.position.x = random(width);
p.position.y = random(height);
p.velocity.x = random(2) - random(2);
p.velocity.y = random(2) - random(2);
p.mass = random(2000.0)
p.volume = p.mass / 40;
}
background(255);
}
void draw() {
background(0);
grid.update();
grid.draw();
colorMode(HSB, 100, 255, 255, 255);
universe.update();
universe.draw();
}
class Cell {
void draw(float x, float y, int cellSize) {
}
void update(float x, float y, Cell[][] cells) {
}
}
class Grid {
boolean drawCellBorder = true;
int gridWidth, gridHeight;
int cellSize;
Cell[][] cells;
Grid(int size) {
cellSize = floor(2 * height / (size + 4));
gridHeight = size;
gridWidth = floor(width / (cellSize * 1.5));
cells = new Cell[gridWidth][gridHeight];
for(int x=0; x < gridWidth; x++) {
for(int y=0; y < gridHeight; y++) {
cells[x][y] = null;
}
}
}
void draw() {
for(int x=0; x < gridWidth; x++) {
for(int y=0; y < gridHeight; y++) {
if(drawCellBorder) {
int dcellSize = cellSize;
int dX = x * dcellSize * 1.5;
int dY = y * (dcellSize/2);
if(y % 2 == 1) {
dX += dcellSize - dcellSize/4;
}
dX += dcellSize/2;
dY += dcellSize;
float massWithin = universe.massWithin(dX, dY, cellSize);
colorMode(RGB);
strokeWeight(0.125);
strokeWeight(massWithin / massMax);
stroke(0, random(55) + 200, 0);
noFill();
beginShape();
vertex(dX-dcellSize/2, dY);
vertex(dX-dcellSize/4, dY-dcellSize/2);
vertex(dX+dcellSize/4, dY-dcellSize/2);
vertex(dX+dcellSize/2, dY);
vertex(dX+dcellSize/4, dY+dcellSize/2);
vertex(dX-dcellSize/4, dY+dcellSize/2);
endShape(CLOSE);
strokeWeight(0.125);
}
if(cells[x][y] != null) {
cells[x][y].draw(x, y, cellSize);
}
}
}
}
void update() {
for(int x=0; x < gridWidth; x++) {
for(int y=0; y < gridHeight; y++) {
if(cells[x][y] != null) {
cells[x][y].update(x, y, cells);
}
}
}
}
}
class Particles {
ArrayList particles;
ArrayList newParticles;
Particles(int numParticles) {
particles = new ArrayList();
newParticles = new ArrayList();
for(int i=0; i < numParticles; i++) {
particles.add(new Particle(random(width), random(height), this));
}
}
void update() {
Particle p;
int numParticles = numberOfParticles();
for(int i = numParticles - 1; i >= 0; i--) {
particleAt(i).updateVelocity(numParticles);
}
for(int i=0; i < newParticles.size(); i++) {
particles.add(newParticles.get(i));
newParticles.remove(i);
}
for(int i=numberOfParticles() - 1; i >= 0; i--) {
p = particleAt(i);
if(p.destroyed) {
particles.remove(i);
}
else {
p.updatePosition();
}
}
}
float massWithin(float x, float y, float distance) {
float mass = 0.0;
for(int i=0; i < numberOfParticles(); i++) {
Particle part = particleAt(i);
PVector pos = part.position;
if(abs(pos.x - x) < distance &&
abs(pos.y - y) < distance) {
mass += part.mass;
}
}
return mass;
}
void draw() {
for(int i=0; i < numberOfParticles(); i++) {
particleAt(i).drawPosition();
}
}
int numberOfParticles() {
return particles.size();
}
Particle particleAt(int i) {
return particles.get(i);
}
void addNewParticle(Particle p) {
newParticles.add(p);
}
}
int particleId = 0;
class Particle {
float GravitationalConstant = 0.000667384;
int myId;
float mass = 1;
float volume = 4;
float minVolume = 4;
float minDestructionForce = 4;
PVector acceleration;
PVector velocity;
PVector position;
Particles universe;
boolean destroyed;
color myColor;
Particle(float positionX, float positionY, Particles inUniverse) {
myId = ++particleId;
universe = inUniverse;
destroyed = false;
acceleration = new PVector(0,0);
velocity = new PVector(0,0);
position = new PVector(positionX, positionY);
myColor = color(myId, 255, 255, 200);
}
int getId() {
return myId;
}
void updateVelocity(int numParticles) {
acceleration.x = acceleration.y = 0;
for(int i=numParticles - 1; i >= 0; i--) {
Particle other = universe.particleAt(i);
if(other.getId() != myId) {
float diffX = other.position.x - position.x;
float diffY = other.position.y - position.y;
float distance = PVector.dist(position, other.position);
PVector attraction = new PVector(diffX, diffY);
attraction.normalize();
if(distance >= (other.volume/2 + volume/2)) {
attraction.mult((mass * other.mass) / sq(distance));
attraction.mult(GravitationalConstant);
acceleration.add(attraction);
}
else {
hitOtherParticle(other);
}
}
}
acceleration.div(mass);
velocity.add(acceleration);
velocity.limit(20);
}
void splitParticle(float numPieces,
PVector collisionVelocity,
Particle other) {
Particle p;
destroyed = true;
collisionVelocity.div(numPieces);
volume = volume / numPieces;
mass = mass / numPieces;
for(int i=0; i < numPieces; i++) {
p = new Particle(position.x, position.y, universe);
p.mass = mass;
p.volume = volume;
p.velocity.x = sin(TWO_PI - random(2*TWO_PI));
p.velocity.y = cos(TWO_PI - random(2*TWO_PI));
p.velocity.normalize();
p.velocity.mult(collisionVelocity.mag());
p.velocity.limit(20);
universe.addNewParticle(p);
}
}
void hitOtherParticle(Particle other) {
if(volume <= minVolume || mass < 4) {
destroyed = true;
}
else {
PVector collisionVelocity = PVector.sub(velocity, other.velocity);
float collisionMagnitude = collisionVelocity.mag();
float force = collisionMagnitude * mass;
float otherForce = collisionMagnitude * other.mass;
if(collisionMagnitude > 0) {
acceleration.sub(collisionVelocity);
}
else {
float tx, ty;
tx = velocity.x;
ty = velocity.y;
velocity.x = other.velocity.x;
velocity.y = other.velocity.y;
other.velocity.y = ty;
other.velocity.x = tx;
}
}
}
void updatePosition() {
position.add(velocity);
if(position.x < 0) {
position.x = width;
}
else if(position.x > width) {
position.x = 0;
}
if(position.y < 0) {
position.y = height;
}
else if(position.y > height) {
position.y = 0;
}
}
void drawPosition() {
stroke(myId, 255, 255, 127);
strokeWeight(volume);
point(position.x, position.y);
}
}
0 notes
Photo
Processing 3
import peasy.*; PeasyCam cam; Attractor att, att2, att3; void setup() { size(540, 540, P3D); // ortho(-width/2, width/2, -height/2, height/2); cam = new PeasyCam(this, 500); att = new Attractor(0.01, 0.0, 0.0, 0.01); //x, y, z, dt att2 = new Attractor(0.1, 0.0, 0.0, 0.01); att3 = new Attractor(0.1, 0.0, 0.0, 0.05); } void draw() { background(0); att.lorenz(10, 28, 8.0/3.0); //param a, b, c att.point_draw(0, 135, -80, 2); //x_position, ypos, zpos, *scale att.line_draw(0, -135, -80, 2); att2.aizawa(0.95, 0.7, 0.6, 3.5, 0.25, 0.1); //param a, b, c, d, e, f att2.line_draw(-135, 0, -80, 40); att3.thomas(0.19); //param b att3.line_draw(135, 0, -80, 14); } class Attractor { float x, y, z; float dt; ArrayList<PVector> points; Attractor(float _x, float _y, float _z, float _dt) { x = _x; y = _y; z = _z; dt = _dt; points = new ArrayList<PVector>(); } void lorenz(float _a, float _b,float _c) { float a = _a; float b = _b; float c = _c; float dx = (a*(y - x))*dt; float dy = (x*(b - z) - y)*dt; float dz = (x*y - c*z)*dt; x = x + dx; y = y + dy; z = z + dz; } void aizawa(float _a, float _b,float _c, float _d,float _e, float _f) { float a = _a; float b = _b; float c = _c; float d = _d; float e = _e; float f = _f; for (int i = 0; i < 3; i = i+1) { float dx = ((z - b)*x - d*y)*dt; float dy = (d*x + (z - b)*y)*dt; float dz = (c + a*z - (pow(z,3)/3) - (pow(x,2) + pow(y,2))*(1 + e*z)+f*z*pow(x,3))*dt; x = x + dx; y = y + dy; z = z + dz; } } void thomas(float _b) { float b = _b; for (int i = 0; i < 3; i = i+1) { float dx = (-b*x + sin(y))*dt; float dy = (-b*y + sin(z))*dt; float dz = (-b*z + sin(x))*dt; x = x + dx; y = y + dy; z = z + dz; } } void line_draw(float _xpos, float _ypos, float _zpos, float _size) { points.add(new PVector(x*_size, y*_size, z*_size)); pushMatrix(); translate(_xpos, _ypos, _zpos); stroke(255); strokeWeight(2); noFill(); beginShape(); for (PVector v : points) { stroke(255, 50); vertex(v.x, v.y, v.z); } endShape(); popMatrix(); } void point_draw(float _xpos, float _ypos, float _zpos, float _scale) { points.add(new PVector(x*_scale, y*_scale, z*_scale)); pushMatrix(); translate(_xpos, _ypos, _zpos); stroke(255); strokeWeight(1); noFill(); for (PVector v : points) { stroke(255, random(196)); point(v.x, v.y, v.z); } popMatrix(); } }
<>が消える
109 notes
·
View notes
Video
tumblr
Final Processing Design: “Bubblegum”
The experience I wanted to give the viewer as they interacted with this scene was a sort of ‘underwater fun’ feeling, mimicking the bubbles and the constant movement of water. I hoped that the movement created from the spawned particles would emphasise the underwater aspect, also making it full screen for a more immersive feel. Initially, I removed the line of code that said if the mouse was released the bubbles would stop. However, I wanted to give the viewer more creative liberty so I added that line back in. To add a little bit of excitement, I also randomised the background colour so that whenever the stage was cleared a random colour (with the same colour range as the bubbles) would fill the screen. This produced a different outcome with each click because some of the bubbles’ visibility would be affected.
How it works / changes made:
made full screen so viewer would feel more immersed and less distracted: fullScreen();
Changed the frame rate to be higher so bubbles would appear to be spawned smoother: frameRate(180);
Added title and instructions at the beginning so user would know how to interact: text("'BUBBLEGUM'" + "\n" + "Drag and draw." + "\n" + "Press 'c' to clear the stage." + "\n" , width*0.5, height*0.5);
Added rule that if mouse was released the bubbles would stop spawning: kept void mouseReleased() { onPressed = false; }
randomised background colour when key is pressed so that user is tempted to keep playing: background(color(random(20),random(255),255));
Particle Components:
Particle: float randDegrees = random(360); vel = new PVector(cos(radians(randDegrees)), sin(radians(randDegrees))); vel.mult(random(3000)); acc = new PVector(0,100); lifeSpan = int(random(05, 180)); decay = random(0.1, 0.7); c = color(random(0),random(240),255); weightRange = random(10, 400);
Variables that affect outcome:
where the user clicks and drags determines the shape
how long they play for affects how filled up the canvas is
how fast they move the mouse effects the spacing between the bubbles spawned
the background randomised background colour affects the visibility of some colours
Things to consider:
During presentation, when stage was cleared the instructions would show with the new background. It may be better to display instructions each time if we were to assume that more than one person would be playing with the design.
0 notes