【问题标题】:Use X,Y coordinates to plot points inside a circle使用 X,Y 坐标在圆内绘制点
【发布时间】:2011-01-16 20:20:00
【问题描述】:

在 javascript 中有没有办法绘制 x,y 坐标,使它们落入圆形而不是方形?

例如,如果我有以下代码:

  circleRadius = 100;
  context.drawImage(img_elem, dx, dy, dw, dh);

我需要找出一个 100 像素圆圈内的 x,y 值的组合。

谢谢!

【问题讨论】:

  • 半径为 r 的圆内的 (x, y) 点集合由不等式 x^2 + y 给出^2

标签: javascript plot coordinates geometry


【解决方案1】:
  1. 在 -100 到 100 之间随机选择一个 x
  2. 圆由x^2 + y^2 = r^2 定义,在您的情况下等于100^2 = 10000
  3. 从这个方程你可以得到 y^2 = 10000 - x^2 ,因此带有选定 x 和 y = +/-sqrt(10000 - x^2) 的点将位于圆上。
  4. 在点 3 找到的两个坐标之间随机选择一个 y
  5. 你准备好了!

编辑: 在 JS 中:

var radius = 100;
x = Math.random() * 2 * radius - radius;
ylim = Math.sqrt(radius * radius - x * x);
y = Math.random() * 2 * ylim - ylim;

另一个编辑: a jsFiddle Example

【讨论】:

  • 稍微玩弄一下:jsfiddle.net/YL6Bj/1 - 请注意,点往往会聚集在 x 方向的极端,因为在这些区域中 y 的选择较少.如果您需要很多点,您可能需要纠正在生成 x 坐标时引入的偏差。
  • 是的,这给出了一个非常糟糕的分布。我添加了一个具有等分布结果的答案。
  • 嗯,该解决方案在大多数情况下都非常有效,没有必要投反对票...
  • 我把它变成了一个小提琴并添加了那个
【解决方案2】:

不确定您对 javascript 的含义,但

x = R*cos(theta)y = R*sin(theta) 是圆的笛卡尔点。 R当然是半径,theta是从0到2*Pi的角度。

【讨论】:

    【解决方案3】:

    如果你想要均匀分布的坐标,你最好选择

    var radius = 100
    var center_x = 0
    var center_y = 0
    
    // ensure that p(r) ~ r instead of p(r) ~ constant
    var r = radius*Math.sqrt(Math.random(1))
    var angle = Math.sqrt(2*Math.PI)
    
    // compute desired coordinates
    var x = center_x + r*Math.cos(angle);
    var x = center_y + r*Math.sin(angle);
    

    如果您想要更多靠近中间的点,请使用

    var r = radius*Math.random(1)
    

    改为。

    【讨论】:

      【解决方案4】:

      我将此作为解决方案发布,因为这个问题是谷歌中唯一相关的结果。

      我的问题/问题是如何在xy 不会超过r 的圆内添加笛卡尔坐标。

      例子:

      1. 绘图:(45,75) 在半径为 100 的圆内(通常会落在圆内,但位置不正确)
      2. 绘图:(100,100) 在半径为 100 的圆内(通常会落在圆外

      解决方案

      // The scale of the graph to determine position of plot
      // I.E. If the graph visually uses 300px but the values only goto 100
      var scale = 100; 
      
      // The actual px radius of the circle / width of the graph
      var radiusGraph = 300; 
      
      // Plot the values on a cartesian plane / graph image
      var xCart = xVal * radiusGraph;
      var yCart = yVal * radiusGraph;
      
      // Get the absolute values for comparison
      var xCartAbs = Math.abs( xCart );
      var yCartAbs = Math.abs( yCart );
      
      // Get the radius of the cartesian plot
      var radiusCart = Math.sqrt( xCart * xCart + yCart * yCart );
      
      // Compare to decide which value is closer to the limit
      // Once we know, calculate the largest possible radius with the graphs limit. 
      // r^2 = x^2 + y^2
      if ( xCartAbs > yCartAbs ) { // Less than 45°
          diff = scale / xCartAbs;
          radiusMaximum = Math.sqrt( radiusGraph * radiusGraph + Math.pow( yCartAbs * diff, 2) );
      } else if ( yCartAbs > xCartAbs ) { // Greater than 45°
          diff = scale / yCartAbs;
          radiusMaximum = Math.sqrt( radiusGraph * radiusGraph + Math.pow( xCartAbs * diff, 2) );
      } else { // 45°
          radiusMaximum = Math.sqrt( 2 * ( radiusGraph * radiusGraph ) );
      }
      
      // Get the percent of the maximum radius that the cartesian plot is at
      var radiusDiff = radiusCart / radiusMaximum;
      var radiusAdjusted = radiusGraph * radiusDiff;
      
      // Calculate the angle of the cartesian plot
      var theta = Math.atan2( yCart, xCart );
      
      // Get the new x,y plot inside the circle using the adjust radius from above
      var xCoord = radiusAdjusted * Math.cos( theta );
      var yCoord = radiusAdjusted * Math.sin( theta );
      

      【讨论】:

        【解决方案5】:

        不确定这是否是正确的 JavaScript 代码,但类似这样:

        for (x = -r; x < r; x++) {
          for (y = -r; x < r; y++) {
            if ((x * x + y * y) < (r * r)) {
              // This x/y coordinate is inside the circle.
              // Use <= if you want to count points _on_ the circle, too.
            }          
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-23
          • 2021-03-07
          • 2013-10-23
          • 2018-11-10
          相关资源
          最近更新 更多