Questions about Math

The following code(the most important part) can achieve the programming effect I want

// params.count  : Number of points
// params.branch : Number of lines
// params.radius : The radius of the shape

const generateGalaxy = () => {
  geometry = new THREE.BufferGeometry();
  const positions = new Float32Array(params.count * 3);
  const colors = new Float32Array(params.count * 3);

  for (let i = 0; i < params.count; i++) {
    const branchAngel = (i % params.branch) * ((2 * Math.PI) / params.branch);
    const distance = Math.random() * params.radius;
    const current = i * 3;
    // Calculate coordinates
    positions[current] = Math.cos(branchAngel + distance) * distance;
    positions[current + 1] = 0;
    positions[current + 2] = Math.sin(branchAngel + distance) * distance;
  }

Running result:
image

My question is why distance needs to be added after branchAngel in trigonometric functions to achieve bending effect when calculating coordinates

When there is only branchAngel in the function, the line drawn is a straight line
Like this

    positions[current] = Math.cos(branchAngel) * distance;
    positions[current + 1] = 0;
    positions[current + 2] = Math.sin(branchAngel) * distance;

image
When I add a constant,the result is still a straight line
Like this

    positions[current] = Math.cos(branchAngel + 3) * distance;
    positions[current + 1] = 0;
    positions[current + 2] = Math.sin(branchAngel + 3) * distance;

When I add a random variable

    const r = Math.random() * 8;
  
    positions[current] = Math.cos(branchAngel + r) * distance;
    positions[current + 1] = 0;
    positions[current + 2] = Math.sin(branchAngel + r) * distance;

The result
image
I looked up a rotation matrix in advanced algebra, but I haven’t figured out the relationship between this formula and the addition of distance after branchAngel when calculating coordinates here.

So, in order to generate a curve, do we need to add a number related to distance after branchAngel? Why?

Looking forward to everyone’s reply

images

It’s kinda a coincidence in this case. Look at the value of distance - in the center it’s 0.0, so it won’t have any effect on the trigonometric functions - but as you move further away, it’ll start increasing, causing the trigonometric functions to shift (and since this distance is uniform in all directions, it gives that synchronised shift for all branches in all directions.)

6 Likes

The algorithm uses polar coordinates (distance,angle) converted into Cartesian coordinates (the one that Three.js uses):

x = distance * cos(angle)
y = distance * sin(angle)

image

Now, imagine that you draw many points and keep the distance the same, but changing gradually the angle, you will get points along a concentric circle:

image

Now, imagine that you draw many points and keep the angle the same, but change gradually the distance. The result will be a radial line:

image

The last step is to combine both: increasing the distance will move points away from the center, increasing the angle will rotate the points around the center. The overall result will be a spiral:

image

Yes, a change i the distance should also need a change in the angle. The exact relation defines the look-and-feel of the spiral. Try the following versions:

// angle is fixed, so there will be straight lines, no spirals
positions[current] = Math.cos(branchAngel + 0*distance) * distance;
positions[current + 1] = 0;
positions[current + 2] = Math.sin(branchAngel + 0*distance) * distance;
// angle is changing slowly, the spiral will have slight curvature
positions[current] = Math.cos(branchAngel + 0.1*distance) * distance;
positions[current + 1] = 0;
positions[current + 2] = Math.sin(branchAngel + 0.1*distance) * distance;
// angle is changing faster, the spiral will have bigger curvature
positions[current] = Math.cos(branchAngel + distance) * distance;
positions[current + 1] = 0;
positions[current + 2] = Math.sin(branchAngel + distance) * distance;
// angle is changing in the opposite direction, the spiral will be curved in the opposite direction
positions[current] = Math.cos(branchAngel - distance) * distance;
positions[current + 1] = 0;
positions[current + 2] = Math.sin(branchAngel - distance) * distance;

Final remark, sometimes it is better to think in another way, because the relation distance-angle might be confusing. Here is my suggestion. There is parameter t that defines the position on a spiral, t=0 is the origin of the spiral. In this case, we have distance = t; and angle = branchAngle + t. This is the same relation as before, but the direct connection between the distance and the angle is removed.

3 Likes

Thank you for your answer! I’m verry happy to learn knowledge from your answers!

1 Like

em…the branchAngel is as cute as your avatar(I’m not sure if I used the wrong word in this sentence~), And thank you for your answer!

I had a giggle reading @mjurczyk answer.

image

5 Likes

hhh~yes,My English still needs improvement. It’s a spelling errors,but The angel’s picture is quite cute