# Calculate maximum length of a vector

**URL:** <https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818>\
**Category:** Coding Questions\
**Created:** [November 29, 2021, 1:36pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818 "2021-11-29T13:36:17Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [November 29, 2021, 1:36pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/1 "2021-11-29T13:36:18Z")

</div>

I’m trying to achieve the following calculation but i really don’t know what functions and equations to use in this situation.

 ![vectors](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/6/67b4351a42bc8ab966ac0ffbe842c2d2b6ae5854.jpeg)

As you can see in the diagram, I have vector A and vector B and I know angle K and angle J. What I am trying to find out is how to calculate the maximum magnitude of vector C - the point it intersects with vector A. With that maximum length in hand, I’ll generate a random number (10, maxLength) to draw a line from where vector C intersects vector B to the random length using sin(J) \* length & cos(J) \* length.

I’ve looked at scalar projection and dot product and other vector math stuff and I really haven’t a clue how to tackle this problem. any help would be greatly appreciated.

---

<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:** [November 29, 2021, 6:42pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/2 "2021-11-29T18:42:40Z")

</div>

![Screenshot 2021-11-29 at 18.24.06](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/6/650dee3c1f0f345d92e3d2197a4a968f4355083b.png)

I have added some info to your drawing, a,b and c are the lengths of the 3 sides of a triangle formed by the intersection of three non-parallel lines. Assuming that you calculate the distance `b` then you can calculate the other two sides using ‘sine law’.

`c = b * sin(K) / sin(J - K)`  
and  
`a = b * sin(180 - J) / sin(J - K)`

Where J and K are measured in degrees. Obvious should use radians on the computer.

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [November 29, 2021, 9:30pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/3 "2021-11-29T21:30:40Z")

</div>

This is excellent. I see it now. Just to confirm, those formulas for c & a will give me a length/distance of those lines/sides? I’ll try this tonight.

---

<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:** [November 30, 2021, 8:38am UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/4 "2021-11-30T08:38:14Z")

</div>

> [@travis.stdenis](#):
>
> Just to confirm, those formulas for c & a will give me a length/distance of those lines/sides?

Yes 👍

Extra to make the minimum 20 characters needed LOL

---

<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:** [November 30, 2021, 11:45am UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/5 "2021-11-30T11:45:41Z")

</div>

Hello,

Some links to help you:

- [The Law of Sines](https://www.mathsisfun.com/algebra/trig-sine-law.html)

- [Trigonometry Index](https://www.mathsisfun.com/algebra/trigonometry-index.html)

- [https://processing.org/tutorials/trig](https://processing.org/tutorials/trig)

`:)`

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [November 30, 2021, 1:42pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/6 "2021-11-30T13:42:03Z")

</div>

I implemented the formulas, however, it doesn’t appear to be working as expected. the code below is for a snowflake generator. you can see in the output below, where i’ve circled, the lines intersect each other and continue on when they should terminate.

 ![snowflake_03](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/5f3fba7afe95ab393f165524be1791d78a9af5d5.png)

```auto
int numStems = (random(1) <= 0.5) ? 6 : 8;
float stemAngle = TWO_PI / numStems;
boolean centerPiece = (random(1) <= 0.5) ? true : false;
int centerType = floor(random(1,7));
boolean midStems;
int numMidStems = 6;
int mainStemLen = 200;
int midStemLen = 150;
int stemOffset = (centerPiece) ? 50 : 0;
int numMainBranches;
int numMidBranches = 4;
float branchAngle = random(PI/6, PI/3);
float spaceBuffer = 20;
float mainBranchSpacer;
float[] mainBranchLen;
PVector[] mainBranchEnd;

void setup() {
  size(650, 850, P3D);
  background(0);
  smooth(8);
  
  if(numStems <= 6){
    midStems = (random(1) <= 0.5) ? true : false;
  } else{ midStems = false; }
  if(centerPiece){
    numMainBranches = floor(random(4,7));
  } else{ numMainBranches = floor(random(5,8)); }
  
  mainBranchSpacer = (mainStemLen - stemOffset - spaceBuffer*2) / numMainBranches;
  mainBranchLen = new float[numMainBranches];
  mainBranchEnd = new PVector[numMainBranches];
  
  noLoop();
}

void draw(){
  background(0);
  translate(width/2, height/2);
  rotate(HALF_PI);

  // draw the stems
    for(int i=0; i<numStems; i++){
      pushMatrix();
        rotate(stemAngle * i);
        stroke(255);
        strokeWeight(5);
        strokeCap(SQUARE);
        line(stemOffset, 0, mainStemLen, 0);
      popMatrix();
    }
    //draw the in-between stems
    if(midStems){
      for(int i=0; i<numMidStems; i++){
        pushMatrix();
          rotate((stemAngle * i) + (PI / numMidStems));
          stroke(255);
          strokeWeight(3);
          strokeCap(SQUARE);
          line(stemOffset, 0, midStemLen, 0);
        popMatrix();
      }
    }

    // draw the branches on main stems
    for(int j=1; j<=numMainBranches; j++){
      float maxLength = ((spaceBuffer + (mainBranchSpacer*j)) * sin(stemAngle/2)) / sin(branchAngle - (stemAngle/2)); //stemAngle/2 is meeting in the middle
      if(j < 3){ //only for the first two
        if(! centerPiece){ //don't do if there is a centerpiece
          mainBranchLen[j-1] = (random(1) <= 0.5) ? random(15, maxLength) : maxLength; //50% chance they are connected
        } else{ mainBranchLen[j-1] = random(15, maxLength); }
      }
      else if(j == numMainBranches){
          mainBranchLen[j-1] = random(15, 20); //want the last one to be shorter
      } 
      else{
        mainBranchLen[j-1] = random(35, maxLength/6);
      }
      mainBranchEnd[j-1] = new PVector(cos(branchAngle)*mainBranchLen[j-1], sin(branchAngle)*mainBranchLen[j-1]);
    }
    for(int i=0; i<numStems; i++){
      pushMatrix();
      rotate(stemAngle * i);
      for(int k=0; k<numMainBranches; k++){
        pushMatrix();
          translate(spaceBuffer + stemOffset + (mainBranchSpacer*k), 0);
          stroke(255);
          strokeWeight(3);
          strokeCap(SQUARE);
          line(0, 0, mainBranchEnd[k].x, mainBranchEnd[k].y);
          line(0, 0, mainBranchEnd[k].x, -mainBranchEnd[k].y);
        popMatrix();
      }
      popMatrix();
    }
}

```

---

<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:** [November 30, 2021, 5:20pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/7 "2021-11-30T17:20:46Z")

</div>

Now that I know your goal is to create snowflakes I can think of several different algorithms for doing this and avoid the intersections. Unfortunately your code is quite complex so I would struggle to find the solution by modifying what you have.

I would start again but this time focus on creating a _ **single branch** _. This would be a two stage process.

1. Turn your computer off and get pen and paper and draw what you would want a typical branch to look like. From that, design an algorithm to draw the _ **single** _ branch.
2. Convert the algorithm into a reusable _ **function** _ with appropriate parameters to control the size and shape of the branch.

You will probably iterate this process several times before you get what you need.

Since snowflakes exhibit 6-fold symmetry can repeatably draw the branches by repeated calls to the function with rotation to get the final snow flake.

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [November 30, 2021, 6:43pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/8 "2021-11-30T18:43:10Z")

</div>

have already done all that! above is just the part of the code that generates the stems and branches so you can see the implementation of the original question. i know i can consolidate the stem and branch generation into a single, 6x repeating function and will do that, but it still leaves a question of setting a maximum length of a branch to prevent them crossing and continuing instead of terminating. i’m open to any other ways of doing this, but i wanted to give feedback on your solution above to see if it can be fixed.

---

<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:** [December 1, 2021, 10:33am UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/9 "2021-12-01T10:33:20Z")

</div>

My answer gave the solution to the original question “Calculate the maximum length of a vector” and the sine law answered that.

I believe that the intersection problem is caused by a logic error when using the sine-law-results in the branch-drawing algorithm that is why I suggested revisiting the algorithm from scratch, it was not a criticism of your approach.

I often have to go back to square one when I am programming some complex algorithm because my original logic was flawed.

It seems to me that there are three possibilities

1. The sine law has been incorrectly implemented
2. The vector A is not the mid point between two branches and may impinge on the space required by an adjacent branch. For six-fold symmetry the angle K should be \<= 30 degrees
3. The length of the sub branch is greater than the maximum length calculated using the sine law.

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [December 3, 2021, 3:20am UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/10 "2021-12-03T03:20:21Z")

</div>

Fair enough. I’ll comb back through the code.

edit: I found the error in the original formula. Per the diagram above, the formula was written:  
c = b \* sin(K) / sin(J - K)  
when it should have been  
c = b \* sin(K) / sin((180-J) - K)

---

<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:** [December 5, 2021, 10:20am UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/11 "2021-12-05T10:20:48Z")

</div>

![Screenshot 2021-11-29 at 18.24.06](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/6/650dee3c1f0f345d92e3d2197a4a968f4355083b.png)  
Sine line means that

\frac{a}{sin(180-J)}=\frac{b}{sin(L)}=\frac{c}{sin(K)}

Since we know the angles J and K we can calculate the angle L because the sum of the internal angles of a triangle is 180 degrees. So we have

180 - J + L + K = 180  
Subtract 180 from both sides gives  
- J + L + K = 0  
Adding J to and subtracting K from both sides gives  
L = J - K

Substituting back into the sine law gives

\frac{a}{sin(180-J)}=\frac{b}{sin(J-K)}=\frac{c}{sin(K)}

From this you can see that

c = \frac{b \* sin(K)}{sin(J - K)}

So although

c = \frac{b \* sin(K)}{sin((180-J) - K)}

might solve your intersection problem it is not a valid outcome of the sine law.

---

<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:** [December 5, 2021, 3:29pm UTC](https://discourse.processing.org/t/calculate-maximum-length-of-a-vector/33818/12 "2021-12-05T15:29:08Z")

</div>

I really enjoy playing with algorithms so I decided to start at first principles based on your problem description and came up with a solution that could be adapted to suit other user needs.

So here is my diagram for a main branch with a single sub-branch

 ![Scan 3](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/0/00571083b26a743a81add4751d5cc82f80520527.jpeg)  
The horizontal line represents the main branch. The dotted line represents the limit for any sub-branch and is the mid point between two main branches. For 6-fold symmetery the angle between main branches is 60o so the angle `a1` will be 30o. `sbAngle` is the angle between the sub branch and the main branch (i.e. J in the original drawing)

Using this information I created a basic sketch to draw the branh with this result  
 ![sn75](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/7e0bf11b326a68e561dbb7997934caf1e9f47146.png)  
Repeating this six times to make a snowflake gives  
 ![sn389](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/4/43b7e57ced77f1beee2a2707da1f6dcf215f10c7.png)  
The blue lines represent the area available to each branch.

The sketch code is below and should be self explanatory when read in conjunction with the diagram above

```auto
public void setup() {
  size(320, 320);
}

void draw() {
  background(0);
  translate(width/2, height/2);
  // Select single branch or snowflake
  branch(new PVector(), 0, 100, 5, PI/3, PI/6);
  // snowflake(new PVector(), 100, 5, PI/3 + PI/2, PI/6);
}

void snowflake(PVector centre, float mbLength, int nbrSBs, float sbAngle, float a1) {
  translate(centre.x, centre.y);
  pushMatrix();
  for (int i = 0; i < 6; i++) {
    branch(centre, i * PI / 3, mbLength, nbrSBs, sbAngle, a1);
  }
  popMatrix();
}

/**
 * This draws a single branch of the snow flake. To prevent interactions between
 * neighbouring branches the last parameter is the angular limit for all sub branches.
 * For 6-fold symmetry the angle between main branches is PI/3 so the angular limit
 * is PI/6
 * @param start the global position for the start of the branch
 * @param rotAngle the global angle the main branch makes with the x-axis
 * @param mbLength the length of the main branch
 * @param nbrSBs the number of sub-branches from the main branch
 * @param sbAngle the angle between the sub branch makes along length of the main branch
 * @param a1 the limit angle.
 */
public void branch(PVector start, float rotAngle, float mbLength, int nbrSBs, 
  float sbAngle, float a1) {
  pushMatrix();
  // Transform the graphics context so the main branch starts at [0,0] and lies 
  // along x-axis
  translate(start.x, start.y, rotAngle);
  rotate(rotAngle);
  stroke(255);
  strokeWeight(2.5f);
  float spacing = mbLength / (nbrSBs + 1);
  float a2 = PI - sbAngle; // triangle internal angle
  float a3 = PI - a2 - a1; // calculate third internal angle
  line(0, 0, mbLength, 0);
  float d1, d2, d3, p3X, p3Y;
  for (int i = 1; i <= nbrSBs; i++) {
    // Find position on main branch to start sub-branch
    d3 = i * spacing;
    // Use the Sine Law to calculate other two side lengths
    d1 = d3 * sin(a1) / sin(a3); // length of the sub branch
    d2 = d3 * sin(a2) / sin(a3); // d2 is not used in this sketch
    // Before drawing the sub branch we have the opportunity to change
    // the length of the sub branch if we wish

    // Using Pythagorus calculate the coordinates for end of
    // the sub branch (p3) based on the length of the sub-branch
    p3X = d3 + d1 * cos(PI - a2);
    p3Y = d1 * sin(PI - a2);
    line(d3, 0, p3X, p3Y);
    line(d3, 0, p3X, -p3Y);
  }
  // Show limit angle (blue lines
  PVector limit = new PVector(cos(a1), sin(a1));
  limit.mult(300);
  stroke(120, 220, 220);
  strokeWeight(1.5f);
  line(0, 0, limit.x, limit.y);
  line(0, 0, limit.x, -limit.y);
  popMatrix();
}

void mouseClicked() {
  save("sn" + frameCount + ".png");
}

```
