javascript - JS在圆上移动一个角度
问题描述
我有程序单击三次,每次单击都会在画布上创建一个点。然后我计算这三个点之间的角度,如下所示:
function find_angle(A, B, C) {
var AB = Math.sqrt(Math.pow(B.x - A.x, 2) + Math.pow(B.y - A.y, 2));
var BC = Math.sqrt(Math.pow(B.x - C.x, 2) + Math.pow(B.y - C.y, 2));
var AC = Math.sqrt(Math.pow(C.x - A.x, 2) + Math.pow(C.y - A.y, 2));
return Math.acos((BC * BC + AB * AB - AC * AC) / (2 * BC * AB));
}
在上面的示例图片中,计算出的角度为 93°。我需要移动point 3
-3°,所以点正好成 90°。我有这个功能:
var angleToCorrect = alpha * (Math.PI / 180) - 90 * (Math.PI / 180);
correct_angle(point2, point3, angleToCorrect)
...
function correct_angle(p2, p3, angle) {
var x = p2.x - p3.x;
var y = p2.y - p3.y;
var r = Math.sqrt(x * x + y * y); //circle radius. origin of the circle is point 2
return {
X: p2.x + (Math.cos(angle) * r),
Y: p2.y + (Math.sin(angle) * r)
};
}
现在,此函数应返回 newx
和y
for point 3
,并将角度校正为 90°。然而坐标不符合我的预期。有人可以指出我做错了什么吗?
解决方案
要计算新位置,仅提供两个点是不够的,因为角度是在三个点之间测量的。
所以在这个函数中,你必须弄清楚点 1 和点 2 之间矢量的当前角度是多少。Javascript为此提供了一个漂亮的内置函数Math.atan2()
现在我们知道了角度(以弧度为单位),我们需要向它添加新的角度。这确保我们可以正确放置第 3 点。
function correct_angle(p1, p2, p3, angle)
{
var currentAngle=Math.atan2(p1.y-p2.y, p1.x-p2.x);
currentAngle+=angle;
var x = p2.x - p3.x;
var y = p2.y - p3.y;
var r = Math.sqrt(x * x + y * y);
return {
X: p2.x + (Math.cos(currentAngle) * r),
Y: p2.y + (Math.sin(currentAngle) * r)
};
}
函数的角度参数应该是以弧度为单位的目标角度(在您的情况下为 90 或 1.5707963267949)
这是一个交互式示例:
Point = function(x, y) {
this.x = x;
this.y = y;
}
var pointA = new Point(162, 39);
var pointB = new Point(105, 161);
var pointC = new Point(211, 242);
var context = document.getElementById("canvas").getContext("2d");
function correct() {
var newPoint = correct_angle(pointA, pointB, pointC, 1.5707963267949);
pointC.x = newPoint.X;
pointC.y = newPoint.Y;
draw();
}
function correct_angle(p1, p2, p3, angle) {
var currentAngle = Math.atan2(p1.y - p2.y, p1.x - p2.x);
currentAngle += angle;
var x = p2.x - p3.x;
var y = p2.y - p3.y;
var r = Math.sqrt(x * x + y * y);
return {
X: p2.x + (Math.cos(currentAngle) * r),
Y: p2.y + (Math.sin(currentAngle) * r)
};
}
function draw() {
context.clearRect(0, 0, 400, 300);
context.fillStyle = "red";
context.beginPath();
context.arc(pointA.x, pointA.y, 10, 0, 2 * Math.PI);
context.fill();
context.beginPath();
context.arc(pointB.x, pointB.y, 10, 0, 2 * Math.PI);
context.fill();
context.beginPath();
context.arc(pointC.x, pointC.y, 10, 0, 2 * Math.PI);
context.fill();
}
draw();
<canvas id="canvas" width="400" height="300" style="background-color:#dddddd;"></canvas>
<button onclick="correct()" style="float:left">
correct me
</button>
推荐阅读
- html - 如何将图标集中在小边框元素内?
- javascript - 承诺 IF 条件始终为假 JavaScript
- android - 使用 Flutter 和 Firebase 时如何更改应用程序 ID?
- python - TypeError: '>' 在 'str' 和 'int' 的实例之间不支持,但我将字符串设为整数
- swift - CryptoKit 加密文件太大而无法存储
- acumatica - 在 SOSshipmentPlan 上覆盖用于 PXProjection 的 BQL
- python - 在 GSI 上使用值列表进行 DynamoDB 查询 - Python
- networking - JADE 使用什么连接协议来通过网络进行代理到代理的连接?
- php - 通过dockerfile在docker容器上安装php imap
- excel - Excel中如何根据其他几个单元格设置一个单元格的值