【问题标题】:How to calculate angle of rectangle using corner position?如何使用角位置计算矩形的角度?
【发布时间】:2017-11-19 11:28:29
【问题描述】:

我有一个这样的矩形......

...而且我也知道矩形的角位置,如下面的数组:

var corners = [[107, 0], [0, 21], [111, 24], [4, 45]]

因为我需要计算矩形的角度,就像我在上图中用符号表示的那样,所以我的想法是只使用以下代码:

var rectangle_angle = ((180/Math.PI) * Math.atan((a[1] - b[1]) / (a[0] - b[0]))).toFixed(2)
console.log('angle : ' + rectangle_angle)

在上面的例子中,我使用前两个角点来计算角度:

var a = corners[0], b = corners[1]

但是例如我正在使用如下所示的矩形并尝试计算矩形的角度...

(角落:[[101, 0], [110, 22], [0, 38], [9, 60]]

...但是我得到的结果是这个->angle : 67.75,绝对不是正确的旋转角度。

之后我只使用corner[0]corner[2] 进行计算而不是使用corner[0]corner[1] 来解决问题。

所以我现在得到的结果是-20.62°。好多了。


现在我的问题是:如何从我必须用于计算的角数组中提取正确的点?

你可以在这里试试这个功能:

var corners = [[107, 0], [0, 21], [111, 24], [4, 45]]

var a = corners[0], b = corners[1]
var rectangle_angle = ((180/Math.PI) * Math.atan((a[1] - b[1]) / (a[0] - b[0]))).toFixed(2)
console.log('angle : ' + rectangle_angle)

【问题讨论】:

  • 兄弟,请阅读这个问题,我不是在寻找角落,而是在计算矩形@JonasW 的角度。
  • Now my question: How can I extract the right corner positions that I have to use for my calculation? 但问题在于找到正确的角。
  • ...and I also know the rectangles corner positions... 试图找到角度,是的!
  • 你总是把X轴放在相反的方向吗?令人困惑。
  • 你是指我图片中的 Y 轴吗? - 好吧..因为我真的无法得到你的评论:(@trincot

标签: javascript jquery math angle rectangles


【解决方案1】:

过滤corners,这样你就可以得到角a和b:

const corners = [[107, 0], [0, 21], [111, 24], [4, 45]]

const cornerA = corners.filter(x => x[1] == 0).reduce((a, b) => a.concat(b))
const cornerB = corners.filter(y => y[0] == 0).reduce((a, b) => a.concat(b))

const rectangleAngle = ((180/Math.PI) * Math.atan((cornerA[1] - cornerB[1]) / (cornerA[0] - cornerB[0]))).toFixed(2)

console.log(rectangleAngle)

【讨论】:

  • 嘿约翰,看起来是一个很好的解决方案,但我在这个角落位置遇到了问题[[10, 0], [0, 1], [108, 27], [82, 27]]。 (在这种情况下,矩形顺时针旋转!)
  • 你可能想交换cornerA和cornerB
【解决方案2】:

如何从我必须用于计算的角数组中提取正确的点?

您计算的一个角落是您的 x 值为 0。因此您需要搜索 x = 0 值:

var a;
$.each(corners, function(i, corner) {
    if (corner[0] === 0) {
        // you have found your a corner (corners[i])
        a = corner;
    }
});

计算的 b 角是 y 值为 0 的位置:

var b;
$.each(corners, function(i, corner) {
    if (corner[1] === 0) {
        // you have found your b corner (corners[i])
        b = corner;
    }
});

但是你的计算需要固定如下:

var rectangle_angle = ((180/Math.PI) * Math.atan((a[1] - b[1]) / (b[0] - a[0]))).toFixed(2)

【讨论】:

  • 也不适用于顺时针旋转的矩形 - [[10, 0], [0, 1], [108, 27], [82, 27]]
【解决方案3】:

你得到意想不到的角度的原因是你的两个矩形的角以不同的顺序定义。

第一个将其下边的两个端点作为前两个角,而第二个将短 侧面。从图片可以看出,短边确实有一个更陡的角度。

正如您所指出的,您不能影响矩形定义中点的顺序,您可以按如下方式进行:

  • 通过增加 Y 坐标对角进行排序:第一个角将是底角,接下来的两个角将是底角的​​边缘点
  • 在这两条边中,选择最长的一条
  • 根据该边执行角度计算

您可以使用以下代码来实现这一目标:

function rectangleTilt(rect) {
    const distance2 = (a, b) => (a[0]-b[0])**2 + (a[1]-b[1])**2,
        angle = (a, b) => 180 - Math.atan2(b[1]-a[1], b[0]-a[0]) * 180 / Math.PI,
        // Sort the corners by increasing Y coordinate:
        [a, b, c] = rect.slice().sort( (a, b) => a[1] - b[1] );
    // Return the angle of the longest edge having the lowest corner:
    return distance2(a, b) < distance2(a, c) ? angle(a, c) : angle(a, b);
}

function drawRectangle(ctx, rect) {
    const [a, b, c, d] = rect.slice().sort( (a, b) => a[1] - b[1] );
    ctx.moveTo(a[0], a[1]);
    ctx.lineTo(b[0], b[1]);
    ctx.lineTo(d[0], d[1]);
    ctx.lineTo(c[0], c[1]);
    ctx.lineTo(a[0], a[1]);
    ctx.stroke(); 
}

const ctx = canvas.getContext("2d");
// Make Y axis go upwards, and X axis backwards
ctx.transform(-1, 0, 0, -1, canvas.width, canvas.height);

var rect = [[101, 0], [110, 22], [0, 38], [9, 60]];
drawRectangle(ctx, rect);
console.log(rectangleTilt(rect).toFixed(2) + "°");
&lt;canvas id="canvas" width="200"&gt;&lt;/canvas&gt;

【讨论】:

  • 我完全知道我的矩形具有不同的角特征,但我无法定义我的矩形,因为我得到了这个矩形的角点,我已经在上面提到过,我现在想知道哪个我必须在计算中使用它们!
  • 我添加了一个算法(和 sn-p),用于找到与底角相连的最长边,并对其进行角度计算。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多