> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.AvdPwKfPvNd/rev.422
 * 
 * authors: 
 *   
 *   Scott Mahr

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// This sketch builds on a prior work, "StrafeBot Keyboard", created by Scott Mahr & [unnamed author]
// http://studio.sketchpad.cc/sp/pad/view/ro.9Sg03jSMhNBXy/rev.3368


// 1 - render something that looks like a strafe bot
// 2 - make it move around with key presses
// 3 - have it draw and remember the path that it took
// 4 - output the path as motor velocities
// 

bool drawOn = false;
bool ledOn = 0;

int mem = 400;
int[][][] pos = new int[5][mem][2]; 
int posIdx = 0;

float m;float a;float b;float c;
float sv;float cv;float[][] cnrs;
int[] cur = {200,200,45}; 
int[] max = {800,400,360}; 

int stepMax = 4;
int stepMin = 2;
float mDist = 0;
int mx = 0; int my = 0;

int step = 2;
    
void setup()
{
  size(800, 400);
  noStroke();
  background(0);
  
  frameRate(15);
}

void draw()
{ 
  smooth(); 
  background(0);
  noStroke();
  fill(226);  
  
  pushMatrix();
  translate(cur[0], cur[1]); 
  rotate(radians(cur[2]));
  drawBot();
  popMatrix();
  drawPath();


  if(drawOn){
    mDist = getMouseDist();
    if(mDist<=stepMax && mDist>=stepMin){
      cur[0]= mouseX; cur[1]=mouseY;   
      addPoint();
    }
    else if(mDist>=stepMin){
      cur[0] = (mouseX-cur[0])*stepMax/mDist+cur[0];
      cur[1] = (mouseY-cur[1])*stepMax/mDist+cur[1];
      addPoint();   
    }
      
      
  }


  if(keyPressed || mousePressed){
   // addPoint();
    if(keyPressed){
      if(key == 'w'){cur[1] -= step;}
      if(key == 'a'){cur[0] -= step;}
      if(key == 'd'){cur[0] += step;}
      if(key == 's'){cur[1] += step;}
    }
    if(mousePressed && false){
        cur[2] += (mouseX-200)/15;  
    }
    for(int i=0;i<2;i++){
      if(cur[i]<0){cur[i]==0;}
      if(cur[i]>max[i]){cur[i]==max[i];} 
    }
    if(cur[2] < 0){cur[2] += max[2];}
    if(cur[2] > max[2]){cur[2] -= max[2];}
  }
}

void mouseClicked() {
  drawOn = !drawOn;
}



float getMouseDist(){
  return sqrt(sq(mouseX-cur[0])+sq(mouseY-cur[1]));
}

void addPoint()
{
    sv = sin(radians(cur[2]))*30;
    cv = cos(radians(cur[2]))*30;
    cnrs = {{sv,-cv},{-sv,cv},{-cv,-sv},{cv,sv}};
    for(int i=0;i<4;i++){
        for(int j=0;j<2;j++){
            pos[i][posIdx][j] = cur[j]+cnrs[i][j];
        }
        
    }
    pos[4][posIdx][0]=ledOn;
    posIdx +=1; 
    if(posIdx >= mem){posIdx = 0;}   
}

void drawPath()
{
  for(int i = 1; i < mem; i = i+1){
      float[] vel = getSpeed(i-1);
      //float[] vel = [0,0,0,0];
      for(int j=0;j<4;j++){
       if(vel[j]<0){stroke(255,0,0);}
       else if(vel[j]>0){stroke(0,0,255);}
       else(stroke(0,255,0);}
       point(pos[j][i][0], pos[j][i][1]);
    }
  }
}

void drawBot()
{
  quad(0, 0-30, 0+30, 0, 0, 0+30, 0-30, 0);
  rect(0-5, 0-33, 10, 6);
  
  rect(0-5, 0+30, 10, 3);
  rect(0-33, 0-5, 3 ,10);
  rect(0+30, 0-5, 3, 10); 
}

//this is for calculation
float[] getSpeed(int idx)
{
  m = 1.0*(pos[1][idx][1]-pos[0][idx][1])/(pos[1][idx][0]-pos[0][idx][0]); 
  a = -m;
  b = 1;
  c = -pos[1][idx][1]+m*pos[1][idx][0];
  a2 = 1/m;
  c2 = -pos[3][idx][1]-1/m*pos[3][idx][0];
  float[] vel = new float[4];
  for(int j=0;j<4;j++){   
    if(j<2){
      vel[j] = (a*pos[j][idx+1][0]+b*pos[j][idx+1][1]+c)/sqrt(sq(a)+sq(b));
      
    }
    else{
      vel[j]=(a2*pos[j][idx+1][0]+b*pos[j][idx+1][1]+c2)/sqrt(sq(a2)+sq(b));
      vel[j] *= m/abs(m);
    }
  }
  
  if(pos[0][idx][0]>pos[1][idx][0]){vel[0]*=-1;}
  else{vel[1]*=-1;}
  
  if(pos[2][idx][1]<pos[3][idx][1]){vel[2]*=-1;}
  else{vel[3]*=-1;}
  
  return vel; 
}

void keyReleased() 
{
  if(key == 'l'){if(ledOn){ledOn=0;}else{ledOn=1;}}
  
  if(key == 'p') {
    for(int i = 1; i < mem; i = i+1){
      float[] vel = getSpeed(i-1);
      print("line"+i);
      for(int j=0;j<4;j++){
        print(","+round(vel[j]*100)/100);
      }
      print(",");
      print(pos[4][i][0]);
      print("\n");
    }
    println("done");
  }
}