【问题标题】:Pie in cartesian coordinates笛卡尔坐标中的饼图
【发布时间】:2014-03-03 03:16:32
【问题描述】:

以下是使用众所周知的公式在笛卡尔坐标中生成“实心”圆(圆盘)的代码:

(x - j)2 + (y - k)2 = r2

其中 j & k 是中心的坐标,r 是半径。

它工作得很好,但现在我只想生成一个扇区,一个磁盘的饼图,但仍然使用笛卡尔坐标。关于如何实现这一点的任何线索?

    for(var scanx=x-radius; scanx<x+radius; scanx+=1) {            
        // out of extend
        if(scanx<0 || scanx>params.width){
            continue;
        }
        for(var scany=y-radius; scany<y+radius; scany+=1) {

            if(scany<0 || scany>params.height) {
              continue;
            }                  

            var dist = Math.sqrt(Math.pow((scanx-x), 2)+Math.pow((scany-y), 2));

            if(dist > radius) {
                continue;
            } else {
                var v = data - params.step * Math.pow(dist, degree);
                var id = scanx+scany*params.width;
                if(value[id]){
                   value[id] = Math.max(value[id], v); 
                } else {
                    value[id] = v;
                }
            }
        }
    }    

【问题讨论】:

  • 题外话:计算平方根很慢。最好在循环之前计算radius*radius,并在每次迭代时将其与scanx*(scanx-2*x)+x*x+scany*(scany-2*y)+y*y (=dist*dist) 进行比较。还要注意x*xMath.pow(x,2) 快,因为函数调用很慢。
  • 您可以随时询问 wolfram alpha:wolframalpha.com/input/?i=parametric+equation+of+arc
  • 此外,与其循环遍历无用的值,不如将循环改进为for(var scanx=Math.max(x-radius,0), untilx=Math.min(x+radius,params.width); scanx&lt;untilx; ++scanx),并摆脱if(scanx&lt;0 || scanx&gt;params.width)

标签: javascript math


【解决方案1】:

您可以通过定义要输出的 x 轴和 y 轴的截面来绘制曲线段。

因此,如果您想打印圆圈的第一个象限,您可以将“x”for 循环限制在 0x+radius 之间,并将“y”for 循环限制在 0y+radius

如果您正在寻找基于起始角度θ1 和最终角度θ2 的输出,您需要使用以下方法将它们从极坐标转换为笛卡尔坐标:

x1 = r × cos( θ1 ); y1 = r × sin( θ1 ); 
x2 = r × cos( θ2 ); y2 = r × sin( θ2 );

然后使用值 x1, x2 作为 x for 循环边界,使用 y1 和 y2 作为 y for 循环边界。

使用这种方法的一个注意事项:

如果您的圆弧距离大于 45 度,则需要将其从起点到最近的轴分成几段并获得最大坐标值。或者您可以循环遍历角度步长并从上面的极坐标-笛卡尔转换中打印出 x-y 坐标。

【讨论】:

    【解决方案2】:

    你可以使用画布:

    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');
    ctx.beginPath();
    ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
    ctx.lineTo(x, y);
    ctx.closePath();
    ctx.fill();
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多