I wrote this println ( " lastDataOfTheSample " + list.get(list.size()-1);
but I have syntax error.
Could you please put your lines of code in my code?
here is an example
see last paragraph in draw() pls
you need to click two points with the mouse into my program
ArrayList<PVector> points = new ArrayList ();
boolean runPoints=false;
float x, y;
float startX, startY, endX, endY;
float timeSpan;
int i=0;
float amt;
void setup() {
size(800, 800);
startX = width/2;
startY = height/2;
endX = 100;
endY = 100;
timeSpan = 2000.0;
}
void draw() {
if (runPoints) {
// PLAY Mode
// background(255);
// frameRate(1) ;
fill(255, 0, 0);
text("PLAY Mode - press any key to edit ", 19, 19);
PVector pv1 = points.get(i);
PVector pv2 = points.get(i+1);
/// lerp !!!!!
//for (int i2 = 0; i2 <= 10; i2++) {
float x = lerp(pv1.x, pv2.x, amt/10.0);
float y = lerp(pv1.y, pv2.y, amt/10.0);
point(x, y);
// }
// line(pv1.x, pv1.y, pv2.x, pv2.y);
amt+=0.1;
if (amt>10) {
amt=0;
i++;
}
if (i>points.size()-2) {
i=0;
runPoints=false;
}
}//if
else {
// Edit mode
background(255);
fill(255, 0, 0);
text("Edit Mode - click mouse points and press any key to play ", 19, 19);
for (int i = 0; i<points.size(); i++) {
PVector pv1 = points.get(i);
ellipse(pv1.x, pv1.y, 4, 4);
}
}//else
//-------
// show first and last point
if (points.size()>1) {
fill(0);
text("0", points.get(0).x, points.get(0).y-3);
PVector pv = points.get(points.size()-1).copy();
text("last", pv.x, pv.y-3);
}//if
//
}// function draw()
//-------------------------------------------------------------------
void mousePressed() {
points.add(new PVector(mouseX, mouseY));
runPoints=false;
}
void keyPressed () {
// toggle runPoints
runPoints =
! runPoints;
if (runPoints) {
background(255);
}
}
your arraylist is called samples, not list
you also have a missing ) at the end
I am sure you can apply it to your code.
new version with println:
ArrayList<PVector> points = new ArrayList ();
boolean runPoints=false;
float x, y;
float startX, startY, endX, endY;
float timeSpan;
int i=0;
float amt;
void setup() {
size(800, 800);
startX = width/2;
startY = height/2;
endX = 100;
endY = 100;
timeSpan = 2000.0;
}
void draw() {
if (runPoints) {
// PLAY Mode
// background(255);
// frameRate(1) ;
fill(255, 0, 0);
text("PLAY Mode - press any key to edit ", 19, 19);
PVector pv1 = points.get(i);
PVector pv2 = points.get(i+1);
/// lerp !!!!!
//for (int i2 = 0; i2 <= 10; i2++) {
float x = lerp(pv1.x, pv2.x, amt/10.0);
float y = lerp(pv1.y, pv2.y, amt/10.0);
point(x, y);
// }
// line(pv1.x, pv1.y, pv2.x, pv2.y);
amt+=0.1;
if (amt>10) {
amt=0;
i++;
}
if (i>points.size()-2) {
i=0;
runPoints=false;
}
}//if
else {
// Edit mode
background(255);
fill(255, 0, 0);
text("Edit Mode - click mouse points and press any key to play ", 19, 19);
for (int i = 0; i<points.size(); i++) {
PVector pv1 = points.get(i);
ellipse(pv1.x, pv1.y, 4, 4);
}
}//else
//-------
// show first and last point
if (points.size()>1) {
fill(0);
text("0", points.get(0).x, points.get(0).y-3);
PVector pv = points.get(points.size()-1).copy();
println(pv);
println ( "lastDataOfTheSample "
+ points.get(points.size()-1) ) ;
text("last", pv.x, pv.y-3);
}//if
//
}// function draw()
//-------------------------------------------------------------------
void mousePressed() {
points.add(new PVector(mouseX, mouseY));
runPoints=false;
}
void keyPressed () {
// toggle runPoints
runPoints =
! runPoints;
if (runPoints) {
background(255);
}
}
Thanks. An engineer found a solution for me.
Here it is!
`But now I have to map this interpolation, just the interpolation of y, in order to have a variable from 0 to TWO to see a ball turning always in the same way! I hope you can keep to try to help me!
int actualSec,lastSec,measure,measureToStartRecording;
boolean bRecording = false;
boolean mouseRecorded = true;
int nbBalls=1;
float movementInterpolated;
class Sample {
int t, x, y;
Sample( int t, int x, int y ) {
this.t = t; this.x = x; this.y = y;
}
}
class Sampler {
ArrayList<Sample> samples;
ArrayList<Sample> samplesModified;
int startTime;
int playbackFrame;
Sampler() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
startTime = 0;
}
void beginRecording() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
playbackFrame = 0;
}
void addSample( int x, int y ) { // add sample when bRecording
int now = millis();
if( samples.size() == 0 ) startTime = now;
samples.add( new Sample( now - startTime, x, y ) );
}
int fullTime() {
return ( samples.size() > 1 ) ?
samples.get( samples.size()-1 ).t : 0;
}
void beginPlaying() {
startTime = millis();
playbackFrame = 0;
println( samples.size(), "samples over", fullTime(), "milliseconds" );
if(samples.size() > 0){
int deltax = samples.get(0).x - samples.get(samples.size()-1).x;
int deltay = samples.get(0).y - samples.get(samples.size()-1).y;
float sumdist = 0;
for(int i = 0; i < samples.size() - 1; i++) {
sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
}
samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x , samples.get(0).y ) );
float dist = 0;
for(int i = 0; i < samples.size() - 1; i++) {
dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
samplesModified.add( new Sample(samples.get(i+1).t, (int) (samples.get(i +1).x + (dist * deltax) / sumdist), (int) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
print(samples.get(i).x);
print(",");
print(samples.get(i).y);
print(",");
print( " good data x " + samplesModified.get(i).x);
print(",");
print( " good data y " + samplesModified.get(i).y);
println("");
}
}
}
void draw() {
stroke( 255 );
//**RECORD
beginShape(LINES);
for( int i=1; i<samples.size(); i++) {
vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
vertex( samplesModified.get(i).x, samplesModified.get(i).y );
}
endShape();
//**ENDRECORD
//**REPEAT
int now = (millis() - startTime) % fullTime();
if( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
while( samplesModified.get( playbackFrame+1).t < now )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samplesModified.get( playbackFrame );
Sample s1 = samplesModified.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (now - t0) / (t1 - t0);
float x = lerp( s0.x, s1.x, dt );
float y = lerp( s0.y, s1.y, dt );
circle( x, y, 10 );
println( " good data y " + y);
movementInterpolated=map (y, 0, 400, 0, TWO_PI);
}
}
Sampler sampler;
void setup() {
size( 800, 800, P3D );
frameRate( 30 );
sampler = new Sampler();
}
void draw() {
background( 0 );
activeSampling();
stopSampling();
if( actualSec!=lastSec){
lastSec=actualSec;
measure++;
textSize (100);
text (measure, 100, 100 );
}
actualSec =(int) (millis()*0.001); //
if( bRecording) { // draw circle
circle( mouseX, mouseY, 10 );
sampler.addSample( mouseX, mouseY );
}
else {
if( sampler.fullTime() > 0 )
sampler.draw();
}
drawBall( 1, movementInterpolated);
}
void mousePressed() {
bRecording = true; // draw circle
mouseRecorded = true;
measure=0;
}
void activeSampling() {
if (measure<=1 && measure>=1 &&actualSec!=lastSec && mouseRecorded == true) {
sampler.beginRecording();
}
}
void stopSampling() {
if (measure<=3 && measure>=3 && actualSec!=lastSec) {
mouseRecorded = false;
//**REPEAT
bRecording = false;
sampler.beginPlaying();
}
}
void drawBall(int n, float phase)
{
pushMatrix();
translate(-400, -400, -2000);
noStroke();
float side = height*0.15*1/this.nbBalls;
float rayon = width/2;
float x = rayon*cos(phase);
float y = rayon*sin(phase);
translate (x, y, 200+(50*5*n));
colorMode(RGB, 255, 255, 255);
fill( 0, 255, 0 );
sphere(side*3);
popMatrix();
}
Okay, the line I’ve drawn is shown in white.
A green ball follows the line.
But why is the big green ball still there in this case?
I don’t think this is true. He’s recording throughout - or what do you mean?
not sure, but measure can’t be < 1 AND > 1 at the same time. Hence you mean measure==1
?
movementInterpolated
not clear. Maybe you can communicate what your final goal is?
You are referring to
movementInterpolated=map (y, 0, 400, 0, TWO_PI);
(it’s TWO_PI, not TWO)
(always nice when you tell us the code line
you are referring to )
here is what you can do with movementInterpolated
:
// see y as 0 to TWO_PI
movementInterpolated=map (y,
0, 400,
0, TWO_PI);
// show 2 circles at right screen border
circle( width-11, movementInterpolated+55, 12); // minimal movement
circle( width-11, movementInterpolated*100+255, 12); // movement enhanced by *100
// calc circle pos x1,y1 with movementInterpolated as an angle
float x1=cos(movementInterpolated) * 100 + (width-120);
float y1=sin(movementInterpolated) * 100 + (255);
fill(0, 0, 255);
circle(x1, y1, 9); // show point on circle with movementInterpolated as angle
circle((width-120), 255, 9); // show center of circle
Remark
By the way in processing the order is (mostly (it’s only by convention))
- global vars and objects
- setup and draw
- other functions
- classes
It is unwise to name a method in a class draw(), just use display() instead
Full Sketch
int actualSec, lastSec, measure, measureToStartRecording;
boolean bRecording = false;
boolean mouseRecorded = true;
int nbBalls=1;
float movementInterpolated;
Sampler sampler;
// ------------------------------------------------------------------------------------------------------
// Two core functions
void setup() {
size( 800, 800, P3D );
frameRate( 30 );
sampler = new Sampler();
}//setup()
void draw() {
background( 0 );
activeSampling();
stopSampling();
if (actualSec!=lastSec) {
lastSec=actualSec;
measure++;
}
textSize(100);
text(measure, 100, 100 );
actualSec = (int) (millis()*0.001); //
if (bRecording) {
// draw circle
circle(mouseX, mouseY, 10 );
sampler.addSample( mouseX, mouseY );
} else {
if (sampler.fullTime() > 0 )
sampler.display();
}
drawBall(1, movementInterpolated);
}//draw()
// ------------------------------------------------------------------------------------------------------
// Inputs
void mousePressed() {
bRecording = true; // draw circle
mouseRecorded = true;
measure=0;
}
// ------------------------------------------------------------------------------------------------------
// other functions
void activeSampling() {
if (measure<=1 && measure>=1 &&actualSec!=lastSec && mouseRecorded == true) {
sampler.beginRecording();
println ("here 18");
}
}
void stopSampling() {
if (measure<=3 && measure>=3 && actualSec!=lastSec) {
mouseRecorded = false;
//**REPEAT
bRecording = false;
sampler.beginPlaying();
}
}
void drawBall(int n, float phase) {
pushMatrix();
translate(-400, -400, -2000);
noStroke();
float side = height*0.15*1/this.nbBalls;
float rayon = width/2;
float x = rayon*cos(phase);
float y = rayon*sin(phase);
translate (x, y, 200+(50*5*n));
colorMode(RGB, 255, 255, 255);
fill( 0, 255, 0 );
sphere(side*3);
popMatrix();
}
// ====================================================================
// Two classes
class Sample {
int t, x, y;
//constr
Sample( int t, int x, int y ) {
this.t = t;
this.x = x;
this.y = y;
}//constr
//
}//class
// ----
class Sampler {
ArrayList<Sample> samples;
ArrayList<Sample> samplesModified;
int startTime;
int playbackFrame;
//constr
Sampler() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
startTime = 0;
}//constr
void beginRecording() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
playbackFrame = 0;
}
void addSample( int x, int y ) { // add sample when bRecording
int now = millis();
if ( samples.size() == 0 ) startTime = now;
samples.add( new Sample( now - startTime, x, y ) );
}
int fullTime() {
return
samples.size() > 1 ?
samples.get( samples.size()-1 ).t : 0;
}
void beginPlaying() {
// called only once
println("here 12");
startTime = millis();
playbackFrame = 0;
println( samples.size(), "samples over", fullTime(), "milliseconds" );
if (samples.size() > 0) {
int deltax = samples.get(0).x - samples.get(samples.size()-1).x;
int deltay = samples.get(0).y - samples.get(samples.size()-1).y;
float sumdist = 0;
for (int i = 0; i < samples.size() - 1; i++) {
sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
}
samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x, samples.get(0).y ) );
float dist = 0;
for (int i = 0; i < samples.size() - 1; i++) {
dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
samplesModified.add( new Sample(samples.get(i+1).t, (int) (samples.get(i +1).x + (dist * deltax) / sumdist), (int) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
print(samples.get(i).x);
print(",");
print(samples.get(i).y);
print(",");
print( " good data x " + samplesModified.get(i).x);
print(",");
print( " good data y " + samplesModified.get(i).y);
println("");
}
}
}
void display() {
stroke( 255 );
//**RECORD
beginShape(LINES);
for ( int i=1; i<samples.size(); i++) {
vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
vertex( samplesModified.get(i).x, samplesModified.get(i).y );
}
endShape();
//**ENDRECORD
//**REPEAT
int now = (millis() - startTime) % fullTime();
if ( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
while ( samplesModified.get( playbackFrame+1).t < now )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samplesModified.get( playbackFrame );
Sample s1 = samplesModified.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (now - t0) / (t1 - t0);
float x = lerp( s0.x, s1.x, dt );
float y = lerp( s0.y, s1.y, dt );
circle( x, y, 10 );
println( " good data y " + y);
// see y as 0 to TWO_PI
movementInterpolated=map (y,
0, 400,
0, TWO_PI);
// show 2 circles at right screen border
circle( width-11, movementInterpolated+55, 12); // minimal movement
circle( width-11, movementInterpolated*100+255, 12); // movement enhanced by *100
// calc circle pos x1,y1 with movementInterpolated as an angle
float x1=cos(movementInterpolated) * 100 + (width-120);
float y1=sin(movementInterpolated) * 100 + (255);
fill(0, 0, 255);
circle(x1, y1, 9); // show point on circle with movementInterpolated as angle
circle((width-120), 255, 9); // show center of circle
//
}//method
//
}//class
//
Hi Mister,
Thank for helping me
I wanted to say, I want to follow the movement drawn in white color doing a loop.
If you try to record a big circle with the mouse you will see that your circle an my green ball turn in the same way. But sometimes, depending of the movement drawn in white color we have some jumps, glitches in the movement made by your circle and my ball.
I think it is possible to fix this bug by mapping the interpolatedmovement with better method.
I wrote at line 206 a possible method.
I will explain my final goal a bit later.
Thank you so much
int actualSec, lastSec, measure, measureToStartRecording;
boolean bRecording = false;
boolean mouseRecorded = true;
int nbBalls=1;
float movementInterpolated;
float formerInterpolatedY,interpolatedY;
Sampler sampler;
// ------------------------------------------------------------------------------------------------------
// Two core functions
void setup() {
size( 800, 800, P3D );
frameRate( 30 );
sampler = new Sampler();
}//setup()
void draw() {
background( 0 );
activeSampling();
stopSampling();
if (actualSec!=lastSec) {
lastSec=actualSec;
measure++;
}
textSize(100);
text(measure, 100, 100 );
actualSec = (int) (millis()*0.001); //
if (bRecording) {
// draw circle
circle(mouseX, mouseY, 10 );
sampler.addSample( mouseX, mouseY );
} else {
if (sampler.fullTime() > 0 )
sampler.display();
}
drawBall(1, movementInterpolated);
}//draw()
// ------------------------------------------------------------------------------------------------------
// Inputs
void mousePressed() {
bRecording = true; // draw circle
mouseRecorded = true;
measure=0;
}
// ------------------------------------------------------------------------------------------------------
// other functions
void activeSampling() {
if (measure==1 && actualSec!=lastSec && mouseRecorded == true) {
sampler.beginRecording();
println ("here 18");
}
}
void stopSampling() {
if (measure==3 && actualSec!=lastSec) {
mouseRecorded = false;
//**REPEAT
bRecording = false;
sampler.beginPlaying();
}
}
void drawBall(int n, float phase) {
pushMatrix();
translate(-400, -400, -2000);
noStroke();
float side = height*0.15*1/this.nbBalls;
float rayon = width/2;
float x = rayon*cos(phase);
float y = rayon*sin(phase);
translate (x, y, 200+(50*5*n));
colorMode(RGB, 255, 255, 255);
fill( 0, 255, 0 );
sphere(side*3);
popMatrix();
}
// ====================================================================
// Two classes
class Sample {
int t, x, y;
//constr
Sample( int t, int x, int y ) {
this.t = t;
this.x = x;
this.y = y;
}//constr
//
}//class
// ----
class Sampler {
ArrayList<Sample> samples;
ArrayList<Sample> samplesModified;
int startTime;
int playbackFrame;
//constr
Sampler() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
startTime = 0;
}//constr
void beginRecording() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
playbackFrame = 0;
}
void addSample( int x, int y ) { // add sample when bRecording
int now = millis();
if ( samples.size() == 0 ) startTime = now;
samples.add( new Sample( now - startTime, x, y ) );
}
int fullTime() {
return
samples.size() > 1 ?
samples.get( samples.size()-1 ).t : 0;
}
void beginPlaying() {
// called only once
println("here 12");
startTime = millis();
playbackFrame = 0;
println( samples.size(), "samples over", fullTime(), "milliseconds" );
if (samples.size() > 0) {
int deltax = samples.get(0).x - samples.get(samples.size()-1).x;
int deltay = samples.get(0).y - samples.get(samples.size()-1).y;
float sumdist = 0;
for (int i = 0; i < samples.size() - 1; i++) {
sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
}
samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x, samples.get(0).y ) );
float dist = 0;
for (int i = 0; i < samples.size() - 1; i++) {
dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
samplesModified.add( new Sample(samples.get(i+1).t, (int) (samples.get(i +1).x + (dist * deltax) / sumdist), (int) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
print(samples.get(i).x);
print(",");
print(samples.get(i).y);
print(",");
print( " good data x " + samplesModified.get(i).x);
print(",");
print( " good data y " + samplesModified.get(i).y);
println("");
}
}
}
void display() {
stroke( 255 );
//**RECORD
beginShape(LINES);
for ( int i=1; i<samples.size(); i++) {
vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
vertex( samplesModified.get(i).x, samplesModified.get(i).y );
}
endShape();
//**ENDRECORD
//**REPEAT
int now = (millis() - startTime) % fullTime();
if ( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
while ( samplesModified.get( playbackFrame+1).t < now )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samplesModified.get( playbackFrame );
Sample s1 = samplesModified.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (now - t0) / (t1 - t0);
float x = lerp( s0.x, s1.x, dt );
float y = lerp( s0.y, s1.y, dt );
circle( x, y, 10 );
println( " good data y " + y);
//my modification
formerInterpolatedY=interpolatedY;
interpolatedY= constrain ( lerp( s0.y, s1.y, dt ), 0, 800);
// a possible to have movement in the same way
if (formerInterpolatedY<=interpolatedY){
movementInterpolated= map (interpolatedY, 800, 0, 0, TWO_PI); // map from the highest interpolated point to lowest interpolated point
}
else
{
movementInterpolated=map (interpolatedY, 0, 800, 0, TWO_PI); // map from the lowest interpolated point to highest interpolated point
}
// former modification
// see y as 0 to TWO_PI
// movementInterpolated=map (y,
// 0, 400,
// 0, TWO_PI);
// show VerticalMovement 2 circles at right screen border
circle( width-11, movementInterpolated+55, 12); // minimal movement
circle( width-11, movementInterpolated*100+255, 12); // movement enhanced by *100
// calc circle pos x1,y1 with movementInterpolated as an angle
float x1=cos(movementInterpolated) * 100 + (width-120);
float y1=sin(movementInterpolated) * 100 + (255);
fill(0, 0, 255);
circle(x1, y1, 9); // show point on circle with movementInterpolated as angle
circle((width-120), 255, 9); // show center of circle
//
}//method
//
}//class
//
Hello super Mister.
I changed the program.
Now, i have perfect angle to interpolate, not a shape drawn with the mouse.
I think you will have solution, quite easy.
I will try make a video tomorow in order to see what i’m trying to do.
Take care of you.
Benjamin
Hello!
you can also just record a circle based on the angle between mouse and screen center (core idea is using atan2()
here).
This circle would have a fixed radius.
Remark
When you have a real circle and know its center and radius, you can of course calc the intermediate points (not only one but all):
- calc the angle from last point a1
- calc the angle from first point a2
- for loop a_intermediate from a1 to a2; lots of ways to do this;
for(int a_intermediate = degree(a1); a_intermediate <= degree(a2); a_intermediate++) {
or uselerp()
between the angles a1 and a2 (not between the points obviously). - calc x and y based on a_intermediate and cos and sin (and r and center) like here:
float x=cos(a_intermediate) * r + centerX;
float y=sin(a_intermediate) * r + centerY;
Warm regards,
Chrisir
Full Sketch
(without the remark above)
void setup() {
size(800, 600);
}
void draw() {
background(204);
float a = calcAngle();
//----------------------------------------
pushMatrix();
translate(width/2, height/2);
rotate(a);
translate(28, 0);
rect(-30, -5, 60, 10);
popMatrix();
//----------------------------------------
ellipse(width/2, height/2, 5, 5);
text(degrees(a), 22, 22);
}
//----------------------------------------------------------------------
float calcAngle() {
// calc angle between mouse and screen center
float a = atan2(mouseY-height/2, mouseX-width/2);
if (a<0) {
a=map(a, -PI, 0,
PI, TWO_PI);
}
return a;
}
//
new version where the points on the circle are shown separately using :
stroke(255, 0, 0);
ellipse(
cos(a) * 150 + width/2.0,
sin(a) * 150 + height/2.0,
4,
4
);
Full Sketch
void setup() {
size(800, 600);
}
void draw() {
// background(204);
float a = calcAngle();
//----------------------------------------
pushMatrix();
translate(width/2, height/2);
rotate(a);
translate(28, 0);
stroke(0);
rect(-30, -5, 60, 10);
popMatrix();
//----------------------------------------
stroke(255, 0, 0);
ellipse(
cos(a) * 150 + width/2.0,
sin(a) * 150 + height/2.0,
4,
4
);
stroke(0);
ellipse(width/2, height/2, 5, 5);
text(degrees(a), 22, 22);
}
//----------------------------------------------------------------------
float calcAngle() {
// calc angle between mouse and screen center
float a = atan2(mouseY-height/2, mouseX-width/2);
if (a<0) {
a=map(a, -PI, 0,
PI, TWO_PI);
}
return a;
}
//
Hi,
I changed the program with yours remarks.
It 's totatlly better to record position of the ball like that.
As you said :
That’s i’m tring to do but i do not retreive the first and the last datas sampled
Here my changes
int actualSec;
int lastSec;
int virtualV2;
float mlerp(float x0, float x1, float t, float M ){
float dx = (x1 - x0 + 1.5*M) % M - 0.5*M;
return (x0 + t * dx + M) % M;
}
float interpolatedAngle;
float angleToInterpolate;
boolean bRecording = false;
boolean mouseRecorded;
float currTime;
float nextSamplePeriod = 2.0;
int measure;
class Sample {
float t, y;
Sample( float t, float y ) {
this.t = t; this.y = y;
}
}
class Sampler {
ArrayList<Sample> samples;
float startTime;
float sampleLengthTime;
float period;
int playbackFrame;
//**** SCULDY COMPUTATION TO PUT HERE ??
Sampler( float newPeriod, float now, float y ) {
samples = new ArrayList<Sample>();
startTime = now;
addSample( now, y );
playbackFrame = 0;
period = newPeriod;
}
void addSample( float now, float y ) {
samples.add( new Sample( now - startTime, y ) );
sampleLengthTime = now - startTime;
if( sampleLengthTime > period )
bRecording = false;
mouseRecorded = false;
// round up the period to the next power of 2
//period = sampleLengthTime < 1 ? 1 :
// pow( 2, max( 0, ceil( log( sampleLengthTime ) / log(2) ) ) );
}
void drawRecordingWithVertexes( float now ){
if( samples.size() < 2 ) return;
// draw the sample trail
stroke( 200 );
beginShape(LINES);
for( int i=1; i<samples.size(); i++) {
vertex( samples.get(i-1).y, samples.get(i).y ); // replace vertex with Pvector ???
}
endShape();
// draw the current sample point
//float st = (now - startTime) % period;
float st = now % period;
if( st > sampleLengthTime ) return;
if( st < samples.get( playbackFrame ).t ) playbackFrame = 0;
while( samples.get( playbackFrame+1).t < st )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samples.get( playbackFrame );
Sample s1 = samples.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (st - t0) / (t1 - t0);
// float x = mlerp( s0.x, s1.x, dt, 400 ); // interpolation with 'continious datas'
float y = mlerp( s0.y, s1.y, dt, TWO_PI ); // interpolation with 'radian datas'
interpolatedAngle = y; // angle between themselves not from the first and the last!
for( int i=1; i<samples.size(); i++) {
print ( " interpolatedAngle " + interpolatedAngle + " first angle " + samples.get(0) + " last angle " + samples.get(samples.size()-1));
}
noStroke();
fill( 255, 40, 40 );
circle ( 100* cos ( interpolatedAngle)+400, 100*sin ( interpolatedAngle)+200, 20);
}
}
Sampler sampler;
ArrayList<Sampler> samplers;
void setup() {
size( 800, 800, P3D );
frameRate( 30 );
samplers = new ArrayList<Sampler>();
}
void draw() {
println ( " measure " + measure );
if (actualSec<lastSec){
measure=measure+1;
}
lastSec=actualSec;
actualSec = millis()%1000; // Values from 0 - 2
activeSamplingSecond();
samplingMovementPro();
angleToInterpolate = calcAngle();
fill( 100, 0, 0);
circle ( 100* cos (angleToInterpolate)+200, 100*sin (angleToInterpolate)+200, 20);
//----------------------------------------
pushMatrix();
translate(width/2, height/2);
rotate(angleToInterpolate);
translate(28, 0);
rect(-30, -5, 60, 10);
popMatrix();
//----------------------------------------
ellipse(width/2, height/2, 5, 5);
text(degrees(angleToInterpolate), 22, 22);
}
//----------------------------------------------------------------------
float calcAngle() {
float a = atan2(mouseY-height/2, mouseX-width/2);
if (a<0) {
a=map(a, -PI, 0,
PI, TWO_PI);
}
return a;
}
void samplingMovementPro() {
currTime = millis() * 0.001; // seconds since app started
background( 0 );
for( int i=0; i<3; i++ ) {
float p = pow( 2, i );
stroke( 64, p == nextSamplePeriod ? 255 : 64, 64 );
rect( (currTime % p) / p * width, i*10, 2, 8 );
}
if( bRecording ) {
samplers.get(samplers.size()-1).addSample( currTime, angleToInterpolate ); //
}
for( Sampler s : samplers )
s.drawRecordingWithVertexes( currTime );
}
void mousePressed() {
mouseRecorded = true;
measure=0;
}
void activeSamplingSecond() {
if (measure==0 && actualSec!=lastSec && mouseRecorded == true) {
bRecording = true;
samplers.add( new Sampler( nextSamplePeriod, currTime, angleToInterpolate ) );// work almost with mouseY=v1
}
}
void keyPressed() {
if( key == '1' )
nextSamplePeriod = 1.0;
else if( key == '2' )
nextSamplePeriod = 2.0;
else if( key == '4' )
nextSamplePeriod = 4.0;
else if( key == '8' )
nextSamplePeriod = 8.0;
else if( key == 'X' ) {
if( samplers.size() > 0 )
samplers.remove( samplers.size() - 1 );
}
}
lerp() is an in-built function, see reference
Did you use it?
yes.
Here for 40 point between the first and last point.
for (int i = 0; i <= 40; i++) {
float x = lerp(x1, x2, i/40.0) + 40;
// float y = lerp(y1, y2, i/40.0);
point(x, 100);
}
But my little question is just how can i retreive the fist and the last data of my sample i tried this
for( int i=1; i<samples.size(); i++) {
print ( " interpolatedAngle " + interpolatedAngle + " first angle " + samples.get(0) + " last angle " + samples.get(samples.size()-1));
}
but i read this
interpolatedAngle 3.626964 first angle scudly_sample_chisir_Tangente$Sample@654c74e9 last angle scudly_sample_chisir_Tangente$Sample@5638b99
Ok.
I retreive first and last data like that.
print ( " interpolatedAngle " + interpolatedAngle + " first angle " + samples.get(0).y + " last angle " + samples.get(samples.size()-1).y);
I’m going tot try to interpolate.
retrieve last point x,y - and then its angle a1
retrieve first point x,y - and then its angle a2
then lerp an angle between a1 and a2 in a for loop
calc points from lerp anglle
I think I found the solution with 2 interpolated point! Thank a lot!
int actualSec;
int lastSec;
float mlerp(float x0, float x1, float t, float M ){
float dx = (x1 - x0 + 1.5*M) % M - 0.5*M;
return (x0 + t * dx + M) % M;
}
float firstAngle, lastAngle;
float interpolatedAngle;
float angleToInterpolate;
boolean bRecording = false;
boolean mouseRecorded;
float currTime;
float nextSamplePeriod = 2.0;
int measure;
class Sample {
float t, y;
Sample( float t, float y ) {
this.t = t; this.y = y;
}
}
class Sampler {
ArrayList<Sample> samples;
float startTime;
float sampleLengthTime;
float period;
int playbackFrame;
//**** SCULDY COMPUTATION TO PUT HERE ??
Sampler( float newPeriod, float now, float y ) {
samples = new ArrayList<Sample>();
startTime = now;
addSample( now, y );
playbackFrame = 0;
period = newPeriod;
}
void addSample( float now, float y ) {
samples.add( new Sample( now - startTime, y ) );
sampleLengthTime = now - startTime;
if( sampleLengthTime > period )
bRecording = false;
mouseRecorded = false;
// round up the period to the next power of 2
//period = sampleLengthTime < 1 ? 1 :
// pow( 2, max( 0, ceil( log( sampleLengthTime ) / log(2) ) ) );
}
void drawRecordingWithVertexes( float now ){
if( samples.size() < 2 ) return;
// draw the sample trail
stroke( 200 );
beginShape(LINES);
for( int i=1; i<samples.size(); i++) {
vertex( samples.get(i-1).y, samples.get(i).y ); // replace vertex with Pvector ???
}
endShape();
// draw the current sample point
//float st = (now - startTime) % period;
float st = now % period;
if( st > sampleLengthTime ) return;
if( st < samples.get( playbackFrame ).t ) playbackFrame = 0;
while( samples.get( playbackFrame+1).t < st )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samples.get( playbackFrame );
Sample s1 = samples.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (st - t0) / (t1 - t0);
// float x = mlerp( s0.x, s1.x, dt, 400 ); // interpolation with 'continious datas'
// float y = mlerp( s0.y, s1.y, dt, TWO_PI ); // interpolation with 'radian datas'
float y = mlerp( s0.y, s1.y, dt, TWO_PI ); // interpolation with 'radian datas' // angle interpolated between themselves not from the first and the last!
print ( " y " + y + " first angle " + samples.get(0).y + " last angle " + samples.get(samples.size()-1).y);
firstAngle = samples.get(0).y ;
lastAngle = samples.get(samples.size()-1).y ;
noStroke();
fill( 255, 40, 40 );
circle ( 100* cos ( y)+400, 100*sin ( y)+200, 20);
for (int i = 0; i <= 2; i++) {
interpolatedAngle = lerp(firstAngle, lastAngle, i/2.0);
fill( 255, 127*i, 127*i );
circle ( 100* cos ( interpolatedAngle)+400, 100*sin ( interpolatedAngle)+200, 20);
}
}
}
Sampler sampler;
ArrayList<Sampler> samplers;
void setup() {
size( 800, 800, P3D );
frameRate( 30 );
samplers = new ArrayList<Sampler>();
}
void draw() {
println ( " measure " + measure );
if (actualSec<lastSec){
measure=measure+1;
}
lastSec=actualSec;
actualSec = millis()%1000; // Values from 0 - 2
activeSamplingSecond();
samplingMovementPro();
angleToInterpolate = calcAngle();
fill( 100, 0, 0);
circle ( 100* cos (angleToInterpolate)+200, 100*sin (angleToInterpolate)+200, 20);
//----------------------------------------
pushMatrix();
translate(width/2, height/2);
rotate(angleToInterpolate);
translate(28, 0);
rect(-30, -5, 60, 10);
popMatrix();
//----------------------------------------
ellipse(width/2, height/2, 5, 5);
text(degrees(angleToInterpolate), 22, 22);
}
//----------------------------------------------------------------------
float calcAngle() {
float a = atan2(mouseY-height/2, mouseX-width/2);
if (a<0) {
a=map(a, -PI, 0,
PI, TWO_PI);
}
return a;
}
void samplingMovementPro() {
currTime = millis() * 0.001; // seconds since app started
background( 0 );
for( int i=0; i<3; i++ ) {
float p = pow( 2, i );
stroke( 64, p == nextSamplePeriod ? 255 : 64, 64 );
rect( (currTime % p) / p * width, i*10, 2, 8 );
}
if( bRecording ) {
samplers.get(samplers.size()-1).addSample( currTime, angleToInterpolate ); //
}
for( Sampler s : samplers )
s.drawRecordingWithVertexes( currTime );
}
void mousePressed() {
mouseRecorded = true;
measure=0;
}
void activeSamplingSecond() {
if (measure==0 && actualSec!=lastSec && mouseRecorded == true) {
bRecording = true;
samplers.add( new Sampler( nextSamplePeriod, currTime, angleToInterpolate ) );// work almost with mouseY=v1
}
}
void keyPressed() {
if( key == '1' )
nextSamplePeriod = 1.0;
else if( key == '2' )
nextSamplePeriod = 2.0;
else if( key == '4' )
nextSamplePeriod = 4.0;
else if( key == '8' )
nextSamplePeriod = 8.0;
else if( key == 'X' ) {
if( samplers.size() > 0 )
samplers.remove( samplers.size() - 1 );
}
}
But when I play back the mouvement, the circle doesn’t follow interpolated point.
How can I put them in the play back ?
How can I keep the play back movement for 2 seconds?
you have to add the new found points to the samples ArrayList?
Tricky.
Is it too fast or too slow at the moment?
maybe get rid of this. Then work with a timer,
- When (2 * 1000 / number of points) milliseconds have passed, move to the next point in your animation.
Yes It’s totally my question, but i will never can do that by myself!
Should i post a new request?
it’s a good idea to do this
Hi again !
I tried to mix your program with one made by an engineer.
The goal is the same, to create an intermediate point. An an other option if the movement pass through the first point.
But it saves data with another method, so I have a little bug when I press the mouse.
Could you have a glance please?
int actualSec,lastSec,measure,measureToStartRecording;;
boolean bRecording = false;
boolean mouseRecorded = true;
float firstAngle, lastAngle;
float interpolatedAngle;
float angleToInterpolate;
float currTime;
float nextSamplePeriod = 2.0;
class Sample {
int t;
float x, y;
Sample( int t, float x, float y ) {
this.t = t; this.x = x; this.y = y;
}
}
class Sampler {
ArrayList<Sample> samples;
ArrayList<Sample> samplesModified;
int startTime;
int playbackFrame;
Sampler() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
startTime = 0;
}
void beginRecording() {
samples = new ArrayList<Sample>();
samplesModified = new ArrayList<Sample>();
playbackFrame = 0;
}
void addSample( float x, float y ) { // add radian sample when bRecording
int now = millis();
if( samples.size() == 0 ) startTime = now;
samples.add( new Sample( now - startTime, x, y ) );
}
int fullTime() {
return ( samples.size() > 1 ) ?
samples.get( samples.size()-1 ).t : 0;
}
void beginPlaying() {
startTime = millis();
playbackFrame = 0;
println( samples.size(), "samples over", fullTime(), "milliseconds" );
if(samples.size() > 0){
float deltax = samples.get(0).x - samples.get(samples.size()-1).x;
float deltay = samples.get(0).y - samples.get(samples.size()-1).y;
float sumdist = 0;
for(int i = 0; i < samples.size() - 1; i++) {
sumdist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
}
samplesModified.add( new Sample(samples.get(0).t, samples.get(0).x , samples.get(0).y ) );
float dist = 0;
for(int i = 0; i < samples.size() - 1; i++) {
dist += sqrt((samples.get(i).x - samples.get(i +1 ).x)*(samples.get(i).x - samples.get(i +1 ).x) + (samples.get(i).y - samples.get(i +1 ).y)*(samples.get(i).y - samples.get(i +1 ).y));
samplesModified.add( new Sample(samples.get(i+1).t, (int) (samples.get(i +1).x + (dist * deltax) / sumdist), (int) (samples.get(i+1).y +( dist * deltay )/ sumdist)) );
print(samples.get(i).x);
print(",");
print(samples.get(i).y);
print(",");
print(samplesModified.get(i).x);
print(",");
print(samplesModified.get(i).y);
println("");
}
}
}
void draw() {
stroke( 255 );
//**RECORD
beginShape(LINES);
for( int i=1; i<samples.size(); i++) {
vertex( samplesModified.get(i-1).x, samplesModified.get(i-1).y ); // replace vertex with Pvector
vertex( samplesModified.get(i).x, samplesModified.get(i).y );
}
endShape();
//**ENDRECORD
//**REPEAT
int now = (millis() - startTime) % fullTime();
if( now < samplesModified.get( playbackFrame ).t ) playbackFrame = 0;
while( samplesModified.get( playbackFrame+1).t < now )
playbackFrame = (playbackFrame+1) % (samples.size()-1);
Sample s0 = samplesModified.get( playbackFrame );
Sample s1 = samplesModified.get( playbackFrame+1 );
float t0 = s0.t;
float t1 = s1.t;
float dt = (now - t0) / (t1 - t0);
float x = lerp( s0.x, s1.x, dt );
float y = lerp( s0.y, s1.y, dt );
circle( x, y, 10 );
}
}
Sampler sampler;
ArrayList<Sampler> samplers;
void setup() {
size( 800, 800, P3D );
frameRate(30); // when size is set as P3D (3 dimension) we have 27 or 28 frame (loop) per seconde
sampler = new Sampler();
}
void draw() {
background( 0 );
activeSampling();
stopSampling();
if (actualSec!=lastSec){
lastSec=actualSec;
measure++;
textSize (100);
text (measure, 100, 100 );
}
actualSec =(int) (millis()*0.001); //
samplingMovementPro();
angleToInterpolate = calcAngle();
fill( 100, 0, 0);
circle ( 100* cos (angleToInterpolate)+200, 100*sin (angleToInterpolate)+200, 20);
//----------------------------------------
pushMatrix();
translate(width/2, height/2);
rotate(angleToInterpolate);
translate(28, 0);
rect(-30, -5, 60, 10);
popMatrix();
//----------------------------------------
ellipse(width/2, height/2, 5, 5);
text(degrees(angleToInterpolate), 22, 22);
}
float calcAngle() {
float a = atan2(mouseY-height/2, mouseX-width/2);
if (a<0) {
a=map(a, -PI, 0,
PI, TWO_PI);
}
return a;
}
void samplingMovementPro(){
currTime = millis() * 0.001; // seconds since app started
background( 0 );
for( int i=0; i<3; i++ ) {
float p = pow( 2, i );
stroke( 64, p == nextSamplePeriod ? 255 : 64, 64 );
rect( (currTime % p) / p * width, i*10, 2, 8 );
}
if( bRecording) { // recole radian
samplers.get(samplers.size()-1).addSample( angleToInterpolate, angleToInterpolate ); //
}
else {
if( sampler.fullTime() > 0 )
sampler.draw();
}
}
void mousePressed() {
bRecording = true; // draw circle
mouseRecorded = true;
measure=0;
}
void activeSampling() {
if (measure==1 && actualSec!=lastSec && mouseRecorded == true) {
sampler.beginRecording();
}
}
void stopSampling() {
if (measure==3 && actualSec!=lastSec) {
mouseRecorded = false;
//**REPEAT
bRecording = false;
sampler.beginPlaying();
}
}
really I don’t have time
you need to understand the principles at work and then apply them
it’s your program.