Create an intermediate point

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?

1 Like

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();
  }
}
1 Like

really I don’t have time

you need to understand the principles at work and then apply them

it’s your program.