【问题标题】:How to find intersecting point of 2 rectangles?如何找到2个矩形的交点?
【发布时间】:2020-12-04 01:11:51
【问题描述】:

我正在尝试将两个矩形绘制为一个形状,并使用 HTML5 画布包含角度注释。

我想要实现的最终版本是这样的:

如何找到内角的交点以知道在哪里绘制角度注释?

let canvas=document.getElementById("canvas");
let ctx=canvas.getContext("2d");
    
// rectangle dimensions    
let height = 50;
let width = 200;

// starting coordinates
let x = 20;
let y = 20;

// translate to starting coordinates
ctx.translate(x, y);

// draw first rectangle 
ctx.strokeRect(0,0,width,height);

// translate to the end of the first rectangle
ctx.translate(width, 0);

// rotate canvas by 45 degrees
ctx.rotate(45 * Math.PI / 180);

// draw second rectangle
ctx.strokeRect(0,0,width,height);
<!doctype html>
<html>
<head>
<style>
    body{ background-color: rgb(255, 255, 255); }
</style>
</head>
<body>
    <canvas id="canvas" width=700 height=500></canvas>
</body>
</html>

【问题讨论】:

标签: canvas geometry html5-canvas


【解决方案1】:

如果我们看看你的两个重叠的形状,我们可以发现一些有趣的东西:你想知道的点和附近的两个点形成一个三角形。

让我们仔细看看,看看我们真正知道这个三角形的哪些参数:

  • c 边 - 这只是矩形的高度
  • 点 B - 第一个矩形的起点 + 它的宽度
  • 点 A - 第一个矩形的起点 + 它的宽度和高度
  • b 和 c 之间的角度 - 90°
  • c 和 a 之间的角度 - 如您所见,它正好是旋转的一半 (45° / 2 = 22.5°)
  • b 和 a 之间的角度 - 180° (67.5°) 减去前两个角度后的余数

现在我们感兴趣的是point C,它距离point Aside b长度。

根据上面给出的所有信息,我们得出结论,这个三角形是所谓的 ASA 三角形,意思是“角、边、角”——因为我们知道两个角和一个边角度之间。

根据正弦定律,我们可以使用这个方便的公式获得边b:

这是一个交互式示例:

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
   
let height = 50;
let width = 200;

let x = 20;
let y = 20;
let rotation = 45;
let radius = 30;
let angle;
let missingSide;

function draw() {
  document.getElementById("sliderLabel").innerText = "rotation: " + rotation + "°";
  angle = 180 - 90 - rotation / 2;
  missingSide = (height / Math.sin(angle * Math.PI / 180)) * Math.sin((rotation / 2) * Math.PI / 180);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(x + width - missingSide, x + height, radius, 0, 2 * Math.PI, false);
  ctx.stroke();
  ctx.save();
  ctx.fillStyle = 'grey';
  ctx.translate(x, y);
  ctx.fillRect(0, 0, width, height);
  ctx.translate(width, 0);
  ctx.rotate(rotation * Math.PI / 180);
  ctx.fillRect(0, 0, width, height);
  ctx.restore();
}
draw();

document.getElementById("slider").addEventListener("input", function(e) {
  rotation = parseInt(e.target.value);
  draw();
})
<div>
  <input type="range" min="0" max="90" value="45" id="slider">
  <label for="slider" id="sliderLabel">Volume</label>
</div><br>
<canvas id="canvas" width=440 height=250></canvas>

【讨论】:

  • 这是一个很好的解释,非常感谢提供的示例代码。非常感谢。
  • 感谢您的客气话 Niall - 我很高兴能帮上忙! =)
猜你喜欢
  • 2012-11-20
  • 2018-12-20
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2022-01-20
  • 2013-11-14
  • 2020-06-21
  • 2012-06-13
相关资源
最近更新 更多