# How can i get a line to move in a curve to a specific region on the canvas?

**URL:** <https://discourse.processing.org/t/how-can-i-get-a-line-to-move-in-a-curve-to-a-specific-region-on-the-canvas/19656>\
**Category:** Coding Questions\
**Tags:** homework\
**Created:** [April 11, 2020, 12:30pm UTC](https://discourse.processing.org/t/how-can-i-get-a-line-to-move-in-a-curve-to-a-specific-region-on-the-canvas/19656 "2020-04-11T12:30:14Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![yasinyer](https://avatars.discourse-cdn.com/v4/letter/y/ce73a5/32.png) [@yasinyer](https://discourse.processing.org/u/yasinyer)\
**Post date:** [April 11, 2020, 12:30pm UTC](https://discourse.processing.org/t/how-can-i-get-a-line-to-move-in-a-curve-to-a-specific-region-on-the-canvas/19656/1 "2020-04-11T12:30:14Z")

</div>

Hi guys!

I’m a newbie in programming and could really use the help of you experts for my bachelor project.

What I already have is a line that moves in a curve when turning, based on the arrowkeys. This line is only able to turn left, right, speed up and down.  
What I would like to have is a line that is attracted -with a curvy movement like now- by a specific region (see image) on the screen (when pressed on keyboard for example).

Could somebody please help me with this? It would mean so much to me!

 ![unnamed (8)](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/2/2f4fcc3f1ac75e7c6cc94799cf6cad6aa3a2434a.png)

```auto
let branch;

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(0);
  branch = new Branch(width / 2, height / 2);
}

function draw() {
  if (keyIsPressed) {
    if (keyCode == LEFT_ARROW) {
      branch.turn(1);
    } else if (keyCode == RIGHT_ARROW) {
      branch.turn(-1);
    } else if (keyCode == UP_ARROW) {
      branch.changeSpeed(1);
    } else if (keyCode == DOWN_ARROW) {
      branch.changeSpeed(-1);
    }
  }
  branch.update();
}

class Branch {
  constructor(_x, _y) {
    this.x = _x;
    this.y = _y;
    this.px = _x;
    this.py = _y;
    this.s = 0;
    this.a = PI;
    this.d = 0.05;
  }
  update() {
    this.move();
    this.checkEdges();
    this.show();
  }
  move() {
    this.px = this.x;
    this.py = this.y;
    this.x = this.px + sin(this.a) * this.s;
    this.y = this.py + cos(this.a) * this.s;
  }
  checkEdges() {
    if (this.x > width) {
      this.x = 0;
      this.px = this.x;
    } else if (this.x < 0) {
      this.x = width;
      this.px = this.x;
    }
    if (this.y > height) {
      this.y = 0;
      this.py = this.y;
    } else if (this.y < 0) {
      this.y = height;
      this.py = this.y;
    }
  }
  turn(_d) {
    this.a += _d * this.d;
  }
  changeSpeed(_s) {
    this.s = constrain(this.s + (_s * this.d), 0, 3);
  }
  show() {
    stroke(255);
    strokeWeight(3);
    line(this.px, this.py, this.x, this.y);
  }
}

```

---

<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:** [April 11, 2020, 6:54pm UTC](https://discourse.processing.org/t/how-can-i-get-a-line-to-move-in-a-curve-to-a-specific-region-on-the-canvas/19656/2 "2020-04-11T18:54:57Z")

</div>

Do you want to **replace** the arrow keys by an **automatic function** that would steer the ellipse to the points cat, pappa, law and oh etc. one after another (maybe these points in an random order) ?

---

<div class="post-metadata">

**Author:** ![yasinyer](https://avatars.discourse-cdn.com/v4/letter/y/ce73a5/32.png) [@yasinyer](https://discourse.processing.org/u/yasinyer)\
**Post date:** [April 12, 2020, 11:30am UTC](https://discourse.processing.org/t/how-can-i-get-a-line-to-move-in-a-curve-to-a-specific-region-on-the-canvas/19656/3 "2020-04-12T11:30:58Z")

</div>

Thanks for your input! I actually don’t know how to do that. I made it possible to use speech recognition and when these vowels are recognized, I would like the line to move to a specific direction. For the sake of keeping the question more simple it’s a good start to try it with keyboard presses.

Would you know how to help me with this?

---

<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:** [April 13, 2020, 1:04pm UTC](https://discourse.processing.org/t/how-can-i-get-a-line-to-move-in-a-curve-to-a-specific-region-on-the-canvas/19656/4 "2020-04-13T13:04:29Z")

</div>

here is an example (processing, not p5)

- he’s following the points stored in targets
- variable easing dictates how tight the curves are
- activeSteering() is the interesting part
- maybe it’d look cooler when he’d turn on the screen borders instead of crossing them

Chrisir

```auto
// Walker towards targets

Branch branch;

PVector[] targets = new PVector[15];
int indexTarget=0;

//easing for the angle 
float easing = 0.23; // 0.061288;

int timer; 

void setup() {
  size(990, 800);

  background(0);
  branch = new Branch(width / 2, height / 2);

  // fill targets randomly 
  for (int i2=0; i2<targets.length; i2++) { 
    targets[i2] = new PVector (random(width), random(height));
  }

  timer = millis();
}// func 

void draw() {
  // background(0);

  // readKeys(); 

  branch.update();

  // show target
  showTargets(); 

  // after timer is up 
  if (millis()-timer>1000) {
    // active steering
    activeSteering();
  }//if timer
  //
}//func

//-----------------------------------------------------------------------------------------------------

void showTargets() {
  // show current target
  // fill(255, 0, 0);
  // noStroke(); 
  // ellipse (targets[indexTarget].x, targets[indexTarget].y, 17, 17);

  // show ALL targets 
  int i3=0; 
  strokeWeight(1); 
  for (PVector pv : targets) {
    stroke(111);
    // different shades of red 
    fill( map(i3, 0, targets.length, 40, 255), 0, 0);
    // show current target in BLUE
    if (i3==indexTarget) 
      fill(0, 0, 255); //BLUE
    ellipse (pv.x, pv.y, 
      17, 17);
    i3++;
  }
}//func 

void activeSteering() {
  // active steering

  // core idea
  float targetAngle=getAngle();
  // showLine(targetAngle); // only for debug 

  if (targetAngle>branch.a) 
    branch.turn(1 * easing);
  else if (targetAngle<branch.a) 
    branch.turn(-1 * easing);
  else if (targetAngle==branch.a) {
    // ignore
    // branch.a = 0;
  }

  // when we reach a target we go to next target 
  if (dist(targets[indexTarget].x, targets[indexTarget].y, branch.x, branch.y)<2) {
    indexTarget++;
    // easing+=.103; // change it 
    println("ellipse: "
      +indexTarget
      +" with easing: "
      +easing);
    timer = millis(); // timer 
    // make a random deviation 
    if (random(100) > 50)
      branch.turn(random(4));
    else 
    branch.turn(-random(4));
    // end of array? 
    if (indexTarget>=targets.length)
      indexTarget=0; //reset
  }//if
}//func 

void readKeys() {
  /*
  if (keyPressed) {
   if (keyCode == LEFT) {
   branch.turn(1);
   } else if (keyCode == RIGHT) {
   branch.turn(-1);
   } else if (keyCode == UP) {
   branch.changeSpeed(1);
   } else if (keyCode == DOWN) {
   branch.changeSpeed(-1);
   }
   }
   */
}// func 

void showLine(float a) {   
  // only for debug 
  pushMatrix();
  translate(branch.x, branch.y); 
  rotate(a);
  translate(28, 0);
  fill(0, 0, 255);
  rect(-30, -5, 60, 10);
  popMatrix();
}

float getAngle() {
  // core idea

  float a = atan2(
    targets[indexTarget].y-branch.y, 
    targets[indexTarget].x-branch.x);

  //----------------------------------------
  if (a<0) {
    a=map(a, -PI, 0, 
      PI, TWO_PI);
  }

  return a;
}

//==========================================================================

class Branch {

  float x, y; // pos 
  float px, py; // prev pos 
  float s, // speed 
    a, // angle 
    d; // damping? 

  Branch(float _x, float _y) {
    this.x = _x;
    this.y = _y;
    this.px = _x;
    this.py = _y;

    this.s = 1;
    this.a = TWO_PI-PI/2; // PI;
    this.d = 0.05;
  }

  void update() {
    this.move();
    this.checkEdges();
    this.show();
  }

  void move() {
    this.px = this.x;
    this.py = this.y;

    this.x = this.px + cos(this.a) * this.s;
    this.y = this.py + sin(this.a) * this.s;
  }

  void checkEdges() {
    if (this.x > width) {
      this.x = 0;
      this.px = this.x;
    } else if (this.x < 0) {
      this.x = width;
      this.px = this.x;
    }

    if (this.y > height) {
      this.y = 0;
      this.py = this.y;
    } else if (this.y < 0) {
      this.y = height;
      this.py = this.y;
    }
  }

  void turn(float _t) {
    this.a += _t * this.d;
  }

  void changeSpeed(float _s) {
    this.s =
      constrain(this.s + (_s * this.d), 0, 3);
  }

  void show() {
    // stroke(255);
    stroke(0, 255, 0);
    strokeWeight(3);
    line(this.px, this.py, 
      this.x, this.y);
  }
}//class
//

```
