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

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 60

^{o} so the angle

`a1`

will be 30

^{o}.

`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

Repeating this six times to make a snowflake gives

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

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