【问题标题】:JS: Calculate midpoints of lines recursivelyJS:递归计算线的中点
【发布时间】:2017-06-20 07:02:42
【问题描述】:

我正在用 JS 编写一个使用坐标的简单绘图应用程序。我需要递归地找到两点的中点以绘制一条线(点 A 和 B 之间的中点,然后是三个结果点之间的两个中点,依此类推)。请参阅this GIF 以获得更清晰的示例。

这是一个基于网格/坐标的绘图应用程序,因此无法简单地绘制一条线。需要获取所有点之间的坐标。

我有一个查找中点的函数

function findMidpoint(p1,p2){
    return Math.floor((p1+p2)/2);
}

还有一个绘制点的函数(我还将以前的点存储为 prevX 和 prevY

setPoint(X,Y);

所以我画中点的方法如下:

setPoint(findMidpoint(X,prevX),findMidpoint(Y,prevY));

下一组中点:

setPoint(findMidpoint(findMidpoint(X,prevX),prevX),findMidpoint(findMidpoint(Y,prevY),prevY));
setPoint(findMidpoint(X,findMidpoint(X,prevX)),findMidpoint(Y,findMidpoint(Y,prevY));

如您所见,这很快就会变得一团糟。我想有一种递归方式可以做到这一点,或者某种方式可以循环给定次数,但我似乎无法弄清楚。任何帮助将不胜感激!

【问题讨论】:

  • 你得到的是一条线。为什么需要积分?您需要指定中点动作应该停止的结束条件。
  • 这是一个基于网格/坐标的绘图应用程序,因此无法简单地画一条线。有必要获取点之间的所有坐标。我遇到的问题是创建中点操作,因此不必手动完成。

标签: javascript coordinates draw


【解决方案1】:

您可以计算中点并仅在中点与左点或右点之一不同时调用recusion。

function midpoint(a, b) {
    return Math.floor((a + b) / 2);
}

function drawPoints(p0, p1) {
    var middle = [midpoint(p0[0], p1[0]), midpoint(p0[1], p1[1])];
    ctx.beginPath();
    ctx.fillRect(middle[0], middle[1], 1, 1);
    ctx.closePath();
    if ((p0[0] !== middle[0] || p0[1] !== middle[1]) && (p1[0] !== middle[0] || p1[1] !== middle[1])) {
        drawPoints(p0, middle);
        drawPoints(middle, p1);
    }
}

var ctx = document.getElementById("canvas").getContext("2d");

drawPoints([0,0], [600, 20]);
<canvas id="canvas" style="border-width: 0; display: block; padding: 0; margin: 0;" width="600" height="200"></canvas>

【讨论】:

    【解决方案2】:
                var points = [];
                function findMid(x,y){ 
                    var mid  = parseInt((x+y)/2);
                    if(x!=mid && y!=mid){
                        points.push(mid);
                        console.log("x:"+x+" y:"+y+" mid:"+mid);
                        findMid(x,mid);
                        findMid(y,mid);
                  }     
                }
                initialPointX = 4;
                initialPointY = 10;
                console.log(findMid(initialPointX,initialPointY));
    

    【讨论】:

      【解决方案3】:

      每个递归的递归函数应该

      1. 创建 A 和 B 之间的中点,比如 C
      2. 在 (A, C) 和 (B, C) 上调用自己
      3. 如果 A == B 或 A 非常接近 B,则停止

      在代码中是这样的:

      function placeMidPoint(Ax, Ay, Bx, By) {
        var e = 0; // some small number, if e==0 then you're stopping when A==B
        if( (Ax - Bx) < e && (Ay - By) < e )
          return;
        var Cx = findMidpoint(Ax, Bx);
        var Cy = findMidpoint(Ay, By);
        setPoint(Cx, Cy);
      
        placeMidPoint(Ax, Ay, Cx, Cy);
        placeMidPoint(Cx, Cy, Bx, By);
      }
      

      【讨论】:

        猜你喜欢
        • 2020-02-21
        • 1970-01-01
        • 1970-01-01
        • 2021-08-15
        • 2015-08-31
        • 2019-09-03
        • 2017-08-22
        • 1970-01-01
        • 2020-09-30
        相关资源
        最近更新 更多