Search code examples
algorithmdraw

How can i split a list of points in all angle


I try to seperate a list of point into all basic angle

enter image description here

Here's my code

var increment =15/50;       
var distance = 20;
var count = 0;

for( theta=0;theta <50; theta++) {      
  var newX = centerX +distance*Math.cos(theta*2*Math.PI*increment);
  var newY = centerY +distance*Math.sin(theta*2*Math.PI*increment);
  cxt.fillText("o",newX, newY);
  count++;
  if(count%5===0){
  distance=distance+20;
  }
}

Output:

enter image description here

I try to modify the increment many times but either they didn't make into straght lines or all the points turn into a mess What is the exact increment number or function for this?


Solution

  • Problem 1

    No need for count - it is being incremented in exactly the same fashion as theta:

    var increment =15/50;       
    var distance = 20;
    
    for( theta=0;theta <50; theta++) {      
      var newX = centerX +distance*Math.cos(theta*2*Math.PI*increment);
      var newY = centerY +distance*Math.sin(theta*2*Math.PI*increment);
      cxt.fillText("o",newX, newY);
      if(theta%5===0){  // just use theta here
        distance=distance+20;
      }
    }
    

    Problem 2

    The if statement increments distance once every 5 points, which means each "ring" only contains 5 points, whereas they should have as many points as basic angles. The logic should therefore be:

    if (theta % 16 === 0) {  // there are 16 "basic angles"
      distance += 20;
    }
    

    Problem 3

    1 is not an integer multiple of the fractional increment 15/50, so the second "ring" of points will not line up with the first - there will be an angular offset of 2*PI/5 between consecutive rings.

    It is more efficient to separate the single loop into two nested loops, as suggested by Damien. The outer loop should increment the angle as the trigonometric functions are expensive.

    var num_basic_angles = 16;  // number of basic angles
    var separation = 20;        // distance between each point
    var num_points;             // number of points per angle
    
    for (var angle = 0; angle < num_basic_angles; angle++) {
      var theta = 2*Math.PI*angle/num_basic_angles;
      var cos_t = Math.cos(theta);
      var sin_t = Math.sin(theta);
      for (var point = 0; point < num_points; point++) {
        var x = centerX + distance * point * cos_t;
        var y = centerY + distance * point * sin_t;
        cxt.fillText("o",x,y);
      }
    }
    

    If you really want to do things in a single loop, use theta = Math.floor(i / num_basic_angles), point = i % num_basic_angles, where i is the loop counter from 0 to num_basic_angles * num_points - 1.


    Problem 4

    The "basic angles" are not evenly distributed, so incrementing by a fixed value will not work.

    No need to be too smart here, because these basic angles are arbitrarily defined anyway. Just store them in an array:

    var basic_angles = [0,30,45,60,90,120,135,150,180,210,224,240,270,300,315,330];
    
    var separation = 20;  // distance between each point
    var num_points;       // number of points per angle
    
    for (var angle = 0; angle < basic_angles.length; angle++) {
      var theta = Math.PI/180.0*basic_angles[angle];
      var cos_t = Math.cos(theta);
      var sin_t = Math.sin(theta);
      for (var point = 0; point < num_points; point++) {
        var x = centerX + distance * point * cos_t;
        var y = centerY + distance * point * sin_t;
        cxt.fillText("o",x,y);
      }
    }