javascript - 我如何获得每个矩形的坐标?

标签 javascript math canvas html5-canvas geometry

enter image description here 我已经尝试过这个,

  public drawNumbers(ctx, x1, y1, length, count) {
      let angle = 0;
      for (let i = 0; i <= count; i++ ) {
        angle += 2 * Math.PI / (count );
      const x2 = x1 + length * Math.cos(angle),
        y2 = y1 + length * Math.sin(angle);
       ctx.beginPath();
       ctx.fillRect(x2, y2, 10, 20);
       ctx.stroke();

    }
  }

    this.canvas.drawNumbers(ctx, this.midX, this.midY, 160, 60);

输出:

enter image description here

预期结果:

我想计算旋转轴的四个坐标(矩形)。

如何检测每个矩形上的点击事件?

enter image description here

最佳答案

使用setTransform

白柳的答案是一个解决方案,尽管步骤太多。

可以使用 setTransform 在一次转换中完成此操作,并一步应用平移和旋转。另外,第二个平移是相对于其原点绘制框的位置。使用变换时,始终围绕旋转中心绘制对象。

 ctx.strokeRect(-10,-10,20,20); // rotation is always around 0,0

const ctx = canvas.getContext("2d");
const centerX = 250;
const centerY = 250;
const radius = 200;
const boxWidth = 10;
const bobLength = 20;

// draw boxs around circle center at cx,cy and radius rad
// box width bw, and box height bh
// spacing optional is the distance between boxes
function drawCircleOfBoxes(cx,cy,rad,bw,bh,spacing = 5){
  var steps = ((rad - bw /2) * Math.PI * 2) / (bw + spacing) | 0; // get number boxes that will fit circle
  ctx.beginPath();
  for(var i = 0; i < steps; i ++){
      const ang = (i / steps) * Math.PI * 2;
      var xAxisX = Math.cos(ang);  // get the direction of he xAxis
      var xAxisY = Math.sin(ang);
      // set the transform to circle center x Axis out towards box
      // y axis at 90 deg to x axis
      ctx.setTransform(xAxisX, xAxisY, -xAxisY, xAxisX, cx, cy);
      // draw box offset from the center so its center is distance radius
      ctx.rect(rad - bh / 2, -bw / 2, bh, bw);
  }
  ctx.fill(); 
  ctx.stroke();
  ctx.setTransform(1,0,0,1,0,0); // reset transform
}

ctx.fillStyle = "#FCD";
ctx.strokeStyle = "#000";
drawCircleOfBoxes(centerX, centerY, radius, boxWidth, bobLength);
<canvas id="canvas" width="500" height="500"></canvas>

手动将变换应用于点

如果您希望在代码中变换框,您可以使用上面应用的变换并将其直接应用于一组点。您无法将其应用于需要 API 转换的 ctx.rect 函数。

要变换点pxpy,您需要旋转x轴的方向

const xAx = Math.cos(dirOfXAxis);
const xAy = Math.sin(dirOfXAxis);

然后,您可以沿 x 轴移动点 px 距离,然后旋转 90 度并沿 y 轴移动 py 距离

var x = px * xAx;  // move px dist along x axis
var y = px * xAy;

x += py * -xAy;  // move px dist along y axis
y += py * xAx;

然后只需添加翻译

x += translateX;
y += translateY;

或者一次性完成

var x = px * xAx - py * xAy + translateX;  // move px dist along x axis
var y = px * xAy + py * xAx + translateY;

该代码片段显示了它的实际效果

const ctx = canvas.getContext("2d");
const centerX = 250;
const centerY = 250;
const radius = 200;
const boxWidth = 10;
const boxLength = 20;


// draw boxs around circle center at cx,cy and radius rad
// box width bw, and box height bh
// spacing optional is the distance between boxes
function drawCircleOfBoxes(cx,cy,rad,bw,bh,spacing = 5){
  var points = [  // setout points of box with coord (0,0) as center
    {x : bh / 2, y :  -bw / 2},
    {x : bh / 2 + bh, y :  -bw / 2},
    {x : bh / 2 + bh, y :  -bw / 2 + bw},
    {x : bh / 2, y :  -bw / 2 + bw},
  ];
  var steps = (((rad - bw /2) * Math.PI * 2) / (bw + spacing) )+ 4| 0; // get number boxes that will fit circle
  ctx.beginPath();
  for(var i = 0; i < steps; i ++){
      const ang = (i / steps) * Math.PI * 2;
      const xAx = Math.cos(ang);  // get the direction of he xAxis
      const xAy = Math.sin(ang);
      var first = true
      for(const p of points){ // for each point
          // Apply the transform to the point after moving it
          // to the circle (the p.x + rad)
          const x = (p.x + rad) * xAx - p.y * xAy + cx;
          const y = (p.x + rad) * xAy + p.y * xAx + cy;
          if(first){
             ctx.moveTo(x,y);
             first = false;
          }else{
             ctx.lineTo(x,y);
          }
      }
      ctx.closePath();
  }

  ctx.fill(); 
  ctx.stroke();

}


ctx.fillStyle = "#CFD";
ctx.strokeStyle = "#000";

for(var i = boxLength + 5; i < radius; i += boxLength + 5){
    drawCircleOfBoxes(centerX, centerY, i , boxWidth, boxLength);
}
<canvas id="canvas" width="500" height="500"></canvas>

关于javascript - 我如何获得每个矩形的坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48215539/

相关文章:

JavaScript 匿名函数数组到 Java 的翻译

javascript - 如何使用 javascript 将任何手机号码包装到 anchor 标记中

html - 高分辨率 Canvas 页面缩放到窗口高度

javascript - CamanJS - 移动 - 空白 Canvas

javascript - 使用 Jasmine Sequelize TypeError 进行测试 : _models2. default.count 不是函数

Javascript unescape() 与 Python urllib.unquote()

c++ - 求已知边的多边形面积 [C++]

javascript - 计算 d3 路径中的弧/点

python - 如何对类中的多个方法设置偏差?

javascript - 使用 JavaScript 的 Canvas 动画。每次启动时的随机坐标和速度