圈出坐标以用Javascript数组

时间:2020-03-06 14:57:17  来源:igfitidea点击:

在JavaScript中将圆的坐标添加到数组的最佳方法是什么?到目前为止,我只能做一个半圆,但是我需要一个公式,将整个圆返回两个不同的数组:xValues和yValues。 (我正在尝试获取坐标,以便可以沿路径对对象进行动画处理。)

这是我到目前为止的内容:

circle: function(radius, steps, centerX, centerY){
    var xValues = [centerX];
    var yValues = [centerY];
    for (var i = 1; i < steps; i++) {
        xValues[i] = (centerX + radius * Math.cos(Math.PI * i / steps-Math.PI/2));
        yValues[i] = (centerY + radius * Math.sin(Math.PI * i / steps-Math.PI/2));
   }
}

解决方案

如果我们已经有半个圆,则只需镜像点即可获得另一半
确保我们以正确的顺序执行此操作。

更具体而言,对于另一半,我们只需将"+ sin(...)"替换为"sin(...)"

我们需要使用部分函数将弧度输入到cos和sin中。因此,请取我们要获得的四分之一或者一半圆的值,并将其反映在中心点的轴上以获得完整的圆。

也就是说,JavaScript的缺点和缺点并不那么挑剔,因此我们必须将弧度或者其他内容减半。我将其写为:

function circle(radius, steps, centerX, centerY){
    var xValues = [centerX];
    var yValues = [centerY];
    var table="<tr><th>Step</th><th>X</th><th>Y</th></tr>";
    var ctx = document.getElementById("canvas").getContext("2d");
    ctx.fillStyle = "red"
    ctx.beginPath();
    for (var i = 0; i <= steps; i++) {
        var radian = (2*Math.PI) * (i/steps);
        xValues[i+1] = centerX + radius * Math.cos(radian);
        yValues[i+1] = centerY + radius * Math.sin(radian);
        if(0==i){ctx.moveTo(xValues[i+1],yValues[i+1]);}else{ctx.lineTo(xValues[i+1],yValues[i+1]);}
        table += "<tr><td>" + i + "</td><td>" + xValues[i+1] + "</td><td>" + yValues[i+1] + "</td></tr>";
    }
    ctx.fill();
    return table;
}
document.body.innerHTML="<canvas id=\"canvas\" width=\"300\" height=\"300\"></canvas><table id=\"table\"/>";
document.getElementById("table").innerHTML+=circle(150,15,150,150);

我假定无论出于何种原因,我们都希望xValues [0]和yValues [0]分别是centerX和centerY。我不知道为什么要这么做,因为它们已经是传递给函数的值了。

我可以自己解决问题,方法是将步数乘以2:

circle: function(radius, steps, centerX, centerY){
    var xValues = [centerX];
    var yValues = [centerY];
    for (var i = 1; i < steps; i++) {
        xValues[i] = (centerX + radius * Math.cos(Math.PI * i / steps*2-Math.PI/2));
        yValues[i] = (centerY + radius * Math.sin(Math.PI * i / steps*2-Math.PI/2));
   }
}

循环应这样设置:

for (var i = 0; i < steps; i++) {
    xValues[i] = (centerX + radius * Math.cos(2 * Math.PI * i / steps));
    yValues[i] = (centerY + radius * Math.sin(2 * Math.PI * i / steps));
}
  • 从0开始循环
  • 逐步遍历整个2 * PI范围,而不仅仅是PI。
  • 我们不应该使用var xValues = [centerX]; var yValues = [centerY];-圆心不属于圆心。

Bresenham的算法更快。我们听说过它与绘制直线有关,但是有一种圆形算法。

不管我们使用它还是继续进行Trig计算(如今这些速度都非常快),我们只需要绘制圆的1/8. 通过交换x,y,我们可以得到另一个1/8,然后x,y,交换和未交换的负数都可以为圆的其余部分提供点。加速8倍!

改变:

Math.PI * i / steps

到:

2*Math.PI * i / steps

一个完整的圆圈是2pi弧度,而我们只打算使用pi弧度。