We are about to switch to a new forum software. Until then we have removed the registration on this forum.
there was a Bazier Tool but it hasn't been updated in 5 years and you can't install it in P3. source is in github, maybe it can be updated. https://github.com/drifkin/bezier-editor-tool
alternatively, maybe Chrisir can make his code into a Tool.
Hello, I asked a very close question brillantly answered by @jeremydouglas few time ago, now I'd like to have a different duration for each text. In the sketch below the changePhraseTimer() works, but not the changePhraseTimerN(), we don't see the last text and it doesn't loop properly. Could someone help me with this issue please ?! Thanks a lot in advance. L
import generativedesign.*;
import geomerative.*;
// List of a list of points. 1rst the numbre of phrases: 4, the 2nd indicate the number of points
RPoint[][] myPoints = new RPoint[5][0];
RFont font;
PFont f;
Attractor attractor;
String [][] phraseSets = new String [4][0];
String [] FR1 = {
"On me dit de te haïr et je m'y efforce",
"Je t'imagine cruel, violent, implacable",
"Mais à te voir je n'ai bientôt plus de force",
"Et de te blesser je suis bien incapable",
};
String [] FR2 = {
"Tous mes camarades combattent avec rage",
"Et pleurent la nuit au souvenir des supplices",
"Infligés à leurs frères qui sont du même âge",
"Et rêvent comme eux de toucher une peau lisse"
};
String [] FR3 =
{"Et de pouvoir enfin caresser des obus",
"Autres que ceux produits par le pouvoir obtus",
"Je rêve de quitter ces boyaux infernaux"
};
String [] FR4 = {
"De laisser ces furieux des deux bords du Rhin",
"Et de pouvoir embrasser ta chute de rein",
"Et porter notre amour sur les fonts baptismaux"
};
//TEXT
final color textColor = color(245);
int fontSize;
// TIME
int startTime;
int initTime;
int lineSpacing;
int index;
int state;
float duration;
int dur1;
//----------------SETUP---------------------------------------------------------------------------------------
void setup() {
size(1920, 1080, JAVA2D);
//add phrases to list
phraseSets[0]=FR1;
phraseSets[1]=FR2;
phraseSets[2]=FR3;
phraseSets[3]=FR4;
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 86, CENTER);
stroke(textColor);
strokeWeight(0.05);
//INIT
drawPhrases(phraseSets[0]);
// TIME
startTime=millis();
initTime=millis();
index=0;
lineSpacing =150;
}
//----------------DRAW----------------------------------------------------------------------------------
void draw() {
background(255);
state =0;
// TEXTS
// draw on the center of the screen
translate(width/2, height/2);
// draw phrases vertically centered by moving the top up by half the line spaces
translate(0, -1.0*lineSpacing*(phraseSets[index].length-1)/2.0);
// loop through lines
for (int i=0; i< myPoints.length; i++) {
// draw a line
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
//bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
popMatrix();
}
// move to the next line
translate(0, lineSpacing);
}
//check Timer and redraw phrases if time has passed
changePhraseTimerN();
//changePhraseTimer(duration*4, phraseSets);
}
//----------------INITIALIZE----------------------------------------------------------------------------------------------------------------------------------------
void drawPhrases(String [] phrases) {
myPoints = new RPoint[phrases.length][0];
for (int j=0; j<phrases.length; j++) {
RGroup myGroup = font.toGroup(phrases[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
}
//----------------TIMER----------------------------------------------------------------------------------------------------------------------------------------
/*void changePhraseTimer( float duration, String [][] phraseSets) {
duration = sounds[0].length()-150;
if (millis()-startTime > duration*4) {
index =(index+1) % phraseSets.length;
//drawPhrases(phraseSets[index]);
//startTime = millis();
}
}*/
void changePhraseTimerN() {
dur1=11500;
if (millis()-startTime > dur1+1400) {
index =(index+1) % phraseSets[1].length;
drawPhrases(phraseSets[index]);
startTime= millis();
} else if (millis()-startTime > dur1-800) {
index =(index+1) % phraseSets[2].length;
drawPhrases(phraseSets[index]);
startTime= millis();
} else if (millis()-startTime > dur1+1000) {
index =(index+1) % phraseSets[3].length;
drawPhrases(phraseSets[index]);
startTime= millis();
} else if (millis()-startTime > dur1*2-8000) {
drawPhrases(phraseSets[0]);
startTime= millis();
}
}
//----------------TEXT ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
void initAttractor(int i) {
if (i>=4 && i<8) {
i-=4;
} else if (i>=8 && i<11) {
i-=8;
} else if (i>=11 && i<14) {
i-=11;
} else if (i>14) {
i=0;
}
float x = 0;
float y =-50;
// println(i);
attractor = new Attractor(x, y, myPoints[i]);
}
class Attractor {
float force_radious = 100;
float maxForce = 15;
RPoint position;
RPoint[] points;
Attractor(float x, float y, RPoint[] p) {
points = p;
position = new RPoint(x, y);
}
void attract() {
for (int i =0; i < points.length; i++) {
float d= points[i].dist(position);
// println ("d : "+d);
if (d < force_radious) {
RPoint desired = new RPoint(points[i]);
//points[i]= new RPoint(points[i]);
//println( "avant x : "+ points[i].x +" y: "+points[i].y);
desired.sub(position);
desired.normalize();
desired.scale(map(d, 0, force_radious, maxForce, 0));
points[i].add(desired);
//println( "après x : "+ points[i].x +" y: "+points[i].y);
}
}
}
void display () {
stroke(0);
strokeWeight(2);
// ellipse (position.x, position.y-750, 30, 30);
}
void moveTo(float x, float y){
position.x=x;
position.y=y;
}
}
Oups, thanks Chrisir, yes sorry I've corrected the indents and fix a bit the code :
import geomerative.*;
RPoint[][] myPoints = new RPoint[4][0];
RFont font;
String[][] phraseSets = new String[4][0];
String [] FR1 = { "On me dit de te haïr et je m'y efforce", "Je t'imagine cruel, violent, implacable", "Mais à te voir je n'ai bientôt plus de force", "Et de te blesser je suis bien incapable", };
String [] FR2 = { "Tous mes camarades combattent avec rage", "Et pleurent la nuit au souvenir des supplices", "Infligés à leurs frères qui sont du même âge", "et rêvent comme eux de toucher une peau lisse"};
String [] FR3 = { "Et de pouvoir enfin caresser des obus", "Autres que ceux produits par le pouvoir obtus", "Je rêve de quitter ces boyaux infernaux"};
String [] FR4 = { "De laisser ces furieux des deux bords du Rhin", "Et de pouvoir embrasser ta chute de rein", "Et porter notre amour sur les fonts baptismaux"};
final color textColor = color(245);
// TIME
int startTime;
int index;
int duration;
int linespacing;
int fontsize;
int state=0;
int dur1;
//----------------SETUP---------------------------------
void setup() {
size(900, 600, JAVA2D);
// add phrases to list
phraseSets[0] = FR1;
phraseSets[1] = FR2;
phraseSets[2] = FR3;
phraseSets[3] = FR4;
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 40, CENTER);
stroke(textColor);
strokeWeight(0.05);
drawPhrases(phraseSets[0]);
// TIME
startTime = millis();
index = 0;
// starting set of phrases
duration = 2000;
// timer length
linespacing = 100;
// space between phrase lines
}
//----------------DRAW---------------------------------
void draw() {
background(255);
// draw from the center of the screen
translate(width/2, height/2);
// vertically center text block by moving the top up by half the line spaces
translate(0, -1.0 * linespacing * (phraseSets[index].length-1)/2.0);
// loop through lines
for (int i=0; i< myPoints.length; i++) {
// draw a line
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
popMatrix();
}
// move to the next line
translate(0, linespacing);
}
// check timer, and redraw phrases if time has passed
// changePhraseTimer(duration, phraseSets);
changePhraseTimerALTER(dur1, phraseSets);
}
//----------------FUNCTIONS---------------------------------
/** * Timer will change phrases whenever to the next index * every time duration milliseconds passes. * Restarts itself by updating the global variable startTime. */
void changePhraseTimer(int duration, String[][] phraseSets) {
if (millis()-startTime > duration) {
index = (index+1) % phraseSets.length;
println(index);
startTime = millis();
drawPhrases(phraseSets[index]);
}
}
void changePhraseTimerALTER(float dur1, String [][] phraseSets) {
dur1 = 5000;
if (millis()-startTime > dur1) {
drawPhrases(phraseSets[1]);
}
if (millis()-startTime > dur1*2) {
drawPhrases(phraseSets[2]);
} else if (millis()-startTime > dur1*3) {
drawPhrases(phraseSets[3]);
} else if (millis()-startTime > dur1*4) {
drawPhrases(phraseSets[0]);
startTime = millis();
}
}
/** * Renders a String[] array as a geomerative RGroup * (PolygonGroup) of points, then stores the points in * the global RPoint[][] array myPoints. */
void drawPhrases(String[] phrases) {
myPoints = new RPoint[phrases.length][0];
for (int j=0; j<phrases.length; j++) {
RGroup myGroup = font.toGroup(phrases[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
}
//////////////////////////////////////////////
Hello @jeremydouglas, Pleasefind below a simple version of my latest code. I have two phraseTimer functions, one works well (phraseTimer()) the others doesn't work properly (phraseTimerALTER()), I don't find why ?! Could you please help me with this issue ? Thanks a lot in adavnce. Best wishes, L
import geomerative.*;
RPoint[][] myPoints = new RPoint[4][0];
RFont font;
String[][] phraseSets = new String[4][0];
String [] FR1 = { "On me dit de te haïr et je m'y efforce", "Je t'imagine cruel, violent, implacable", "Mais à te voir je n'ai bientôt plus de force", "Et de te blesser je suis bien incapable", };
String [] FR2 = { "Tous mes camarades combattent avec rage", "Et pleurent la nuit au souvenir des supplices", "Infligés à leurs frères qui sont du même âge", "et rêvent comme eux de toucher une peau lisse"};
String [] FR3 = { "Et de pouvoir enfin caresser des obus", "Autres que ceux produits par le pouvoir obtus", "Je rêve de quitter ces boyaux infernaux"};
String [] FR4 = { "De laisser ces furieux des deux bords du Rhin", "Et de pouvoir embrasser ta chute de rein", "Et porter notre amour sur les fonts baptismaux"};
final color textColor = color(245);
// TIME
int startTime;
int index;
int duration;
int linespacing;
int fontsize;
//----------------SETUP---------------------------------
void setup() {
size(900, 600, JAVA2D);
// add phrases to list
phraseSets[0] = FR1;
phraseSets[1] = FR2;
phraseSets[2] = FR3;
phraseSets[3] = FR4;
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 40, CENTER);
stroke(textColor);
strokeWeight(0.05);
drawPhrases(phraseSets[0]);
// TIME
startTime = millis();
index = 0;
// starting set of phrases
duration = 2000;
// timer length
linespacing = 100;
// space between phrase lines}
//----------------DRAW---------------------------------
void draw() {
background(255);
// draw from the center of the screen
translate(width/2, height/2);
// vertically center text block by moving the top up by half the line spaces
translate(0, -1.0 * linespacing * (phraseSets[index].length-1)/2.0);
// loop through lines
for (int i=0; i< myPoints.length; i++) {
// draw a line
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
popMatrix();
}
// move to the next line
translate(0, linespacing);
}
// check timer, and redraw phrases if time has passed
changePhraseTimer(duration, phraseSets);
changePhraseTimerALTER(dur1, phraseSets);
}
//----------------FUNCTIONS---------------------------------
/** * Timer will change phrases whenever to the next index * every time duration milliseconds passes. * Restarts itself by updating the global variable startTime. */
void changePhraseTimer(int duration, String[][] phraseSets) {
if (millis()-startTime > duration) {
index = (index+1) % phraseSets.length;
println(index);
startTime = millis();
drawPhrases(phraseSets[index]);
}
}
void changePhraseTimerALTER(float dur1, String [][] phraseSets) {
dur1 = 11200.;
if (millis()-startTime < dur1) {
state=0;
} else if (millis()-startTime < dur1*2-200.) {
state=1;
} else if (millis()-startTime < dur1*3-4500.) {
state=2;
} else if (millis()-startTime < dur1*4-9000.) {
state=3;
}
else {
state=0;
startTime = millis();
}
switch(state) {
case 0:
drawPhrases(phraseSets[0]);
break;
case 1:
drawPhrases(phraseSets[1]);
break;
case 2:
drawPhrases(phraseSets[2]);
break;
case 3:
drawPhrases(phraseSets[3]);
break;
}
}
/** * Renders a String[] array as a geomerative RGroup * (PolygonGroup) of points, then stores the points in * the global RPoint[][] array myPoints. */
void drawPhrases(String[] phrases) {
myPoints = new RPoint[phrases.length][0];
for (int j=0; j<phrases.length; j++) {
RGroup myGroup = font.toGroup(phrases[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoint();
}
}
//////////////////////////////////////////////
Dear Chrisir, In fact my problem is linked to the attarctor in my main sketch. I switch from a phrase to the other and the attractor for the lines works too but no the attractor linked to the words !? Don't find why... I tried to debug, but don't succeed. Here is the code: Thanks for your help... best, L
import generativedesign.*;
import geomerative.*;
import ddf.minim.analysis.*;
import ddf.minim.*;
// List of a list of points. 1rst the numbre of phrases: 4, the 2nd indicate the number of points
RPoint[][] myPoints = new RPoint[5][0];
RFont font;
PFont f;
Attractor attractor;
// Variables for lines
Attractor_Lines attractor_Lines;
int xCount=401;
int yCount=401;
float gridSizeX=1800;
float gridSizeY=1000;
Node [] myNodes;
float xPos, yPos;
String [][] phraseSets = new String [4][0];
String [] FR1 = {
"On me dit de te haïr et je m'y efforce",
"Je t'imagine cruel, violent, implacable",
"Mais à te voir je n'ai bientôt plus de force",
"Et de te blesser je suis bien incapable",
};
String [] FR2 = {
"Tous mes camarades combattent avec rage",
"Et pleurent la nuit au souvenir des supplices",
"Infligés à leurs frères qui sont du même âge",
"et rêvent comme eux de toucher une peau lisse"
};
String [] FR3 =
{"Et de pouvoir enfin caresser des obus",
"Autres que ceux produits par le pouvoir obtus",
"Je rêve de quitter ces boyaux infernaux"
};
String [] FR4 = {
"De laisser ces furieux des deux bords du Rhin",
"Et de pouvoir embrasser ta chute de rein",
"Et porter notre amour sur les fonts baptismaux"
};
//TEXT
final color textColor = color(245);
int fontSize;
//SOUND
Minim minim;
AudioPlayer[] sounds;
FFT fft;
float bandHeight;
float soundDuration ;
float soundDuration1 ;
String []fileNamesFR= {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
SoundManager sm;
// TIME
int startTime;
int initTime;
int lineSpacing;
int index;
int state;
float duration;
float dur1;
float dur2;
//----------------SETUP---------------------------------------------------------------------------------------
void setup() {
size(1920, 1080, JAVA2D);
//add phrases to list
phraseSets[0]=FR1;
phraseSets[1]=FR2;
phraseSets[2]=FR3;
phraseSets[3]=FR4;
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 86, CENTER);
stroke(textColor);
strokeWeight(0.05);
//INIT
drawPhrases(phraseSets[0]);
// LINES initiate attractor + attractors specs
myNodes = new Node [xCount*yCount];
initGrid();
attractor_Lines = new Attractor_Lines(0, 0);
attractor_Lines.strength=-160;
attractor_Lines.ramp = 0.85;
//SOUND
minim = new Minim(this);
sounds = new AudioPlayer[fileNamesFR.length];
for (int idx=0; idx<sounds.length; idx++) {
sounds[idx] = minim.loadFile(fileNamesFR[idx]+".wav", 2048);
fft = new FFT(sounds[idx].bufferSize(), sounds[idx].sampleRate());
}
soundDuration = 2000;
sm=new SoundManager(this);
//}
// TIME
startTime=millis();
initTime=millis();
index=0;
lineSpacing =150;
}
//----------------DRAW---------------------------------------------------------------------------------------------
void draw() {
background(255);
state =0;
//SOUNDS ANALYZIS
for (int idx=0; idx < sounds.length; idx++) {
fft.forward(sounds[idx].mix);
for (int i =0; i< fft.specSize(); i++) {
float bandDB = 10*log(fft.getBand(i)/fft.timeSize());
bandDB = constrain(bandDB, -1000, 1000);
bandHeight = map(bandDB*4, 0, -220, 0, height);
stroke(0);
//line(i, height, i, bandHeight-fft.getBand(i)*8);
}
}
// LINES
if (millis()-startTime > 0) {
for (int i = 0; i<myNodes.length; i=i+10) {
pushMatrix();
translate(myNodes[i].x, myNodes[i].y);
stroke(0, 100);
strokeWeight(0.01);
float noiseXRange = attractor_Lines.x/100.0;
float noiseYRange = attractor_Lines.y/1000.0;
float noiseX = map(myNodes[i].x, 0, xCount, 0, noiseXRange/5);
float noiseY = map(myNodes[i].y, 0, yCount, 0, noiseYRange/5);
float noiseValue = noise(noiseX, noiseY);
float angle = noiseValue*TWO_PI;
rotate(angle);
line(0, 0, 10, 10);
popMatrix();
}
}
// TEXTS
// draw on the center of the screen
translate(width/2, height/2);
// draw phrases vertically centered by moving the top up by half the line spaces
translate(0, -1.0*lineSpacing*(phraseSets[index].length-1)/2.0);
// loop through lines
for (int i=0; i< myPoints.length; i++) {
// draw a line
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
//bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
popMatrix();
}
// move to the next line
translate(0, lineSpacing);
}
//check Timer and redraw phrases if time has passed
changePhraseTimerN(dur1, phraseSets);
sm.update();
// changePhraseTimer(duration*4, phraseSets);
}
//----------------INITIALIZE----------------------------------------------------------------------------------------------------------------------------------------
void drawPhrases(String [] phrases) {
myPoints = new RPoint[phrases.length][0];
for (int j=0; j<phrases.length; j++) {
RGroup myGroup = font.toGroup(phrases[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
}
//----------------TIMER----------------------------------------------------------------------------------------------------------------------------------------
/*void changePhraseTimer( float duration, String [][] phraseSets) {
duration = sounds[0].length()-150;
if (millis()-startTime > duration*4) {
index =(index+1) % phraseSets.length;
drawPhrases(phraseSets[index]);
//startTime = millis();
}
}*/
void changePhraseTimerN(float dur1, String [][] phraseSets) {
dur1 = 11200.;
dur2=7000;
if (millis()-startTime < dur1) {
state=0;
} else if (millis()-startTime < dur1*2-200.) {
state=1;
} else if (millis()-startTime < dur1*3-4500.) {
state=2;
} else if (millis()-startTime < dur1*4-9500.) {
state=3;
} else {
state=0;
startTime = millis();
}
switch(state) {
case 0:
drawPhrases(phraseSets[0]);
//println(0);
index=0;
break;
case 1:
//drawPhrases(phraseSets[1]);
index = (index+1) % phraseSets.length;
println(index);
startTime = millis();
drawPhrases(phraseSets[index]);
// println(1);
break;
case 2:
drawPhrases(phraseSets[2]);
// println(2);
break;
case 3:
drawPhrases(phraseSets[3]);
// println(3);
break;
}
}
//----------------TEXT ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
void initAttractor(int i) {
if (i>=4 && i<8) {
i-=4;
} else if (i>=8 && i<11) {
i-=8;
} else if (i>=11 && i<14) {
i-=11;
} else if (i>14) {
i=0;
}
float x = 0;
float y =-50;
// println(i);
attractor = new Attractor(x, y, myPoints[i]);
}
//----------------LINES ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
void updateAttractorLines(float x, float y) {
attractor_Lines.x=x;
attractor_Lines.y=y;
}
//----------------LINES GRID INIT----------------------------------------------------------------------------------------------------------------------------------------
void initGrid() {
int i =0;
for (int x=0; x<xCount; x++) {
for (int y=0; y<yCount; y++) {
xPos = x*(gridSizeX /(xCount-1)) + (width-gridSizeX)/2;
yPos = y*(gridSizeY /(yCount-1)) + (height-gridSizeY)/2;
myNodes[i] = new Node(xPos, yPos);
myNodes[i]. setBoundary(0, 0, width, height);
myNodes[i].setDamping(0.9);
i++;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Attractor {
float force_radious = 100;
float maxForce = 15;
RPoint position;
RPoint[] points;
Attractor(float x, float y, RPoint[] p) {
points = p;
position = new RPoint(x, y);
}
void attract() {
for (int i =0; i < points.length; i++) {
float d= points[i].dist(position);
// println ("d : "+d);
if (d < force_radious) {
RPoint desired = new RPoint(points[i]);
//points[i]= new RPoint(points[i]);
//println( "avant x : "+ points[i].x +" y: "+points[i].y);
desired.sub(position);
desired.normalize();
desired.scale(map(d, 0, force_radious, maxForce, 0));
points[i].add(desired);
//println( "après x : "+ points[i].x +" y: "+points[i].y);
}
}
}
void display () {
stroke(0);
strokeWeight(2);
// ellipse (position.x, position.y-750, 30, 30);
}
void moveTo(float x, float y){
position.x=x;
position.y=y;
}
}
class Attractor_Lines {
float x=0, y=0;
float radius =110;
float strength= 0.55;
float ramp=0.05;
float theX;
float theY;
Attractor_Lines( float theX, float theY) {
x= theX;
y = theY;
}
void attract_Lines (Node theNode) {
float dx = x-theNode.x;
float dy = y-theNode.y;
float d= mag(dx, dy);
if ( d > 0 && d < radius) {
float s = pow(d/radius, 1/ramp);
float f = s*9*strength*50 * (1/(s+1)+((s-3)/4))/d;
theNode.velocity.x += dx*f;
theNode.velocity.y += dy*f;
}
}
}
////////////////////////////////////////////////////////////////
import ddf.minim.analysis.*;
import ddf.minim.*;
class SoundManager {
//SOUND
Minim minim;
AudioPlayer[] sounds;
FFT fft;
float bandHeight;
int currentSound;
String []fileNamesFR1= {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
float []linesYPositions ={300., 450., 600., 750., 300., 450., 600., 750., 450., 600., 750., 450., 600., 750.};
SoundManager(PApplet app) {
minim = new Minim(app);
currentSound =-1;
sounds = new AudioPlayer[fileNamesFR1.length];
for (int idx=0; idx<sounds.length; idx++) {
sounds[idx] = minim.loadFile(fileNamesFR1[idx]+".wav", 2048);
fft = new FFT(sounds[idx].bufferSize(), sounds[idx].sampleRate());
}
}
void update() {
// SOUND
if (currentSound ==-1) {
startPlaying();
} else if (!sounds[currentSound].isPlaying()) {
playNext();
} else {
fft.forward(sounds[currentSound].mix);
for (int i =0; i< fft.specSize(); i++) {
float bandDB = 10*log(fft.getBand(i)/fft.timeSize());
bandDB = constrain(bandDB, -1000, 1000);
bandHeight = map(bandDB*4, 0, -220, 0, height);
}
attractor.moveTo(map(sounds[currentSound].position(), 0, sounds[currentSound].length(), 0, width-100)-width/2, bandHeight/10-300);
attractor.attract();
updateAttractorLines( attractor_Lines.x = map(sounds[currentSound].position(), 0, sounds[currentSound].length(), 0, width-(100)/2), linesYPositions[currentSound]);
for (int j = 0; j<myNodes.length; j++) {
attractor_Lines.attract_Lines(myNodes[j]);
myNodes[j].update();
}
}
}
void startPlaying() {
currentSound=0;
playCurrentSound();
}
void playNext() {
currentSound++;
if (currentSound > sounds.length-1) {
currentSound=0;
drawPhrases(phraseSets[0]);
}
// fonction restartAnimation
//drawPhrases(phraseSets[0]);
playCurrentSound();
}
void playCurrentSound() {
sounds[currentSound].rewind();
sounds[currentSound].play();
initAttractor(currentSound);
}
}
with pleasure, here it is :
import geomerative.*;
RPoint[][] myPoints = new RPoint[4][0];
RFont font;
String[][] phraseSets = new String[4][0];
String [] FR1 = {
"On me dit de te haïr et je m'y efforce",
"Je t'imagine cruel, violent, implacable",
"Mais à te voir je n'ai bientôt plus de force",
"Et de te blesser je suis bien incapable",
};
String [] FR2 = {
"Tous mes camarades combattent avec rage",
"Et pleurent la nuit au souvenir des supplices",
"Infligés à leurs frères qui sont du même âge",
"et rêvent comme eux de toucher une peau lisse"
};
String [] FR3 = {
"Et de pouvoir enfin caresser des obus",
"Autres que ceux produits par le pouvoir obtus",
"Je rêve de quitter ces boyaux infernaux"
};
String [] FR4 = {
"De laisser ces furieux des deux bords du Rhin",
"Et de pouvoir embrasser ta chute de rein",
"Et porter notre amour sur les fonts baptismaux"
};
final color textColor = color(245);
// TIME
int startTime;
int index;
int duration;
int linespacing;
int fontsize;
float dur1;
float dur2;
int state;
//----------------SETUP---------------------------------
void setup() {
size(900, 600, JAVA2D);
// add phrases to list
phraseSets[0] = FR1;
phraseSets[1] = FR2;
phraseSets[2] = FR3;
phraseSets[3] = FR4;
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 40, CENTER);
stroke(textColor);
strokeWeight(0.05);
drawPhrases(phraseSets[0]);
// TIME
startTime = millis();
index = 0; // starting set of phrases
duration = 2000; // timer length
linespacing = 100; // space between phrase lines
}
//----------------DRAW---------------------------------
void draw() {
background(255);
// draw from the center of the screen
translate(width/2, height/2);
// vertically center text block by moving the top up by half the line spaces
translate(0, -1.0 * linespacing * (phraseSets[index].length-1)/2.0);
// loop through lines
for (int i=0; i< myPoints.length; i++) {
// draw a line
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
popMatrix();
}
// move to the next line
translate(0, linespacing);
}
// check timer, and redraw phrases if time has passed
changePhraseTimer(duration, phraseSets);
}
//----------------FUNCTIONS---------------------------------
/**
* Timer will change phrases whenever to the next index
* every time duration milliseconds passes.
* Restarts itself by updating the global variable startTime.
*/
void changePhraseTimer(int dur1, String[][] phraseSets) {
dur1 = 3000;
dur2=6000;
if (millis()-startTime < dur1) {
state=0;
} else if (millis()-startTime < dur1*2) {
state=1;
} else if (millis()-startTime < dur1*3) {
state=2;
} else if (millis()-startTime < dur1*4) {
state=3;
} else {
state=0;
startTime = millis();
}
switch(state) {
case 0:
drawPhrases(phraseSets[0]);
break;
case 1:
drawPhrases(phraseSets[1]);
break;
case 2:
drawPhrases(phraseSets[2]);
break;
case 3:
drawPhrases(phraseSets[3]);
break;
}
}
/**
* Renders a String[] array as a geomerative RGroup
* (PolygonGroup) of points, then stores the points in
* the global RPoint[][] array myPoints.
*/
void drawPhrases(String[] phrases) {
myPoints = new RPoint[phrases.length][0];
for (int j=0; j<phrases.length; j++) {
RGroup myGroup = font.toGroup(phrases[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
}
It somehow works but not as I wish! Thanks for your answer.
L
Look at this cleaned up code for comparison. It is your sketch with minor changes: it uses a set of sets of strings rather than referring to them manually -- this means you can just add more sets of phrases without needing to update the code, and it will just work. Phrases can be any number of lines, 2 lines or 10. There are two functions -- a timer, and a drawing function that renders the phrase strings to RPoints.
import geomerative.*;
RPoint[][] myPoints = new RPoint[4][0];
RFont font;
String[][] phraseSets = new String[4][0];
String [] FR1 = {
"On me dit de te haïr et je m'y efforce",
"Je t'imagine cruel, violent, implacable",
"Mais à te voir je n'ai bientôt plus de force",
"Et de te blesser je suis bien incapable",
};
String [] FR2 = {
"Tous mes camarades combattent avec rage",
"Et pleurent la nuit au souvenir des supplices",
"Infligés à leurs frères qui sont du même âge",
"et rêvent comme eux de toucher une peau lisse"
};
String [] FR3 = {
"Et de pouvoir enfin caresser des obus",
"Autres que ceux produits par le pouvoir obtus",
"Je rêve de quitter ces boyaux infernaux"
};
String [] FR4 = {
"De laisser ces furieux des deux bords du Rhin",
"Et de pouvoir embrasser ta chute de rein",
"Et porter notre amour sur les fonts baptismaux"
};
final color textColor = color(245);
// TIME
int startTime;
int index;
int duration;
int linespacing;
int fontsize;
//----------------SETUP---------------------------------
void setup() {
size(900, 600, JAVA2D);
// add phrases to list
phraseSets[0] = FR1;
phraseSets[1] = FR2;
phraseSets[2] = FR3;
phraseSets[3] = FR4;
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 40, CENTER);
stroke(textColor);
strokeWeight(0.05);
drawPhrases(phraseSets[0]);
// TIME
startTime = millis();
index = 0; // starting set of phrases
duration = 2000; // timer length
linespacing = 100; // space between phrase lines
}
//----------------DRAW---------------------------------
void draw() {
background(255);
// draw from the center of the screen
translate(width/2, height/2);
// vertically center text block by moving the top up by half the line spaces
translate(0, -1.0 * linespacing * (phraseSets[index].length-1)/2.0);
// loop through lines
for (int i=0; i< myPoints.length; i++) {
// draw a line
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
popMatrix();
}
// move to the next line
translate(0, linespacing);
}
// check timer, and redraw phrases if time has passed
changePhraseTimer(duration, phraseSets);
}
//----------------FUNCTIONS---------------------------------
/**
* Timer will change phrases whenever to the next index
* every time duration milliseconds passes.
* Restarts itself by updating the global variable startTime.
*/
void changePhraseTimer(int duration, String[][] phraseSets) {
if (millis()-startTime > duration) {
index = (index+1) % phraseSets.length;
println(index);
startTime = millis();
drawPhrases(phraseSets[index]);
}
}
/**
* Renders a String[] array as a geomerative RGroup
* (PolygonGroup) of points, then stores the points in
* the global RPoint[][] array myPoints.
*/
void drawPhrases(String[] phrases) {
myPoints = new RPoint[phrases.length][0];
for (int j=0; j<phrases.length; j++) {
RGroup myGroup = font.toGroup(phrases[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
}
//////////////////////////////////////////////
Hi, I have an issue with Geomerative. I'd like to switch from text to text using this library according to a time schedule. It works but when switching to a shorter text I still see the previous text! How can I switch properly from a text to another?! Thanks a lot in advance for your help. Best, L
import geomerative.*;
// Liste de liste de points. La 1ère correspond au nombre de phrases, ici 4, la 2ème correspond au nom total de points par phrase
RPoint[][] myPoints = new RPoint[4][0];
RFont font;
String [] FR1 = {
"On me dit de te haïr et je m'y efforce",
"Je t'imagine cruel, violent, implacable",
"Mais à te voir je n'ai bientôt plus de force",
"Et de te blesser je suis bien incapable",
};
String [] FR2 = {
"Tous mes camarades combattent avec rage",
"Et pleurent la nuit au souvenir des supplices",
"Infligés à leurs frères qui sont du même âge",
"et rêvent comme eux de toucher une peau lisse"
};
String [] FR3 = {
"Et de pouvoir enfin caresser des obus",
"Autres que ceux produits par le pouvoir obtus",
"Je rêve de quitter ces boyaux infernaux"
};
String [] FR4 = {
"De laisser ces furieux des deux bords du Rhin",
"Et de pouvoir embrasser ta chute de rein",
"Et porter notre amour sur les fonts baptismaux"
};
final color textColor = color(245);
// TIME
int startTime;
//----------------SETUP---------------------------------
void setup() {
size(1920, 1080, JAVA2D);
smooth();
RG.init(this);
font = new RFont("FreeSans.ttf", 86, CENTER);
stroke(textColor);
strokeWeight(0.05);
//INIT
initAll();
changePhrases(0);
changePhrases(1);
changePhrases(2);
changePhrases(3);
// TIME
startTime=millis();
}
//----------------DRAW---------------------------------
void draw() {
background(255);
translate(width/2, height/1.5);
for (int i=0; i< myPoints.length; i++) {
for (int j=0; j< myPoints[i].length-1; j++) {
pushMatrix();
translate(myPoints[i][j].x, myPoints[i][j].y-420+i*180);
noFill();
stroke(0, 200);
strokeWeight(0.25);
float angle = TWO_PI*10;
rotate(j/angle);
bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
//bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
popMatrix();
}
}
if (millis()-startTime > 0 && millis()-startTime < 3000) {
changePhrases(0);
}
if (millis()-startTime > 3000 && millis()-startTime < 6000) {
changePhrases(1);
}
if (millis()-startTime > 6000 && millis()-startTime < 9000) {
changePhrases(2);
}
if (millis()-startTime > 9000 && millis()-startTime < 12000) {
changePhrases(3);
}
}
//----------------INITIALIZE---------------------------------
void initAll() {
for (int j=0; j<FR1.length; j++) {
RGroup myGroup = font.toGroup(FR1[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
}
//FUNCTION TO SWITCH PHRASES
void changePhrases(int state) {
switch(state) {
case 0:
for (int j=0; j<FR1.length; j++) {
RGroup myGroup = font.toGroup(FR1[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
break;
case 1:
for (int j=0; j<FR2.length; j++) {
RGroup myGroup = font.toGroup(FR2[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
break;
case 2:
for (int j=0; j<FR3.length; j++) {
RGroup myGroup = font.toGroup(FR3[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
break;
case 3:
for (int j=0; j<FR4.length; j++) {
RGroup myGroup = font.toGroup(FR4[j]);
myGroup = myGroup.toPolygonGroup();
myPoints[j] = myGroup.getPoints();
}
break;
}
}
//////////////////////////////////////////////
Here's the code for my sketch that I added to the processing android demo. The problem starts with the ObserverElement. It seems to be trying to read another file using Reader.java
I think I see why its not working with the demo. The difference is that the demo uses gradle and my sketch that worked was jammed into a project(the clearsky android example) imported from eclipse. Theres some kind of dependency issue maybe.
package in.omerjerk.processingdemo.sketch;
import java.util.Arrays;
import java.util.List;
import controlP5.ControlP5;
import controlP5.DropdownList;
import controlP5.ScrollableList;
import controlP5.Textarea;
import jparsec.ephem.Ephem;
import jparsec.ephem.EphemerisElement;
import jparsec.ephem.EphemerisElement.COORDINATES_TYPE;
import jparsec.ephem.EphemerisElement.FRAME;
import jparsec.ephem.Functions;
import jparsec.ephem.Nutation;
import jparsec.ephem.Target.TARGET;
import jparsec.ephem.planets.EphemElement;
import jparsec.ephem.stars.StarElement;
import jparsec.ephem.stars.StarEphem;
import jparsec.ephem.stars.StarEphemElement;
import jparsec.io.ConsoleReport;
import jparsec.math.Constant;
import jparsec.observer.LocationElement;
import jparsec.observer.ObserverElement;
import jparsec.time.AstroDate;
import jparsec.time.SiderealTime;
import jparsec.time.TimeElement;
import jparsec.time.TimeElement.SCALE;
import jparsec.time.TimeScale;
import processing.core.PApplet;
import processing.core.PFont;
//import jparsec.ephem.IAU2006;
//import jparsec.ephem.IAU2006.CIO_EPHEMERIS;
//import jparsec.ephem.planets.JPLEphemeris;
//import jparsec.math.matrix.Matrix;
//import jparsec.observer.EarthOrientationParameters;
public class CSVTest2 extends PApplet {
//import java.sql.*;
//import de.bezier.data.sql.*;
//import java.lang.*;
//import java.time.*;
//SQLite db;
ControlP5 cp5;
ControlP5 controlP5;
Textarea myTextarea;
int Latitude_1 = 39;
int Lat_minutes = 20;
int Lat_seconds = 10;
int Longitude_1 = -77;
int Lon_minutes = 00;
int Lon_seconds = 26;
float Lon = 0;
float Lat = 0;
//ScrollableList Name1;
DropdownList Name1;
ScrollableList Name2;
String Star1 = " ";
String Star2 = " ";
String starName = " ";
float ra = 0;
String proper = " ";
float RA = 0;
float dec = 0;
double pmra = 0;
double pmdec = 0;
double rv = 0;
int i = 0 ;
PFont f;
int z = 18;
int index = 3;
int timer;
int wait = 10000;
public void setup()
{
// size( 100, 100 );
f = createFont("Arial",16,true);
// db = new SQLite( this, "hygdata.db" ); // open database file
cp5 = new ControlP5(this);
controlP5 = new ControlP5(this);
List l = Arrays.asList("Procyon","Rasalhague","Dubhe", "Mirphak", "Alkaid","Altair", "Alioth", "Spica", "Betelgeuse", "Capella", "Vega","Polaris", "Menkalinan", "Pollux", "Regulus","Deneb", "Denebola");
/* add a ScrollableList, by default it behaves like a DropdownList */
// Name1 = cp5.addScrollableList("StarName 1")
Name1 = cp5.addDropdownList("StarName 1")
.setPosition(20, 270)
.setSize(300, 200)
.setBarHeight(50)
.setItemHeight(50)
.addItems(l)
// .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
;
controlP5.addSlider("Latitude_1",0,90,Latitude_1,20,10,255,30);
controlP5.addSlider("Lat_minutes",0,60,Lat_minutes,20,50,255,30);
controlP5.addSlider("Lat_seconds",0,60,Lat_seconds,20,90,255,30);
controlP5.addSlider("Longitude_1",-180,180,Longitude_1,20,130,255,30);
controlP5.addSlider("Lon_minutes",0,60,Lon_minutes,20,170,255,30);
controlP5.addSlider("Lon_seconds",0,60,Lon_seconds,20,210,255,30);
Name2 = cp5.addScrollableList("StarName 2")
.setPosition(20, 590)
.setSize(300, 200)
.setBarHeight(50)
.setItemHeight(50)
.addItems(l)
;
myTextarea = cp5.addTextarea("txt")
.setPosition(420,10)
.setSize(950, 720)
.setFont(createFont("arial", 20))
.setLineHeight(20)
.setColor(color(255))
.setColorBackground(color(255, 0))
.setColorForeground(color(255, 100));
timer = millis();//store the current time
}
public void draw() {
background(0, 0, 0);
String[] starLines = loadStrings("stardata.csv");
println("Loaded " + starLines.length + " stars:");
Lat = (float)Latitude_1 + (float)Lat_minutes/60 + (float)Lat_seconds/3600; //Estimated Latitude
Lon = (float)Longitude_1 - (float)Lon_minutes/60 - (float)Lon_seconds/3600; //Estimated Longitude
if (Longitude_1 > 0) {
Lon = (float)Longitude_1 + (float)Lon_minutes/60 + (float)Lon_seconds/3600; //East of Greenwich
}
for ( i = 0 ; i < starLines.length; i++) {
String[] stars = splitTokens(starLines[i], ", ");
String proper = (stars[0]);
String con = (stars[1]);
double dec = PApplet.parseFloat(stars[2]);
double ra = PApplet.parseFloat(stars[3]);
double pmra = PApplet.parseFloat(stars[4]);
double pmdec = PApplet.parseFloat(stars[5]);
double rv = PApplet.parseFloat(stars[6]);
ra = ra * 15;
Star1 = Name1.getCaptionLabel().getText();
if (Star1 == "Procyon") {
z = 47;
}
if (Star1 == "Rasalhague") {
z = 93;
}
if (Star1 == "Dubhe") {
z = 57;
}
if (Star1 == "Mirphak") {
z = 18;
}
if (Star1 == "Alkaid") {
z = 73;
}
for (int j = 1; j < i; j = i+1) {
try {
if (i == z) { //14 = Polaris 69 = Dubhe
// AstroDate astro = new AstroDate(2008, 4, 24, 10, 36, 18);
AstroDate astro = new AstroDate();
// System.out.println(astro);
TimeElement time = new TimeElement(astro, SCALE.UNIVERSAL_TIME_UTC);
ObserverElement obs = new ObserverElement("", Lon * Constant.DEG_TO_RAD, Lat * Constant.DEG_TO_RAD, 88, 0);
ObserverElement obs0 = obs.clone();
EphemerisElement eph = new EphemerisElement(TARGET.Moon, COORDINATES_TYPE.APPARENT, EphemerisElement.EQUINOX_OF_DATE, EphemerisElement.GEOCENTRIC, EphemerisElement.REDUCTION_METHOD.IAU_2009,
FRAME.DYNAMICAL_EQUINOX_J2000, EphemerisElement.ALGORITHM.MOSHIER); //EphemerisElement.ALGORITHM.MOSHIER); //EphemerisElement.ALGORITHM.JPL_DE405); //.ALGORITHM.JPL_DE405);
eph.correctForPolarMotion = false; //originally false
eph.correctEOPForDiurnalSubdiurnalTides = false; //originally false
eph.correctForEOP = true; //originally false
// EarthOrientationParameters.clearEOP();
Nutation.clearPreviousCalculation();
// System.out.println("Geodetic location: "+Functions.formatAngleAsDegrees(obs.getLongitudeRad(), 3) + " / "+Functions.formatAngleAsDegrees(obs.getLatitudeRad(), 3) + " / "+obs.getHeight());
double TTminusUT1 = TimeScale.getTTminusUT1(time, obs);
// Force TT-UT1 as in the example
TTminusUT1 = 65.571845f;
TimeScale.forceTTminusUT1(time, obs, TTminusUT1);
// Force EOP parameters as in the example
double UT1minusUTC = -0.387845f, x = -0.002f, y = 0.529f, dx = 0, dy = 0;
boolean dxdyAredPsidEpsilon = false;
double jd_UTC = TimeScale.getJD(time, obs, eph, SCALE.UNIVERSAL_TIME_UTC);
// EarthOrientationParameters.forceEOP(jd_UTC, eph, UT1minusUTC, x, y, dx, dy, dxdyAredPsidEpsilon);
double jd_TT = TimeScale.getJD(time, obs, eph, SCALE.TERRESTRIAL_TIME);
double jd_UT1 = TimeScale.getJD(time, obs, eph, SCALE.UNIVERSAL_TIME_UT1);
StarElement star = new StarElement(proper, (double) ra * Constant.DEG_TO_RAD, (double) dec * Constant.DEG_TO_RAD,
0, 0, (float) (pmra * Constant.ARCSEC_TO_RAD / Math.cos((double) dec * Constant.DEG_TO_RAD)),
(float) (pmdec * Constant.ARCSEC_TO_RAD), (float) rv, Constant.J2000, FRAME.ICRF);
// System.out.println("Angular Velocity: " + pmra);
StarEphemElement ephem = StarEphem.starEphemeris(time, obs, eph, star, false);
eph.isTopocentric = true;
ephem = StarEphem.starEphemeris(time, obs, eph, star, false);
// double last = SiderealTime.greenwichMeanSiderealTime(time, obs, eph);
double last = SiderealTime.apparentSiderealTime(time, obs, eph);
// SiderealTime.
eph.correctForPolarMotion = false; //was true
eph.correctEOPForDiurnalSubdiurnalTides = false; //was true
eph.correctForEOP = false; //was true
Nutation.clearPreviousCalculation();
ephem = StarEphem.starEphemeris(time, obs, eph, star, false);
// ephem = IAU2006.getStarEphemerisWithRespectCIO(time, obs, eph, star, CIO_EPHEMERIS.topocentric);
LocationElement loc = ephem.getEquatorialLocation();
System.out.println(loc);
boolean full_ephem = true;
EphemElement sephem = Ephem.getEphemeris(time, obs, eph, true);
// ConsoleReport.fullEphemReportToConsole(sephem);
String Results = ConsoleReport.getBasicEphemReport(sephem, false);
myTextarea.setText(("Geodetic location: " + Functions.formatAngleAsDegrees(obs.getLongitudeRad(), 3) + " / " + Functions.formatAngleAsDegrees(obs.getLatitudeRad(), 3) + " / " + obs.getHeight()) +
"\n" + ("JD TT: " + jd_TT + "\n" + "UT1: " + jd_UT1 + "\n" + "TT-UT1: " + TTminusUT1) + "\n" +
(proper + " geocentric") + "\n" +
("RA: " + Functions.formatValue(ephem.rightAscension * Constant.RAD_TO_DEG / 15.0f, 10)) + "\n" +
("RA: " + Functions.formatRA(ephem.rightAscension, 4)) + "\n" +
("DEC: " + Functions.formatAngleAsDegrees(ephem.declination, 10)) + "\n" +
("DEC: " + Functions.formatDEC(ephem.declination, 4)) + "\n" + ("GP: " + loc) + "\n" +
("Az: " + Functions.formatValue(ephem.azimuth * Constant.RAD_TO_DEG, 10)) + "\n" +
("Az: " + Functions.formatAngle(ephem.azimuth, 4)) + "\n" +
("Alt: " + Functions.formatValue(ephem.elevation * Constant.RAD_TO_DEG, 10)) + "\n" +
("Alt: " + Functions.formatDEC(ephem.elevation)) + "\n" + "\n" +
//("Local Apparent Sidereal Time:: " + ( ((last)* Constant.RAD_TO_HOUR)+ 4)+"\n"+
("Local Apparent Sidereal Time:: " + (Functions.formatRA((last))) + "\n" + "\n" +
// (Functions.formatRA ((last)))
("Basic Ephemeris Report: " + Results))
// ("Basic Ephem Report: "))
);
}
}catch(Exception exc){
exc.printStackTrace();
}
}
// }
}
}
public void settings() { size(1000, 750); }
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "CSVTest2" };
if (passedArgs != null) {
PApplet.main(concat(appletArgs, passedArgs));
} else {
PApplet.main(appletArgs);
}
}
}
@Chrisir -- have you ever thought about wrapping your bezier editor in a Tool? Kind of like a color picker?
here is my bezier editor where you can draw and the sketch generates your code that you can use in the other sketch (your target sketch. Example below)
// see https : // www.processing.org/tutorials/curves/
// see https : // forum.processing.org/two/discussion/26216/can-someone-help-me-to-draw-this#latest
final String helpText =
"BezierVertex-Editor: You can make a vertex here and use it in another program.\nYou can click mouse to add new points, drag and drop existing points to move them.\n"
+"Backspace to remove last entry (or all entries), use Delete key to remove highlighted point (green point),\n"
+"space to export with println (to the direct window). \nThen you need to copy / paste the code from direct window to your target sketch.\n(click x to hide/show this text).";
ArrayList<PVector> listPV = new ArrayList();
// drag and drop
boolean hold=false;
int holding_i=-1;
// help text on off
boolean textHelpIsOn = true;
void setup() {
size(840, 880);
background(255);
makeArrayList();
}
void draw() {
background(255);
// drag and drop management
if (hold) {
PVector pv = listPV.get(holding_i);
pv.x=mouseX;
pv.y=mouseY;
}
// show ArrayList
showArrayList();
// text help
if (textHelpIsOn) {
fill(255, 0, 0) ;
text(helpText, 17, 17);
}
}// func draw()
// -----------------------------------------------------
void showArrayList() {
// show the curve
noFill();
stroke(0);
beginShape();
int i=0;
if (listPV.size()>0) {
curveVertexPVector(listPV.get(i));
for ( i = 0; i < listPV.size(); i++) {
curveVertexPVector(listPV.get(i));
}
i=listPV.size()-1;
curveVertexPVector(listPV.get(i));
}
endShape();
//show the points (additionally)
noStroke();
float rad=3;
for ( i = 0; i < listPV.size(); i++) {
PVector pv=listPV.get(i);
// if we are close to the mouse, color green, else red
if (dist(mouseX, mouseY, pv.x, pv.y)<11) {
// near to mouse
fill( 0, 255, 0); // green
rad=7;
} else {
// normal
fill(255, 0, 0); // red
rad=3;
}
ellipse(pv.x, pv.y,
rad, rad);
}//for
}//func
// ----------------------------------------------------------
// Tools
void makeArrayList() {
// init
int[] coords = {
// alternating x and y value (which belong together: 0 and 1 is a pair, 2 and 3 is a pair....)
40, 90, 110, 90, 140, 130, 60, 150, 50, 180
};
// read coords[]
for (int i = 0; i < coords.length; i += 2) {
listPV.add ( new PVector(coords[i], coords[i + 1]));
}
}//func
void curveVertexPVector(PVector pv) {
// like curveVertex but gets a PVector as input
// (just an easy way to use vectors for curveVertex)
curveVertex(pv.x, pv.y);
}
// ----------------------------------------------------------
void keyPressed() {
if (key==BACKSPACE) {
if (listPV.size()>0)
listPV.remove(listPV.size()-1);
}
// ----------------
else if (key==' ') {
// SPACE BAR
String xval="float[] xValues = { ",
yval="float[] yValues = { ";
for (int i = 0; i < listPV.size(); i++) {
PVector pv=listPV.get(i);
xval += str(pv.x)+",";
yval += str(pv.y)+",";
}//for
println (xval+" };");
println (yval+" };");
println ("remove last comma");
}// else if SPACE BAR
//------------------------
else if (key=='x') {
textHelpIsOn = !textHelpIsOn;
}//else if
//----------------------------
else if (key==DELETE) {
for (int i = 0; i < listPV.size(); i++) {
PVector pv=listPV.get(i);
if (dist(mouseX, mouseY, pv.x, pv.y)<11) {
listPV.remove(i);
return;
}//if
}//for
}//else if
//----------------------------
else if (key==ESC) {
key=0;
}
//----------------------------
}//func
void mousePressed() {
// apply drag and drop
for (int i = 0; i < listPV.size(); i++) {
PVector pv=listPV.get(i);
if (dist(mouseX, mouseY, pv.x, pv.y)<11) {
hold=true;
holding_i=i;
return;
}
}
// no drag and drop, add point
listPV.add(new PVector(mouseX, mouseY));
}
void mouseReleased() {
// end drag and drop
hold=false;
}
//---------------------------------------------------------------
PraxisLIVE is an open-source hybrid visual IDE and runtime for (live) creative coding. It offers a powerful alternative environment for working with the Processing library. Easily create projections, interactive spaces, custom VJ tools, sonic performance instruments, media for theatre; use it as a live digital sketchbook, test out ideas, experiment with code ...
Features include -
Recent changes include -
Download from - https://www.praxislive.org
Online documentation (still being updated for v4) - http://praxis-live.readthedocs.io
Hi
I working on a code running particles to represent refugee data The code limits the number of particles to keep the frameRate but even after using a steady number of particles, it keeps getting slower with lower frameRate.
I'm really not sure what I can do to make this run faster / smoother. Why does it keep getting slower?
Here's the data folder for the Sketch: https://www.dropbox.com/sh/z69phco3tahqklu/AAB8PLMpBQMoFUX5NGSie-5fa?dl=0
PImage texture;
PGraphics pg;
PShape worldMap;
import java.util.Map;
int filterPSystemsNum;
PGraphics sumPG;
// ========== Table Data Stuff
Table immigrationTable;
Table conflictTable;
Table countryLocations;
int k = 0;
String[] destCountryArray = new String[0];
String[] sourceCountryArray = new String[0];
String destCountry = "";
String prevDestCountry = "";
String sourceCountry;
float mapMultiplyX = 4;
float mapOffsetX = -100;
float mapMultiplyY = 4;
float mapOffsetY = 50;
// ========
int amountSum = 1;
String displayType = "Circular";
int maxParticles = 9000;
ParticleSystem ps;
ParticleSystem ps2;
int n = 0, n2=0;
int emmitMultiplyer = 1;
int emmitFreq = 1;
float particleSpeed = 1;
float locationX = 250;
float locationY = 450;
int[] sourceX = {10, 40, 200, 400, 700};
int[] destX = {300, 600, 300, 600, 600};
int[] amount = {10, 100, 500, 800, 1000};
int highestAmount;
float radius = 300;
float tempLong;
float tempLat;
int yearFilterMin = 1996;
int yearFilterMax = 2016;
ParticleSystem[] PSystems;
HashMap<String, Country> countries = new HashMap<String, Country>();
void setup() {
size(1200, 800, P2D);
((PGraphicsOpenGL)g).textureSampling(3);
texture = loadImage("paper_texture.jpg");
//worldMap = loadShape("worldLow.svg");
//=============== load immigrationTable and create an array of countries
immigrationTable = loadTable("asylum_seekers_all.csv", "header");
countryLocations = loadTable("LatLonCountries2.csv", "header");
conflictTable = loadTable("ged171.csv", "header");
destCountryArray = (String[]) append(destCountryArray, "Israel");
sumPG = createGraphics(width, height);
pg = createGraphics(width, height);
pg.beginDraw();
pg.background(177);
pg.endDraw();
image(pg, 0, 0);
for (TableRow row : immigrationTable.rows()) {
if (row.getInt("Year") <= yearFilterMax && row.getInt("Year") >= yearFilterMin) {
String tempCountryHolder = row.getString("Country / territory of asylum/residence");
boolean exists = countryExists(tempCountryHolder);
if (exists==true) {
continue;
}
destCountryArray = (String[]) append(destCountryArray, tempCountryHolder);
}
}
for (TableRow row : immigrationTable.rows()) {
if (row.getInt("Year") <= yearFilterMax && row.getInt("Year") >= yearFilterMin) {
String tempCountryHolder = row.getString("Origin");
boolean exists = countryExists(tempCountryHolder);
if (exists==true) { //println("exists, skipping");
continue;
}
destCountryArray = (String[]) append(destCountryArray, tempCountryHolder);
}
}
destCountryArray = sort(destCountryArray);
//============================ country hashmaps ======================================
for (int i = 0; i < destCountryArray.length; i++) {
String name = destCountryArray[i];
for (TableRow row : countryLocations.rows()) {
if (name.equals(row.getString("name"))) {
tempLong = row.getFloat("longitude");
tempLat = row.getFloat("latitude");
}
}
countries.put(name, new Country(name, width/2+(tempLong*mapMultiplyX)+mapOffsetX, height/2-(tempLat*mapMultiplyY)+mapOffsetY));
}
for (String key : countries.keySet()) {
Country c = countries.get(key);
}
//============================ PSystems =============
PSystems = new ParticleSystem[immigrationTable.getRowCount()];
int j = 0;
highestAmount = 291664;
println(amountSum);
for (TableRow row : immigrationTable.rows()) {
if (row.getInt("Year") <= yearFilterMax && row.getInt("Year") >= yearFilterMin) {
int tempAmount = row.getInt("decisions_recognized");
String tempDestCountry = row.getString("Country / territory of asylum/residence");
String tempSourceCountry = row.getString("Origin");
int tempYear = row.getInt("Year");
float sourceEmmiterX = countries.get(tempSourceCountry).x;
float sourceEmmiterY = countries.get(tempSourceCountry).y;
float destEmmiterX = countries.get(tempDestCountry).x;
float destEmitterY = countries.get(tempDestCountry).y;
PSystems[j] = new ParticleSystem(1, new Vector3D(sourceEmmiterX, sourceEmmiterY, 0), new Vector3D(destEmmiterX, destEmitterY, 0), tempAmount, tempYear);
println("----");
filterPSystemsNum++;
println("tempAmount "+tempAmount);
println("maxParticles "+maxParticles);
println("amountSum "+amountSum);
println("tempAmount*maxParticles "+tempAmount*maxParticles);
println("tempAmount*(maxParticles/amountSum) "+tempAmount*maxParticles/amountSum);
//println("PSystems " + i + " is " +PSystems[i]);
j++;
}
}
smooth();
}
int currentYear = 2000;
void draw() {
blendMode(MULTIPLY);
background(247, 245, 246, 1);
fill(1, 1, 1, 1);
tint(255, 1);
image(pg, 0, 0);
for (int i = 0; i<filterPSystemsNum; i++) {
boolean overCountryOrigin = overCountry(int(PSystems[i].origin.x), int(PSystems[i].origin.y), 10);
boolean overCountryDest = overCountry(int(PSystems[i].dest.x), int(PSystems[i].dest.y), 10);
boolean isOver = (overCountryOrigin || overCountryDest);
PSystems[i].run(isOver);
}
// =======
int allPCount = 0;
for (int k = 0; k<filterPSystemsNum; k++) {
Vector3D b=new Vector3D(PSystems[k].origin.x, PSystems[k].origin.y+abs(PSystems[k].origin.x-PSystems[k].dest.x)/2, 0);
Vector3D c=new Vector3D(PSystems[k].dest.x, PSystems[k].dest.y+abs(PSystems[k].origin.x-PSystems[k].dest.x)/2, 0);
boolean isTherePLimit = PSystems[k].PLimit != 0;
if (isTherePLimit){
boolean isThisAPlayingFrame = frameCount % int(sqrt(highestAmount/PSystems[k].PLimit)) == 0;
boolean isThisTheRightYear = PSystems[k].year == currentYear;
boolean areThereAnyMoreParticles = PSystems[k].PCount<PSystems[k].PLimit;
if (isThisAPlayingFrame && isThisTheRightYear && areThereAnyMoreParticles) {
for(int s = 0; s<emmitMultiplyer; s++){
PSystems[k].addParticle();
PSystems[k].PCount++;
n++;
}
}
}
}
// =========================================================== country labels
for (int i = 0; i<destCountryArray.length; i++) {
float tempX = countries.get(destCountryArray[i]).x;
float tempY = countries.get(destCountryArray[i]).y;
float tempAng = atan((tempY-height/2)/(tempX-width/2));
float labelMargin;
translate(tempX, tempY);
textSize(8);
rotate(tempAng);
fill(0);
if (tempX<width/2) {
textAlign(RIGHT);
labelMargin = -7;
} else {
textAlign(LEFT);
labelMargin = 7;
}
if (overCountry(int(tempX), int(tempY), 9)==true) {
fill(50, 100, 250);
ellipse(0, 0, 5, 5);
fill(0, 0, 255);
text(countries.get(destCountryArray[i]).name, labelMargin, 2);
} else {
fill (200);
fill(30, 100-sq(dist(mouseX, mouseY, tempX, tempY)));
text(countries.get(destCountryArray[i]).name, labelMargin, 2);
}
if (countries.get(destCountryArray[i]).name == "Israel") {
textAlign(RIGHT);
textSize(10);
fill(255);
rotate(-tempAng);
translate(-tempX, -tempY);
rect(-6, -8, -textWidth("you are here")-7, 14);
fill(200, 40, 40);
text ("you are here", mouseX, mouseY);
noFill();
strokeWeight(0.5);
stroke(255, 0, 0);
bezier(mouseX, mouseY, (mouseX+tempX)/2+100, mouseY, tempX, (mouseY+tempY)/2, tempX, tempY);
noStroke();
translate(tempX, tempY);
rotate(tempAng);
ellipse(0, 0, 4, 4);
}
rotate(-tempAng);
translate(-tempX, -tempY);
}
fill(0);
text("Frame rate: "
+ int(frameRate), 10, 20);
text("Each point: " + int(amountSum/maxParticles) +" people", 10, 30);
text("number of refugees: " + n*int(amountSum/maxParticles), 10, 40);
text("number of particles is: " +n, 10, 50);
text("max particles is: " +maxParticles, 10, 60);
textSize(80);
blendMode(BLEND);
fill(128, 130, 131);
text(round(float(n)*float(amountSum)/float(maxParticles)), 10, 160);
textSize(20);
text("RECOGNIZED REFUGEES (" +yearFilterMin+ " - " + yearFilterMax+")", 10, 180);
println("n = "+n);
println("amountSum = "+amountSum);
println("maxParticles = "+maxParticles);
}
// ==============================// A simple Particle class // ===============================================//
class Particle {
Vector3D loc;
Vector3D des;
Vector3D vel;
Vector3D acc;
Vector3D locHome, b, c;
float relativeSpeed;
float r;
float timer;
float t=0.0;
float a = random(TWO_PI);
Particle(Vector3D l, Vector3D m, int accum) {
acc = new Vector3D(0, 0, 0); // new Vector3D(random(-0.1, 0.1), random(-0.02, 0), 0);
loc = l.copy();
des = m.copy();
locHome = l.copy();
float rescale = 0.5;
locHome.x = locHome.x+ cos(a)*random(0, sqrt(accum)*rescale);
locHome.y = locHome.y+ sin(a)*random(0, sqrt(accum)*rescale);
des.x = des.x+ cos(a)*random(0, sqrt(accum)*rescale);
des.y = des.y+ sin(a)*random(0, sqrt(accum)*rescale);
relativeSpeed = random(0.1, 0.02);
r = random(0.9, 3); // particle radius
timer = 10000.0; // particles lifespan
b=new Vector3D(l.copy().x, l.copy().y+abs(l.copy().x-m.copy().x)/2, 0);
c=new Vector3D(m.copy().x, m.copy().y+abs(l.copy().x-m.copy().x)/2, 0);
}
void run(boolean onMouseOverPSystem) {
update();
render(onMouseOverPSystem);
}
// Method to update location
void update() {
if (t>=1)
return;
loc.x = bezierPoint(locHome.x, b.x, c.x, des.x, t);
loc.y = bezierPoint(locHome.y, b.y, c.y, des.y, t);
t = lerp(t, 1, particleSpeed*relativeSpeed/2);
}
void render(boolean isSelected) {
ellipseMode(CENTER);
noStroke();
blendMode(BLEND);
if (isSelected == false) {
fill(128, 129, 129, 150);
}
if (t==lerp(0, 1, particleSpeed*relativeSpeed/2)) {
pg.beginDraw();
pg.blendMode(BLEND);
pg.fill(0, 0, 0);
pg.noStroke();
pg.ellipse(loc.x, loc.y, r, r);
pg.endDraw();
} else {
fill(4*255*t-3*255);
}
ellipse(loc.x, loc.y, r, r);
}
// Is the particle still useful?
boolean dead() {
if (t==1) {
pg.beginDraw();
pg.blendMode(BLEND);
pg.fill(255, 255, 255, 255);
pg.noStroke();
pg.ellipse(loc.x, loc.y, r, r);
pg.endDraw();
return true;
} else {
return false;
}
}
}
// ==============================// A ParticleSystem // ===============================================//
// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles
class ParticleSystem {
ArrayList particles; // An arraylist for all the particles
Vector3D origin; // An origin point for where particles are birthed
Vector3D dest;
int PLimit;
int PCount;
int year;
float ratio = PLimit/highestAmount;
//ParticleSystem( number of particles / frame, source, destination, frequency);
ParticleSystem(int num, Vector3D v, Vector3D d, int f, int y) {
particles = new ArrayList(); // Initialize the arraylist
origin = v.copy(); // Store the origin point
dest = d.copy();
year = y;
PLimit = f;
//if (frameCount % (1/f) == 0){
for (int i = 0; i < num; i++) {
// particles.add(new Particle(origin, dest)); // Add "num" amount of particles to the arraylist
}
//}
}
void run(boolean onMouseOverPSystem) {
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = (Particle) particles.get(i);
p.run(onMouseOverPSystem);
if (p.dead()) {
particles.remove(i);
//PCount--;
//n--;
}
}
}
void addParticle() {
particles.add(new Particle(origin, dest, PCount));
}
// A method to test if the particle system still has particles
boolean dead() {
if (particles.isEmpty()) {
return true;
} else {
return false;
}
}
}
//=================================================== Class Country
class Country {
String name;
float x, y, lon, lat, migrationIndex, incoming, outgoing;
// more things here?
Country(String name, float x, float y) {
this.name = name;
this.x = x;
this.y = y;
}
}
// ================================================ Simple Vector3D Class
public class Vector3D {
public float x;
public float y;
public float z;
Vector3D(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
}
Vector3D(float x_, float y_) {
x = x_;
y = y_;
z = 0f;
}
Vector3D() {
x = 0f;
y = 0f;
z = 0f;
}
void setX(float x_) {
x = x_;
}
void setY(float y_) {
y = y_;
}
void setZ(float z_) {
z = z_;
}
void setXY(float x_, float y_) {
x = x_;
y = y_;
}
void setXYZ(float x_, float y_, float z_) {
x = x_;
y = y_;
z = z_;
}
void setXYZ(Vector3D v) {
x = v.x;
y = v.y;
z = v.z;
}
public float magnitude() {
return (float) Math.sqrt(x*x + y*y + z*z);
}
public Vector3D copy() {
return new Vector3D(x, y, z);
}
public Vector3D copy(Vector3D v) {
return new Vector3D(v.x, v.y, v.z);
}
public void add(Vector3D v) {
x += v.x;
y += v.y;
z += v.z;
}
public void sub(Vector3D v) {
x -= v.x;
y -= v.y;
z -= v.z;
}
public void mult(float n) {
x *= n;
y *= n;
z *= n;
}
public void div(float n) {
x /= n;
y /= n;
z /= n;
}
public void normalize() {
float m = magnitude();
if (m > 0) {
div(m);
}
}
public void limit(float max) {
if (magnitude() > max) {
normalize();
mult(max);
}
}
public float heading2D() {
float angle = (float) Math.atan2(-y, x);
return -1*angle;
}
public Vector3D add(Vector3D v1, Vector3D v2) {
Vector3D v = new Vector3D(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
return v;
}
public Vector3D sub(Vector3D v1, Vector3D v2) {
Vector3D v = new Vector3D(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
return v;
}
public Vector3D div(Vector3D v1, float n) {
Vector3D v = new Vector3D(v1.x/n, v1.y/n, v1.z/n);
return v;
}
public Vector3D mult(Vector3D v1, float n) {
Vector3D v = new Vector3D(v1.x*n, v1.y*n, v1.z*n);
return v;
}
public float distance (Vector3D v1, Vector3D v2) {
float dx = v1.x - v2.x;
float dy = v1.y - v2.y;
float dz = v1.z - v2.z;
return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
}
}
boolean countryExists(String tempCountryHolder) {
for (int i = 0; i < destCountryArray.length; i++) {
if (tempCountryHolder.equals(destCountryArray[i]) == true) {
return true; // it exists
} //if
} //for
return false ; // not found
}//func
//============================================= onMouseOver Bolean Class
boolean overParticle(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}
boolean overCountry(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}
This is something I had up on this forum since last summer, but it was in a question thread so I thought I should share this here in the proper category as well.
Current version: v1.2
This LaTeX listings template will color your Processing code as you see them in the Processing editor. You can just post your code like you normally would using the listings package, and you will automatically get your code in the proper colors. Except one minor inconvenience, that I will explain here.
For a function name that is the same as an already defined keyword (Such as "boolean" and "boolean()"), you have to use [escapechar = "char"] and \color{"color"}{"text"} to color them properly. Example:
\begin{lstlisting}[escapechar = ?]
boolean;
?\color{function}{boolean}?(1);
\end{lstlisting}
Copy and paste the below template if you want to use it. Alternatively, you can copy only the necessary parts. If in that case, note that \usepackage{listings} and \usepackage{color} is a must for this to work.
Also note, I have licensed this work with CreativeCommons license CC-BY-SA, so please remember to give some credit to me ;)
If you find any typos or any other errors, please tell me and I'll try to fix them as much as possible.
Download version:
http://www.mediafire.com/file/cw861uy156xftkv/article_listing_Processing_v1.2.tex
GitHub Gist:
https://gist.github.com/ebigunso/af355220e932f72d03289c576622aa29
Full template below:
\documentclass{article}
\usepackage{graphicx}
\usepackage{url}
\usepackage{verbatim}
\usepackage{listings}
\usepackage{color}
% Processing language definition template for LaTeX listings package v1.2
%
% Credits to ebigunso for creating this LaTeX listings language definition template for Processing
% This template is licensed with CreativeCommons license CC-BY-SA 4.0
% license info:
% https://creativecommons.org/licenses/by-sa/4.0/legalcode
%Define Colors
\definecolor{black}{RGB}{0,0,0}
\definecolor{gray}{RGB}{102,102,102} %#666666
\definecolor{function}{RGB}{0,102,153} %#006699 lightblue
\definecolor{lightgreen}{RGB}{102,153,0} %#669900
\definecolor{bluegreen}{RGB}{51,153,126} %#33997e
\definecolor{magenta}{RGB}{217,74,122} %#d94a7a
\definecolor{orange}{RGB}{226,102,26} %#e2661a
\definecolor{purple}{RGB}{125,71,147} %#7d4793
\definecolor{green}{RGB}{113,138,98} %#718a62
\lstdefinelanguage{Processing}{
%keyword1&2&6
morekeywords = [3]{abstract, break, class, continue, default, enum, extends, false, final, finally, implements, import, instanceof, interface, native, new, null, package, private, protected, public, static, strictfp, throws, transient, true, void, volatile, length, assert, case, return, super, this, throw},
%keyword3
morekeywords = [4]{catch, do, for, if, else, switch, synchronized, while, try},
%keyword4
morekeywords = [5]{width, height, pixelHight, displayHeight, displayWidth, focused, frameCount, frameRate, key, keyCode, keyPressed, mouseButton, mousePressed, mouseX, mouseY, pixels, pixelWidth, pmouseX, pmouseY},
%keyword5
morekeywords = [6]{Array, ArrayList, Boolean, Byte, BufferedReader, Character, Class, Double, Float, Integer, HashMap, PrintWriter, String, StringBuffer, StringBuilder, Thread, boolean, byte, char, color, double, float, int, long, short, FloatDict, FloatList, IntDict, IntList, JSONArray, JSONObject, PFont, PGraphics, PImage, PShader, PShape, PVector, StringDict, StringList, Table, TableRow, XML},
%literal2
morekeywords = [7]{ADD, ALIGN_CENTER, ALIGN_LEFT, ALIGN_RIGHT, ALPHA, ALPHA_MASK, ALT, AMBIENT, ARC, ARROW, ARGB, BACKSPACE, BASELINE, BEVEL, BLEND, BLUE_MASK, BLUR, BOTTOM, BOX, BURN, CENTER, CHATTER, CHORD, CLAMP, CLICK, CLOSE, CMYK, CODED, COMPLAINT, COMPOSITE, COMPONENT, CONCAVE_POLYGON, CONTROL, CONVEX_POLYGON, CORNER, CORNERS, CROSS, CUSTOM, DARKEST, DEGREES, DEG_TO_RAD, DELETE, DIAMETER, DIFFERENCE, DIFFUSE, DILATE, DIRECTIONAL, DISABLE_ACCURATE_2D, DISABLE_DEPTH_MASK, DISABLE_DEPTH_SORT, DISABLE_DEPTH_TEST, DISABLE_NATIVE_FONTS, DISABLE_OPENGL_ERRORS, DISABLE_PURE_STROKE, DISABLE_TEXTURE_MIPMAPS, DISABLE_TRANSFORM_CACHE, DISABLE_STROKE_PERSPECTIVE, DISABLED, DODGE, DOWN, DRAG, DXF, ELLIPSE, ENABLE_ACCURATE_2D, ENABLE_DEPTH_MASK, ENABLE_DEPTH_SORT, ENABLE_DEPTH_TEST, ENABLE_NATIVE_FONTS, ENABLE_OPENGL_ERRORS, ENABLE_PURE_STROKE, ENABLE_TEXTURE_MIPMAPS, ENABLE_TRANSFORM_CACHE, ENABLE_STROKE_PERSPECTIVE, ENTER, EPSILON, ERODE, ESC, EXCLUSION, EXIT, FX2D, GIF, GRAY, GREEN_MASK, GROUP, HALF, HALF_PI, HAND, HARD_LIGHT, HINT_COUNT, HSB, IMAGE, INVERT, JAVA2D, JPEG, LEFT, LIGHTEST, LINE, LINES, LINUX, MACOSX, MAX_FLOAT, MAX_INT, MIN_FOAT, MIN_INT, MITER, MODEL, MOVE, MULTIPLY, NORMAL, NORMALIZED, NO_DEPTH_TEST, NTSC, ONE, OPAQUE, OPEN, ORTHOGRAPHIC, OVERLAY, PAL, PDF, P2D, P3D, PERSPECTIVE, PI, PIE, PIXEL_CENTER, POINT, POINTS, POSTERIZE, PRESS, PROBLEM, PROJECT, QUAD, QUAD_STRIP, QUADS, QUARTER_PI, RAD_TO_DEG, RADIUS, RADIANS, RECT, RED_MASK, RELEASE, REPEAT, REPLACE, RETURN, RGB, RIGHT, ROUND, SCREEN, SECAM, SHAPE, SHIFT, SPAN, SPECULAR, SPHERE, SOFT_LIGHT, SQUARE, SUBTRACT, SVG, SVIDEO, TAB, TARGA, TAU, TEXT, TFF, THIRD_PI, THRESHOLD, TIFF, TOP, TRIANGLE, TRIANGLE_FAN, TRIANGLES, TRIANGLE_STRIP, TUNER, TWO, TWO_PI, UP, WAIT, WHITESPACE},
%function1
morekeywords = [8]{start, stop, breakShape, createPath, str, loadMatrix, parseBoolean, parseByte, parseChar, parseFloat, parseInt, saveFile, savePath, sketchFile, sketchPath, abs, acos, alpha, ambient, ambientLight, append, applyMatrix, arc, arrayCopy, asin, atan, atan2, background, beginCamera, beginContour, beginRaw, beginRecord, beginShape, bezier, bezierDetail, bezierPoint, bezierTangent, bezierVertex, binary, blend, blendColor, blendMode, blue, box, brightness, camera, ceil, clear, clip, color, colorMode, concat, constrain, copy, cos, createFont, createGraphics, createImage, createInput, createOutput, createReader, createShape, createWriter, cursor, curve, curveDetail, curvePoint, curveTangent, curveTightness, curveVertex, day, degrees, delay, directionalLight, displayDensity, dist, ellipse, ellipseMode, emissive, endCamera, endContour, endRaw, endRecord, endShape, exit, exp, expand, fill, filter, floor, frustum, fullScreen, get, green, hex, hint, hour, hue, image, imageMode, join, launch, lerp, lerpColor, lightFalloff, lights, lightSpecular, line, loadBytes, loadFont, loadImage, loadJSONArray, loadJSONObject, loadPixels, loadShader, loadShape, loadStrings, loadTable, loadXML, log, loop, mag, map, match, matchAll, max, millis, min, minute, modelX, modelY, modelZ, month, nf, nfc, nfp, nfs, noClip, noCursor, noFill, noise, noiseDetail, noiseSeed, noLights, noLoop, norm, normal, noSmooth, noStroke, noTint, ortho, parseJSONArray, parseJSONObject, parseXML, perspective, list, pixelDnsity, point, pointLight, popMatrix, popStyle, pow, print, printArray, printCamera, println, printMatrix, printProjection, pushMatrix, pushStyle, quad, quadraticVertex, radians, random, randomGaussian, randomSeed, rect, rectMode, red, redraw, requestImage, resetMatrix, resetShader, reverse, rotate, rotateX, rotateY, rotateZ, round, saturation, save, saveBytes, saveFrame, saveJSONArray, saveJSONObject, saveStream, saveStrings, saveTable, saveXML, scale, screenX, screenY, screenZ, second, selectFolder, selectInput, selectOutput, set, shader, shape, shapeMode, shearX, shearY, shininess, shorten, sin, size, smooth, sort, specular, sphere, sphereDetail, splice, split, splitTokens, spotLight, sq, sqrt, stroke, strokeCap, strokeJoin, strokeWeight, subset, tan, text, textAlign, textAscent, textDescent, textFont, textLeading, textMode, textSize, texture, textureMode, textureWrap, textWidth, thread, tint, translate, triangle, trim, unbinary, unhex, updatePixels, vertex, year},
%function2
morekeywords = [9]{cache, readLine, close, flush, print, println, charAt, equals, indexOf, substring, toLowerCase, toUpperCase, getDouble, getLong, getColumnTitles, getColumnTypes, getColumnType, setDouble, setLong, add, clear, div, get, hasKey, keyArray, keys, mult, remove, set, size, sortKeys, sortKeysReverse, sortValues, sortValuesReverse, sub, valueArray, values, append, array, hasValue, max, min, mult, remove, reverse, shuffle, sort, sortReverse, increment, getBoolean, getFloat, getInt, getIntArray, getJSONArray, getJSONObject, getString, getStringArray, isNull, setBoolean, setFloat, setInt, setJSONArray, setJSONObject, setString, beginDraw, endDraw, blend, copy, filter, loadPixels, mask, resize, save, updatePixels, addChild, beginContour, beginShape, disableStyle, enableStyle, endContour, endShape, getChild, getChildCount, getVertex, getVertexCount, isVisible, resetMatrix, rotate, rotateX, rotateY, rotateZ, scae, setFill, setStroke, setVertex, setVisible, translate, angleBetween, cross, dist, dot, fromAngle, heading, lerp, limit, mag, magSq, normalize, randm2D, random3D, setMag, lower, upper, addColumn, addRow, clearRows, findRow, findRows, getColumnCount, getRow, getRowcount, getStringColumn, matchRow, matchRows, removeColumn, removeRow, removeTokens, rows, trim, getColumnTitle, format, getAttributeCount, getChildren, getContent, getNam, getParent, hasAttribute, hasChildren, listAttributes, listChildren, removeChild, setContent, setName, toString},
%function4
morekeywords = [10]{draw, keyReleased, keyTyped, mouseClicked, mouseDragged, mouseMoved, mouseReleased, mouseWheel, settings, setup},
keywordstyle = [3]\color{bluegreen},
keywordstyle = [4]\color{lightgreen},
keywordstyle = [5]\color{magenta},
keywordstyle = [6]\color{orange},
keywordstyle = [7]\color{green},
keywordstyle = [8]\color{function},
keywordstyle = [9]\color{function},
keywordstyle = [10]\color{function},
sensitive = true,
morecomment = [l][\color{gray}]{//},
morecomment = [s][\color{gray}]{/*}{*/},
morecomment = [s][\color{gray}]{/**}{*/},
morestring = [b][\color{purple}]",
morestring = [b][\color{purple}]'
}
\renewcommand{\ttdefault}{pcr}
\lstset{
language={Processing},
basicstyle={\small\ttfamily},
identifierstyle={\small},
commentstyle={\small\itshape},
keywordstyle={\small},
ndkeywordstyle={\small},
stringstyle={\small\ttfamily},
frame={tb},
breaklines=true,
columns=[l]{fullflexible},
numbers=left,
xrightmargin=0em,
xleftmargin=3em,
numberstyle={\scriptsize},
stepnumber=1,
numbersep=1em,
lineskip=-0.5ex,
}
% Use escapechar and \color{<color>}{<text>} to color function names properly, that is already defined as a different color keyword.
%
% \begin{lstlisting}[escapechar = ?]
% boolean;
% ?\color{function}{boolean}?(1);
% \end{lstlisting}
\title{}
\author{}
\date{}
\begin{document}
\maketitle
\section{}
\begin{thebibliography}{9}
\end{thebibliography}
\end{document}
The Mapping Festival will take place in Geneva, Switzerland, from May 9th to 12th.
MAY 9th : Forum Paradigm_Shifts #2 + Opening Party
MAY 10th : Mapping LAB : WORKSHOPS
MAY 11th & 12th : Mapping LIVE
Join leading artists and designers for Mapping LAB, a full day of workshops curated and produced together with CreativeApplications.Net 1, and learn (more) about creative coding, machine learning, augmented reality, synthesizer making, interface prototyping, data visualisation and more.
WORKSHOPS PROGRAM :
Network Counter-Surveillance Boot-Camp / Julian Oliver (NZ) Capturing wireless traffic, device tracking, exploiting cellular networks – critical engineer Julian Oliver will provide a primer in network topologies, threat-modelling, and surveillance tactics, and introduce tools and techniques for self-protection.
TouchDesigner & Live Performance / Markus Heckmann (DE/CA) TouchDesigner Technical Director Markus Heckmann will introduce the powerful visual development platform and present best practices for using it in live performance – from video mixing to generative 2D/3D to MIDI control to projection mapping.
Rethinking UIs for a Post-Screen Era/ N O R M A L S (FR) Welcome to the N O R M A L S-led Bureau for Anticipated Interfaces, where you will search for human-computer interactions beyond ‘click, type, tap.’ Using Processing and paper, participants will author both a spatial operating system and new digital rituals.
Visual Programming with Paper.js / Jürg Lehni (CH) Unpacking the anatomy of Bézier paths and vector geometry, artist and designer Jürg Lehni will teach participants how to use the Paper.js scripting framework to generate complex graphics and build dynamic drawing tools that can be used manually or procedurally.
Processing Oscilloscopes/ Ted Davis (US) Using his recently released XYscope Processing library, media artist Ted Davis will share beginner-friendly creative coding strategies for audio/video synthesis by drawing vector graphics on an analog oscilloscope – a conversion of shape paths into sound.
Machine Learning for Artists / Gene Kogan (US) Join machine learning authority Gene Kogan for a survey of the rapidly evolving deep generative model landscape. Learn about variational autoencoders and generative adversarial networks, key codebases and artist projects, and tinker with the pix2pix framework.
Data Visualisation for a Post-Truth World / Lisa Charlotte Rost, Stef Tervelde (DE/NL) An editorial data vis whizz (Bloomberg, NPR, ZEIT Online, Tagesspiegel), Lisa Charlotte Rost will provide a comprehensive data visualization primer that juxtaposes tactics, techniques, and tools used in both the newsroom and data art. Learn how to read, visualize, and plot data!
Programmable Matter & Photoelasticity / Dana Zelig (IR) Drawing on her research with programmable polymers and textiles, design researcher Dana Zelig will teach participants how to encode behaviours into everyday materials (e.g. plastic) through creative experimentation with photoelasticity.
Augmented Reality DIY / Raphaël de Courville, Stef Tervelde (FR/NL) The magic of the virtual overlay: creative technologists Raphaël de Courville and Stef Tervelde will introduce mobile Augmented Reality, show how to develop for it using Unity and ARKit, and help participants build their own interactive mobile AR experience.
Draw (and Play) a Synthesizer / Coralie Gourguechon (FR) Using conductive paint and paper electronics, designer Coralie Gourguechon will demonstrate how to create a variety of (lofi) musical interfaces by simply drawing them. This session includes introductions to electronic prototyping, 555 timers, and sound generation.
Browser History Matchmaking / Dries Depoorter (BE) Join media artist Dries Depoorter for a fun group experiment in online dating, Google algorithm tweaking, and browser history analysis and learn about today’s web technology in the process. Will you find your perfect match at Mapping? P.S. Results may inform Depoorter’s next artwork.
Mapping, Mixing, Modulating Light and Video / Gaël Abegg Gauthey (CH) Opening their toolbox of MadMapper, Modul8, and miniMAD, garageCube’s Gaël Abegg Gauthey will demonstrate how to manage, mix, map, and modulate light and video in real-time. Learn how to control LEDs and multi-computer set-ups in installations or on stage.
Hacking the Human Sensorium / Susanna Hertrich, Daniela Silvestrin (DE/CH) Making the invisible visible: artist Susanna Hertrich and researcher Daniele Silvestrin will reveal the secret world of electromagnetic (EM) fields – and how easily our senses can be tricked. Using EM field detectors and hands-on experiments, participants will prototype sensorial hacks.
TICKETS : https://etickets.infomaniak.com/shop/d7FHecPkhK/ 1
INFORMATION TICKETS : https://2018.mappingfestival.com/en/tickets/ 4
INFORMATION WORKSHOPS : https://2018.mappingfestival.com/en/event/thursday-10-may-2018/
size(400,400);
stroke(0);
strokeWeight(3);
noFill();
background(255);
translate(200,200);
bezier(0,0,0,40,-100,0,-100,40);
bezier(0,0,0,40,100,0,100,40);
two cubic bezier curves
In your original code the Bezier coordinates were actual screen coordinates and you said the cloud centre was at [130, 190]. To get my Bezier points I have subtracted 130 from the X value and 190 from the Y value so the cloud centre is now [0,0].
The cloud can be drawn anywhere now by translating the axis (line 28) before drawing
Demo below. I demo how to draw points on a curve and then a second demo how to color from the center to any of those points.
A second approach is to create the radial color in the background and use the cloud shape as a mask, similar to a cookie-cutter.
Kf
final color STROKECOLOR1=color(250, 0, 250);
final color STROKECOLOR2=color(250, 250, 0);
float p1x;
float p1y;
float p2x;
float p2y;
float c1x;
float c1y;
float c2x;
float c2y;
PVector centroid;
void setup() {
size(300, 300);
background(50);
smooth();
centroid = new PVector(130, 190);
}
void draw() {
//for (int i=1;i<j;i++) {
// color interA=lerpColor(from, to, (float(i)/j));
// fill(interA);
fill(255);
beginShape();
vertex(50, 180);
bezierVertex(50, 150, 80, 120, 132, 150);
bezierVertex(150, 115, 210, 135, 200, 160);
bezierVertex(270, 175, 230, 235, 170, 220);
bezierVertex(170, 250, 80, 255, 70, 220);
bezierVertex(20, 240, 25, 170, 50, 180);
endShape();
stroke(255, 0, 250);
strokeWeight(4);
noFill();
setGlobalPoints(50, 180, 50, 150, 80, 120, 132, 150);
drawBezier(STROKECOLOR1);
drawPointToBezier(10,STROKECOLOR1,STROKECOLOR2,centroid);
setGlobalPoints(170, 220,170, 250, 80, 255, 70, 220);
drawBezier(STROKECOLOR1);
drawBezierPoints(10,STROKECOLOR1,STROKECOLOR2);
//center
stroke(#ff5060);
strokeWeight(6);
point(centroid.x,centroid.y);
noLoop();
}
void drawBezierPoints(int steps, color cs1,color cs2) {
for (int i = 0; i <= steps; i++) {
float t = i / float(steps);
float x = bezierPoint(p1x, c1x, c2x, p2x, t);
float y = bezierPoint(p1y, c1y, c2y, p2y, t);
stroke(lerpColor(cs1,cs2,t));
ellipse(x, y, 5, 5);
}
}
void drawPointToBezier(int steps, color cs1,color cs2, PVector centroid) {
for (int i = 0; i <= steps; i++) {
float t = i / float(steps);
float x = bezierPoint(p1x, c1x, c2x, p2x, t);
float y = bezierPoint(p1y, c1y, c2y, p2y, t);
stroke(lerpColor(cs1,cs2,t));
line(centroid.x,centroid.y, x, y);
}
}
void setGlobalPoints(float... a) {
p1x=a[0];
p1y=a[1];
c1x=a[2];
c1y=a[3];
p2x=a[6];
p2y=a[7];
c2x=a[4];
c2y=a[5];
}
void drawBezier(color cs) {
stroke(cs);
noFill();
bezier(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
}
Hello Processing Community, I have created a sketch ,But in the Beziercurve, how to make it from the center point to the surrounding color gradient? Until fill the entire graph.how to use Processing to achieve it? waiting for your suggestions and trying my best for this... regards ...
//color from = color (232, 255, 62);
//color to = color (255, 62, 143);
//int j=4;
void setup(){
size(300, 300);
background(50);
smooth();
}
void draw(){
//for (int i=1;i<j;i++) {
// color interA=lerpColor(from, to, (float(i)/j));
// fill(interA);
fill(255);
beginShape();
vertex(50, 180);
bezierVertex(50, 150, 80, 120, 132, 150);
bezierVertex(150, 115, 210, 135, 200, 160);
bezierVertex(270, 175, 230, 235, 170, 220);
bezierVertex(170, 250, 80, 255, 70, 220);
bezierVertex(20, 240, 25, 170, 50, 180);
endShape();
//center
stroke(#ff5060);
strokeWeight(6);
point(130,190);
noLoop();
}