【问题标题】:Find angle of point on circle求圆上点的角度
【发布时间】:2019-11-15 20:08:02
【问题描述】:

假设我在屏幕上绘制了一个中心坐标为 (cx,cy) 的圆,并在圆上选择了一个随机点 (A)。

通过A点的坐标,我需要找到(a)的角度。

更新:

我尝试过使用以下公式:

Math.toDegrees(Math.asin(((x - cx) / radius).toDouble()))

这实际上是相反的(圆是通过给这个圆提供角度来创建的):

x = radius * Math.sin(Math.toRadians(angle.toDouble())) + cx
y = radius * Math.cos(Math.toRadians(angle.toDouble())) + cy

但由于公式中不存在 y 坐标,因此答案可能是错误的。

【问题讨论】:

  • 参见java.lang.Math 包文档。你试过^F angle吗?
  • 在我的几何课中,圆的东边是零度

标签: java android math trigonometry


【解决方案1】:

如果你知道点A(x,y)的笛卡尔坐标,那么你可以通过将其转换为极坐标来找到角度theta,如下所示:

double theta = Math.toDegrees(Math.atan2(y - cy, x - cx));

如果您的 X 轴为 0 度,则此公式有效,否则您需要考虑偏移量。

【讨论】:

  • 谢谢,但这里的问题是这个公式不能正确区分象限。这个公式总是返回一个从 0 到 180 的角度。
  • 您可以使用 CAST 规则计算出角度,例如。如果 x 和 y 均为正,则角度相同,如果 x 和 y 均为负,则角度为 theta+180
  • @HamedMomeni 那么您检查了Math 包文档吗? “此方法通过计算 -pi 到 pi 范围内 y/x 的反正切来计算相位 theta”
  • @pskink 你是对的。 System.out.println(Math.toDegrees(Math.atan2(2,2))); 打印 45 而System.out.println(Math.toDegrees(Math.atan2(-2,-2))); 打印 -135。
【解决方案2】:

我认为您正在寻找的方法是 Math.atan2,它计算与 x 和 y 坐标的角度。我现在修改了代码以调整向下 0 度。我还翻转了y轴,把0、0坐标放在左上角(屏幕坐标),把180以上的度数调整为负度数:

public double theta(int cx, int cy, int x, int y)
{
    double angle = Math.toDegrees(Math.atan2(cy - y, x - cx)) + 90;
    return angle <= 180? angle: angle - 360;
}

验证某些角度的小测试...

@Test
public void test()
{
    assertThat(theta(50, 50, 60, 50), is(90.0));
    assertThat(theta(50, 50, 50, 60), is(0.0));
    assertThat(theta(50, 50, 40, 50), is(-90.0));
    assertThat(theta(50, 50, 50, 40), is(180.0));
}

【讨论】:

  • 正确答案但是......方向相反,起点被 pi / 2 偏移 - 所以我不认为 OP 接受它,因为他想要鱼,而不是鱼竿
【解决方案3】:

我相信,您可以找到切角并将该角度添加到 90 或从 270 开始的子结构并找到结果。我像您的图纸一样设计代码。我猜你可以让它更通用。 您有 4 个区域:

  1. 0度到90度
  2. 90度到180度
  3. 90 度到 -90(270) 度
  4. -90(270) 度到 0(360) 度

代码:

public static double findAngle(double x,  double y,
                               double cx, double cy, double radius){
    double beta, alfa;

    double distanceX = Math.abs(Math.abs(x) - Math.abs(cx));
    double distanceY = Math.abs(Math.abs(y) - Math.abs(cy));

    // check the point is on the circle or not
    // with euchlid
    if (radius != Math.sqrt(x * x + y * y)) {
        return -1;
    }

    if (x >= cx && y <= cy) {
        // find tangent
        beta = Math.atan(distanceY / distanceX);
        alfa = 90 - beta;
        return alfa;
    }
    // 90-180 -> second area
    else if (x >= cx && y >= cy) {
        beta = Math.atan(distanceY / distanceX);
        alfa = 90 + beta;
        return alfa;
    }
    // 180 - -90 -> third area
    else if (x <= cx && y >= cy) {
        beta = Math.atan(distanceY / distanceX);
        alfa = 270 - beta;
        return alfa;
    }
    // -90 - 0 -> forth area
    else if (x <= cx && y <= cy) {
        beta = Math.atan(distanceY / distanceX);
        alfa = 270 + beta;
        if (alfa == 360) {
            alfa = 0;
        }
        return alfa;    
    } 
    else {
        return -1;
    }
}

【讨论】:

    【解决方案4】:

    Atan2 的主要捕获点是中心点。如果您的中心偏移(Cx, Cy) 而不是原点,并且您想找到(X1, Y1)(X2, Y2) 之间的弧角,那么我建议采用这种方法:

    double startAngle = Math.Atan2(Y1-Cy, X1-Cx);
    double endAngle = Math.Atan2(Y2-Cy, X2-Cx);
    double ArcAngle = endangle - startAngle;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多