# Using vectors to find the line between two lines

**URL:** <https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856>\
**Category:** Coding Questions\
**Created:** [April 27, 2023, 2:50pm UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856 "2023-04-27T14:50:16Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![paulstgeorge](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@paulstgeorge](https://discourse.processing.org/u/paulstgeorge)\
**Post date:** [April 27, 2023, 2:50pm UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/1 "2023-04-27T14:50:16Z")

</div>

I can do this (see sketch) with lerp(), but it cannot be the best way. Using lerp() and starting at the desired angle, one would have to use tan(), then solve two equations before knowing what value to give lerp(). Then I would need to lengthen the line. All doable, but inelegant.

I am guessing the cross formula is the way to go, but I could see further if I stood on the shoulders of giants.

![lerp1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/0/c/0cd508614b4c70d48d614530e332baa1c8a5ff5c.png)

```auto
PVector a, b, c;
PVector middle;
float angle = 0.5;
float m;

void setup() {
  size(400, 400, P3D);

  a = new PVector(0, 0, 0);
  b = new PVector(100, 100, 0);
  c = new PVector(100, -100, 0);

  m = PVector.dist(a, b);
}

void draw() {
  background(255);
  strokeWeight(1);
  //noLoop();
  //println(mouseX);
  angle = 1-(mouseY/float(height));

  translate(width/2, height/2); // move (0, 0, 0) to centre of window

  stroke(0, 0, 0);

  line(a.x, a.y, a.z, b.x, b.y, b.z);
  line(a.x, a.y, a.z, c.x, c.y, c.z);

  middle = PVector.lerp(b, c, angle);
  middle.normalize();
  middle.mult(m);
  stroke(0, 0, 127);
  line(a.x, a.y, a.z, middle.x, middle.y, middle.z);

  pushMatrix(); // move (0, 0, 0) back to centre of window
  translate(a.x, a.y, a.z);
  noFill();
  stroke(0);
  sphere(4);
  popMatrix();

  pushMatrix(); 
  translate(b.x, b.y, b.z);
  noFill();
  stroke(0);
  sphere(4);
  popMatrix();

  pushMatrix(); 
  translate(c.x, c.y, c.z);
  noFill();
  stroke(0);
  sphere(4);
  popMatrix();

  pushMatrix(); 
  translate(middle.x, middle.y, middle.z);
  noFill();
  stroke(127);
  sphere(4);
  popMatrix();
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [April 27, 2023, 9:29pm UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/2 "2023-04-27T21:29:42Z")

</div>

Hello @paulstgeorge,

This will display a line between two vectors but not return the vector:

```auto
//https://github.com/processing/processing4/blob/main/core/src/processing/core/PApplet.java#L12888

PVector a, b, c, ax, v;

float x, y, z;

void setup() 
 {
 size(400, 400, P3D);

 a = new PVector(0, 0, 0);
 b = new PVector(100, 100, 50);
 c = new PVector(100, -100, -50);
 ax = new PVector(0, 0, 0);
 v = new PVector(0, 0, 0);
 }

void draw() 
 {
 background(255);

 float angleBetween = PVector.angleBetween(b, c);
 float angle = map(mouseX, 0, width, 0, angleBetween);

 translate(width/2, height/2); // move (0, 0, 0) to centre of window
 rotateY(frameCount%360*(TAU/360)); // This will mess with modelX below

 stroke(0);
 strokeWeight(2);

 line(a.x, a.y, a.z, b.x, b.y, b.z);
 line(a.x, a.y, a.z, c.x, c.y, c.z);
 
 ax = b.cross(c).normalize(); //normalize may not be needed

 // Rotates a line about an axis
 stroke(255, 128, 0);
 pushMatrix();
 rotV(angle, ax);
 line(a.x, a.y, a.z, b.x, b.y, b.z);
 popMatrix();
 }
 
void rotV(float angle, PVector axis) 
 {
 rotate(angle, axis.x, axis.y, axis.z);
 }

```

References:

This gem is not in the on-line references:  
[https://github.com/processing/processing4/blob/main/core/src/processing/core/PApplet.java#L12888](https://github.com/processing/processing4/blob/main/core/src/processing/core/PApplet.java#L12888)

> **[angleBetween() / Reference](https://processing.org/reference/PVector_angleBetween_.html)**
>
> Calculates and returns the angle (in radians) between two vectors.

`:)`

---

<div class="post-metadata">

**Author:** ![paulstgeorge](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@paulstgeorge](https://discourse.processing.org/u/paulstgeorge)\
**Post date:** [April 28, 2023, 8:47am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/3 "2023-04-28T08:47:38Z")

</div>

A gem indeed. Well found @glv  
I actually want the vector. This is currently rotating the display of line AB. Isn’t there one or two lines of code we can add to the sketch below to find the new vector?

```auto
PVector a, b, c, ax;

float x, y, z, angle;

void setup()
{
  size(400, 400, P3D);

  a = new PVector(0, 0, 0);
  b = new PVector(100, 100, 50);
  c = new PVector(100, -100, -50);
  ax = new PVector(0, 0, 0);
  angle = radians(60);
}

void draw()
{
  background(255);
  translate(width/2, height/2); // move (0, 0, 0) to centre of window
  stroke(0);
  strokeWeight(2);

  line(a.x, a.y, a.z, b.x, b.y, b.z); // static line ab
  line(a.x, a.y, a.z, c.x, c.y, c.z); // static line ac

  //step 1
  ax = b.cross(c);
  
  // Rotates a line about an axis
  stroke(255, 128, 0);
  pushMatrix();
  rotV(angle, ax); //step 2
  line(a.x, a.y, a.z, b.x, b.y, b.z); // the line ab rotated in display
  popMatrix();

  // a blob for identifying vector points
  pushMatrix();
  translate(a.x, a.y, a.z);
  noFill();
  stroke(127);
  //sphere(4);
  popMatrix();
}

void rotV(float angle, PVector axis) //step 3
{
  rotate(angle, axis.x, axis.y, axis.z);
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [April 28, 2023, 11:23am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/4 "2023-04-28T11:23:17Z")

</div>

Hello again!

I do not have a simple solution… and very little time these days to explore.

A search revealed some possible solutions for consideration:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/e/3/e3b70971ba5b307d8823c31f4723d016098a6f23.png)

I have used your initial approach in the past for drawing arcs on a sphere.

`:)`

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [April 29, 2023, 12:50pm UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/5 "2023-04-29T12:50:01Z")

</div>

Hello again!

If you are using transformations you can use get the x, y, z coordinates with the `modelX()`, `modelY()`, `modelZ()` functions.  
See references for details.

Example:

```auto
PVector a, b, c, ax;
float x, y, z, angle;

void setup()
  {
  size(400, 400, P3D);

  a = new PVector(0, 0, 0);
  b = new PVector(100, 100, 60);
  c = new PVector(100, -100, -60);
  ax = new PVector(0, 0, 0);
  angle = radians(60);
  }

void draw()
  {
  background(255);
  translate(width/2, height/2); // move (0, 0, 0) to center of window
  
  ax = b.cross(c);
 
 // Just for fun! Can uncomment these to animate!
  //float aY = (frameCount%360)*(TAU/360); // One degree per frame
  //rotateY(aY);
  //angle = PVector.angleBetween(b, c)/2*sin(aY) + PVector.angleBetween(b, c)/2;
  
  stroke(0);
  strokeWeight(3);
  line(a.x, a.y, a.z, b.x, b.y, b.z); // static line ab
  line(a.x, a.y, a.z, c.x, c.y, c.z); // static line ac
  
  // Rotates a line about an axis and returns PVector
 pushMatrix();
  resetMatrix(); //otherwise this includes the transformations above
  rotV(angle, ax);
  PVector v = new PVector(modelX(b.x, b.y, b.z), 
                          modelY(b.x, b.y, b.z), 
                          modelZ(b.x, b.y, b.z));
  println(v);
 popMatrix();
  
  stroke(255, 0, 0);
  line(a.x, a.y, a.z, v.x, v.y, v.z); // the line ab rotated in display
  }

void rotV(float angle, PVector axis)
  {
  rotate(angle, axis.x, axis.y, axis.z);
  }

```

@paulstgeorge Consider refactoring into a single function to rotate PVector and return PVector.

`:)`

---

<div class="post-metadata">

**Author:** ![corvanessen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/corvanessen/32/18302_2.png) [@corvanessen](https://discourse.processing.org/u/corvanessen)\
**Post date:** [May 3, 2023, 4:43am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/6 "2023-05-03T04:43:15Z")

</div>

Maybe I’m misunderstanding the question, but it sounds like you want to do vector addition.

> **[Vector Addition -- from Wolfram MathWorld](https://mathworld.wolfram.com/VectorAddition.html)**
>
> Vector addition is the operation of adding two or more vectors together into a vector sum. The so-called parallelogram law gives the rule for vector addition of two or more vectors. For two vectors A and B, the vector sum A+B is obtained by placing...

In your example a is at the origin right, so you’d just be adding b and c

---

<div class="post-metadata">

**Author:** ![paulstgeorge](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@paulstgeorge](https://discourse.processing.org/u/paulstgeorge)\
**Post date:** [May 3, 2023, 11:41am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/7 "2023-05-03T11:41:00Z")

</div>

Yes @corvanessen , ‘addition’ works very well.

but it bisects the angle

How do I use ‘add’ to choose the ratio of division between the two lines?

so, for example if there were 90° between AC and AB how would I find the line AM that is 30° from AC and 60° from AD.

Adding the two vectors gives me 45° in this example.

---

<div class="post-metadata">

**Author:** ![paulstgeorge](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@paulstgeorge](https://discourse.processing.org/u/paulstgeorge)\
**Post date:** [May 4, 2023, 7:55pm UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/8 "2023-05-04T19:55:48Z")

</div>

Solved! I just add the two vectors, but I do not give them equal weight. First multiply each of the two vectors according to the desired ratio. The full sketch is below, here is the pertinent detail:

```auto
  b2 = b.copy();
  b2.mult(sin(angle));
  c2 = c.copy();
  c2.mult(cos(angle));

  v3 = PVector.add(b2, c2);
  v3.normalize();
  v3.mult(m);

```

Sketch:

```auto
PVector a, b, c, b2, c2, v3;

float m, dangle, angle;

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

  a = new PVector(0, 0, 0);
  b = new PVector(100, 100, 0);
  c = new PVector(100, -100, 0);

  m = PVector.dist(a, b);
}

void draw() {
  background(255);
  strokeWeight(1);

  textSize(64);

  dangle = 90 * (mouseY/float(height)); // 0.0 at top, 90.0 at bottom
  angle = dangle * PI /180; // radians

  translate(width/2, height/2); // move (0, 0, 0) to centre of window

  stroke(0, 0, 0);

  line(a.x, a.y, a.z, b.x, b.y, b.z);
  line(a.x, a.y, a.z, c.x, c.y, c.z);

  b2 = b.copy();
  b2.mult(sin(angle));
  c2 = c.copy();
  c2.mult(cos(angle));

  v3 = PVector.add(b2, c2);
  v3.normalize();
  v3.mult(m);

  line(a.x, a.y, a.z, v3.x, v3.y, v3.z);

  pushMatrix();
  translate(v3.x, v3.y, v3.z);
  noFill();
  stroke(127, 0, 0);
  sphere(4);
  popMatrix();

  pushMatrix(); // move (0, 0, 0) back to centre of window
  translate(a.x, a.y, a.z);
  noFill();
  stroke(0);
  sphere(4);
  popMatrix();

  pushMatrix();
  translate(b.x, b.y, b.z);
  noFill();
  stroke(0);
  sphere(4);
  popMatrix();

  pushMatrix();
  translate(c.x, c.y, c.z);
  noFill();
  stroke(0);
  sphere(4);
  popMatrix();

  fill(0, 408, 612, 204);
  text(int(dangle), 40, 360);
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [May 5, 2023, 11:01am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/9 "2023-05-05T11:01:06Z")

</div>

This topic was engaging!

Another twist on this that was inspired by the discussions:

```auto
PVector a, b, c, b2, c2, v3;

float m, dangle, angle;

void setup() 
  {
  size(500, 500, P3D);

  a = new PVector(0, 0, 0);
  b = new PVector(100, 140, 50);
  c = new PVector(100, -100, -50);

  m = PVector.dist(a, b);
  textSize(64);
  }

void draw() 
  {
  background(0);

  float ratio = float(mouseY)/height; 
  println(ratio);
 push();
  translate(width/2, height/2); // move (0, 0, 0) to centre of window
  rotateY((frameCount%360)*(TAU/360));

  stroke(128);
  strokeWeight(2);
  line(a.x, a.y, a.z, b.x, b.y, b.z);
  line(a.x, a.y, a.z, c.x, c.y, c.z);

  //b2 = b.copy();
  //b2.mult(sin(angle));
  //c2 = c.copy();
  //c2.mult(cos(angle));
  
  //Replaces above
  b2 = b.copy();
  b2.mult(ratio);
  c2 = c.copy();
  c2.mult(1-ratio);
  println(b2, c2);
  
  strokeWeight(5);
  stroke(255, 0, 0);
  line(a.x, a.y, a.z, b2.x, b2.y, b2.z);
  stroke(0, 255, 0);
  line(a.x, a.y, a.z, c2.x, c2.y, c2.z);

  v3 = PVector.add(b2, c2);
  //v3.normalize();
  //v3.mult(m);
  
  stroke(255, 255, 0);
  line(a.x, a.y, a.z, v3.x, v3.y, v3.z);
 pop();

  fill(0, 408, 612, 204);
  text( (int) degrees(PVector.angleBetween(b2, v3)), 40, height-40 );
  }

```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/2/f/2fe613a6c79e979b656e1ae5031f26152b05b532.png)

`:)`

---

<div class="post-metadata">

**Author:** ![paulstgeorge](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@paulstgeorge](https://discourse.processing.org/u/paulstgeorge)\
**Post date:** [May 5, 2023, 12:45pm UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/10 "2023-05-05T12:45:45Z")

</div>

@glv I realise that it is not solved. As @corvanessen points out, the solution only works when a is at the origin.

I have been trying and failing to make the solution more general. Can you help?

Everything the same, still 90° between the two lines but the point a can be anywhere.

---

<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:** [July 5, 2023, 8:52am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/11 "2023-07-05T08:52:45Z")

</div>

I know this is a bit late but this might do what you want. 😀

```auto
PVector vo, vs, ve, vr;
float t = 0, step = 0.01, dt = 1;

void setup() {
  size(512, 512);
  cursor(CROSS);
  textSize(16);
  getRandomPositions();
}

void draw() {
  background(0);
  fill(240);
  text("Hit 'n' key to get new random vectors", 20,20);
  strokeWeight(1.5);
  stroke(100, 255, 1000); // start vector colour
  line(vo.x, vo.y, vs.x, vs.y);
  stroke(255, 100, 100); // end vector colour
  line(vo.x, vo.y, ve.x, ve.y);
  // Now adjust the parametric value t to get wiper blade effect
  t += step * dt;
  if (t > 1) {
    t = 1;
    dt = -1;
  } else if (t < 0) {
    t = 0;
    dt = 1;
  }
  // Get the lerped vector
  vr = lerpBetween2Vectors(vo, vs, ve, t);
  stroke(255, 255, 100); // lerped vector colour
  line(vo.x, vo.y, vr.x, vr.y);
}

// origin is the common origin far all vectors
// t is the parametric value and should be in the range >=0 and <=1
// the function will constrain the passed parameter to this value
PVector lerpBetween2Vectors(PVector origin, PVector start, PVector end, float t) {
  PVector s = PVector.sub(start, origin);
  PVector e = PVector.sub(end, origin);
  t = constrain(t, 0, 1);
  float rx = origin.x + s.x + (e.x - s.x) * t;
  float ry = origin.y + s.y + (e.y - s.y) * t;
  float rz = origin.z + s.z + (e.z - s.z) * t;
  return new PVector(rx, ry, rz);
}

void getRandomPositions() {
  float minX = 60, maxX = width - 2 * minX;
  float minY = 60, maxY = height - 2 * minY;
  // common origin forstart and end vectors
  vo = new PVector(random(minX, maxX), random(minY, maxY));
  // start and end vector positions
  vs = new PVector(random(minX, maxX), random(minY, maxY));
  ve = new PVector(random(minX, maxX), random(minY, maxY));
}

void keyTyped() {
  if (key == 'n') getRandomPositions();
}

```

---

<div class="post-metadata">

**Author:** ![paulstgeorge](https://avatars.discourse-cdn.com/v4/letter/p/53a042/32.png) [@paulstgeorge](https://discourse.processing.org/u/paulstgeorge)\
**Post date:** [July 7, 2023, 6:40am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/12 "2023-07-07T06:40:54Z")

</div>

This is impressive! I have been trying to tweak it so the two vectors vs and ve (with common origin vo) and perpendicular. Can your code be reduced so the angle between vo-vs and vo-ve is always 90°?

---

<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:** [July 7, 2023, 8:26am UTC](https://discourse.processing.org/t/using-vectors-to-find-the-line-between-two-lines/41856/13 "2023-07-07T08:26:17Z")

</div>

> [@paulstgeorge](#):
>
> Can your code be reduced so the angle between vo-vs and vo-ve is always 90°?

Yes. 😀

Add this method to the sketch and replace the calls to `getRandomPositions` in `setup` and `keyTyped` to `getRandomPositions90`.

```auto
void getRandomPositions90() {
  float minX = 60, maxX = width - 4 * minX;
  float minY = 60, maxY = height - 4 * minY;
  // common origin for start and end vectors
  vo = new PVector(random(minX, maxX), random(minY, maxY));
  // start and end vector positions
  vs = PVector.random2D(); // unit vector
  ve = new PVector(-vs.y, vs.x); // unit perpendiciular
  vs.mult(random(minX, maxX)).add(vo);
  ve.mult(random(minX, maxX)).add(vo);
}

```
