# Create an intermediate point

**URL:** https://discourse.processing.org/t/create-an-intermediate-point/41318
**Category:** Coding Questions
**Created:** [March 16, 2023, 12:05pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318 "2023-03-16T12:05:46Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 16, 2023, 12:05pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/1 "2023-03-16T12:05:46Z")

</div>

Hello all!

For an artistic project, I sample for two seconds a pseudo circle (not entirely finished) drawn with the mouse.  
Then this shape repeats itself.

I would like to add between the last and the first point drawn, “an interpolation point” or more simply an intermediate point which is placed at the average  
of the affine line created by the first and the last.

To draw a pseudo circle over two seconds, you have to keep the mouse pressed. The recording is done at each change of second.  
(but we’re not supposed to know that).

Thanks for your help 😉

 ![Capture d’écran 2023-03-16 à 13.09.13](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/9/1/91d89cbd646004c64ebf43a9f75ecc7c417c1ad0.png)

```auto
int actualSec,lastSec,measure,measureToStartRecording;
boolean bRecording = false;
boolean mouseRecorded = true;

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;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = 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" );
  }
  
 
  void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samples.get(i-1).x, samples.get(i-1).y ); // replace vertex with Pvector
      vertex( samples.get(i).x, samples.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samples.get( playbackFrame ).t ) playbackFrame = 0;
    while( samples.get( playbackFrame+1).t < now )
      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 = (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;

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

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

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 16, 2023, 3:15pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/2 "2023-03-16T15:15:11Z")

</div>

> [@bking](#):
>
> `sampler.addSample( mouseX, mouseY );`

I suggest to only add when

```auto
if( mouseX!=pmouseX ||
 mouseY!=pmouseY)

```

**Regarding your question:**

Isn’t the intermediate just the center between start and end, so the middle of the Arraylist? Just like  
` int (list.size() /2.0)`

---

<div class="post-metadata">

### Author: ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)
#### Post date: [March 16, 2023, 3:31pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/3 "2023-03-16T15:31:08Z")

</div>

> [@Chrisir](#):
>
> Isn’t the intermediate just the center between start and end, so the middle of the Arraylist? Just like  
> int (list.size() /2.0)

I think he means to complete the circle so the mid point between start and and end is not the mid point of the list.

> [@bking](#):
>
> (but we’re not supposed to know that).

So this is homework? If so no full code solutions.

We need to find the start and last points drawn so let’s look at the mousePressed method

> [@bking](#):
>
> ```auto
> void mousePressed() {
> // if we are NOT recording i.e. bRecording is false then the mouse has just
> // been pressed so we can store the start position for the curve
> bRecording = true; // draw circle
> mouseRecorded = true;
> measure=0;
> }
> 
> ```

Now add a mouseReleased method

```auto
void mouseReleased() {
  // if we are recording i.e. bRecording is true then the mouse has just 
  // been released so we can store the end position for the curve
  // Now you have start and end positions the mid point between 
  // them can be added to the curve.
}

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 16, 2023, 5:23pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/4 "2023-03-16T17:23:23Z")

</div>

Hi,

Yes, maybe there is a command computing the middle of the last and the beginning of an arrayList.  
Or something else computing the middle of a vector from the last and the beginning point.  
Then it might be easy to add this point at the end of the array list.  
But I really don’t know how to proceed.  
Thank again for helping!

I add you code line 100 like that but the program doesn’t understand.

```auto
int actualSec,lastSec,measure,measureToStartRecording;;
boolean bRecording = false;
boolean mouseRecorded = true;

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;
  int startTime;
  int playbackFrame;
  
  Sampler() {
    samples = new ArrayList<Sample>();
    startTime = 0;
  }
  void beginRecording() {   
    samples = new ArrayList<Sample>();
    print (samples);
    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" );
  }
  
  
  void draw() {
    stroke( 255 );
    
    //**RECORD
    beginShape(LINES);
    for( int i=1; i<samples.size(); i++) {
      vertex( samples.get(i-1).x, samples.get(i-1).y ); // replace vertex with Pvector
      vertex( samples.get(i).x, samples.get(i).y );
    }
    endShape();
    //**ENDRECORD
    
    //**REPEAT
    int now = (millis() - startTime) % fullTime();
    if( now < samples.get( playbackFrame ).t ) playbackFrame = 0;
    while( samples.get( playbackFrame+1).t < now )
      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 = (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 (frameCount + " x " + x);
  }
  
}

Sampler sampler;

void setup() {  
  size( 800, 800, P3D );
  frameRate( 30 );  
  sampler = new Sampler();
}

void draw() {
 // text ( "bla" , 200, 200);
  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 );
   //*** Chisir Method 
 // if( mouseX!=pmouseX || mouseY!=pmouseY) {   
 // int (list.size() /2.0)
   }
  }
  
  else {    
  if( sampler.fullTime() > 0 )
        sampler.draw();    
  }  
}

void mouseReleased() {
  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();
  }
}

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 16, 2023, 5:26pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/5 "2023-03-16T17:26:56Z")

</div>

> [@quark](#):
>
> think he means to complete the circle so the mid point between start and and end is not the mid point of the list.

I think you’re right, the mid point is the average point between the last and the fist point of the array list.

I changed with mouseReleased() and it doesn’t change anything!

Thanks again.

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 18, 2023, 12:13pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/6 "2023-03-18T12:13:45Z")

</div>

Hi again!  
How can we get the last and the first data of the arrayList?

Then I will have two add a point calculated like that

 ![Capture d’écran 2023-03-18 à 13.12.37](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/6/9/6930d6364ff73c3d87eb26ec3b29ae8e75753e11.png)  
Thanks again

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 18, 2023, 12:15pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/7 "2023-03-18T12:15:15Z")

</div>

list.get(0)  
and

list.get(list.size()-1)

Maybe even list.last()

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 18, 2023, 1:23pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/8 "2023-03-18T13:23:50Z")

</div>

> [@Chrisir](#):
>
> size()-1

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?

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 18, 2023, 1:33pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/9 "2023-03-18T13:33:11Z")

</div>

here is an example

see last paragraph in draw() pls

you need to click two points with the mouse into my program

```auto

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);
  }
}

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 18, 2023, 1:36pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/10 "2023-03-18T13:36:02Z")

</div>

> [@bking](#):
>
> `println ( " lastDataOfTheSample " + list.get(list.size()-1);`

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:

```auto

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);
  }
}

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 19, 2023, 1:35pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/11 "2023-03-19T13:35:26Z")

</div>

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!

```auto
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();
    }

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 19, 2023, 3:23pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/12 "2023-03-19T15:23:30Z")

</div>

> [@bking](#):
>
> I sample for two seconds a pseudo circle (not entirely finished) drawn with the mouse.  
> Then this shape repeats itself.

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?

> [@bking](#):
>
> The recording is done at each change of second.

I don’t think this is true. He’s recording throughout - or what do you mean?

> [@bking](#):
>
> ```auto
> void activeSampling() { 
> if (measure<=1 && measure>=1 
> 
> ```

not sure, but measure can’t be \< 1 AND \> 1 at the same time. Hence you mean `measure==1`?

* * *

**movementInterpolated**

> [@bking](#):
>
> 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

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`:

```auto
    // 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**

```auto

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
//

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 19, 2023, 4:05pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/13 "2023-03-19T16:05:45Z")

</div>

![Capture d’écran 2023-03-19 à 16.55.13](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/f/0/f00800e2a598fce9ad1c3374ba8532a22246d6ed.png)

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

```auto

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
//

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 21, 2023, 7:14pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/14 "2023-03-21T19:14:25Z")

</div>

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

> [@Interpolation between two radian angle. Circular movement and Perfect arabesque to reach ;)](https://discourse.processing.org/t/interpolation-between-two-radian-angle-perfect-movement-to-reach/41395):
>
> Hi ! I’m trying to sample movements on a motor position sensor. This movement goes more or less quickly and always in the same direction. The first goal is: To repeat these circular movements and ensure that there is at least one transition point between the first and the last recorded point. I manage to create 2 interpolated point but I have to put them back in sampled datas and keeping the mouvement played back for 2 sec. (If i record a movement for 2 second)

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 21, 2023, 8:11pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/15 "2023-03-21T20:11:36Z")

</div>

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 use `lerp()` 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:

```auto
float x=cos(a_intermediate) * r + centerX; 
float y=sin(a_intermediate) * r + centerY;

```

Warm regards,

Chrisir

* * *

**Full Sketch**

(without the remark above)

```auto

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;
}
//

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 21, 2023, 8:16pm UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/16 "2023-03-21T20:16:59Z")

</div>

new version where the points on the circle are shown separately using :

```auto
  stroke(255, 0, 0);
  ellipse(
    cos(a) * 150 + width/2.0,
    sin(a) * 150 + height/2.0,
    4,
    4
    );

```

* * *

**Full Sketch**

```auto

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;
}
//

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 22, 2023, 9:04am UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/17 "2023-03-22T09:04:50Z")

</div>

Hi,

I changed the program with yours remarks.  
It 's totatlly better to record position of the ball like that. 🙂  
As you said :

> [@Chrisir](#):
>
> or use `lerp()` between the angles a1 and a2 (not between the points obviously).

That’s i’m tring to do but i do not retreive the first and the last datas sampled 🥶

Here my changes

```auto
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 );
  }
}

```

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 22, 2023, 9:10am UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/18 "2023-03-22T09:10:40Z")

</div>

lerp() is an in-built function, see reference

Did you use it?

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 22, 2023, 9:18am UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/19 "2023-03-22T09:18:39Z")

</div>

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

```auto
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

```auto
interpolatedAngle 3.626964 first angle scudly_sample_chisir_Tangente$Sample@654c74e9 last angle scudly_sample_chisir_Tangente$Sample@5638b99

```

---

<div class="post-metadata">

### Author: ![bking](https://avatars.discourse-cdn.com/v4/letter/b/dc4da7/32.png) [@bking](https://discourse.processing.org/u/bking)
#### Post date: [March 22, 2023, 9:23am UTC](https://discourse.processing.org/t/create-an-intermediate-point/41318/20 "2023-03-22T09:23:31Z")

</div>

Ok.  
I retreive first and last data like that.

```auto
    print ( " interpolatedAngle " + interpolatedAngle + " first angle " + samples.get(0).y + " last angle " + samples.get(samples.size()-1).y); 

```

I’m going tot try to interpolate.

[Next page](https://discourse.processing.org/t/create-an-intermediate-point/41318.md?page=2)
