【问题标题】:Calculating points around circle围绕圆计算点
【发布时间】:2018-10-05 19:57:04
【问题描述】:

如图所示,我有一个大圆圈和几个小圆圈

首先我像这样画中间的小圆圈:

cxSmallMiddle = cxBig + radiusBig + hDist + radiusSmall;
sySmallMiddle = radiusBig;

cxBig 是大圆的中心。 hDist 是我希望每个小圆圈到大圆圈的距离。

所以现在中间小圆的中点与大圆的中点平行。

现在我想用大圆的hDist和中间小圆的vDist(垂直距离)绘制下一个小圆。

这样hDistvDist 将相应地控制小圆圈与大圆圈的距离以及小圆圈之间的间隙。

如何找到其他按钮的 cx 和 cy?

这是手绘完成版

编辑:添加了@Gene建议的代码

@Override
public void onDraw(Canvas canvas) {

    float radiusBig = 110f * singleDp;
    float cxBig = screenWidth / 2f;
    //float cyBig = screenHeight / 2f;
    float cyBig = radiusBig + strokeWidth + (20*singleDp);

    canvas.drawCircle(cxBig, cyBig, radiusBig, paint);

    float radiusSmall = 20 * singleDp;
    float vDist = 0 * singleDp;
    float hDist = 0 * singleDp;
    float acPoint = radiusBig;
    float bcPoint = radiusSmall + vDist;

    float theta = (float) Math.acos(bcPoint / acPoint);

    int i = 0;
    double x_i = acPoint * Math.cos(i * theta) + cxBig;
    double y_i = acPoint * Math.sin(i * theta) + cyBig;
    canvas.drawCircle((float) x_i, (float) y_i, radiusSmall, paint);

    i = 1;
    x_i = acPoint * Math.cos(i * theta) + cxBig;
    y_i = acPoint * Math.sin(i * theta) + cyBig;
    canvas.drawCircle((float) x_i, (float) y_i, radiusSmall, paint);

}

我用这段代码做了很多实验,这就是我得到的。当我画i=0 时,距离i=0 几乎是 45 度。在试验时,我发现如果我指定vDist = 80;然后看起来没问题。 vDist 越大,越接近i=0

【问题讨论】:

  • 那么距离就是各个圆的切线之间的距离?您是否有理由不只是想做一些极坐标逻辑,即给出一系列角度和与大圆中心的距离?然后每一个小圆圈都将均匀分布,并且都与大圆圈的中心等距。我假设您想在较大的圆圈周围绘制几个较小的圆圈,也许这是不对的
  • 我将在大圆圈的左右两侧绘制 5 个圆圈。是的,切线。我不想做角度,因为距离可以改变,大小圆的大小也可以改变,小圆之间的间隙也可以改变。我还添加了一张照片@MattMessersmith

标签: algorithm math trigonometry


【解决方案1】:

这是高中三角学。由大圆心(A)、小圆心(C)和小圆心正下方水平半径上的点(B)组成一个直角三角形。

边BC的长度是vDist + 2 * radiusSmall。 AC的长度为radiusBig

设 \theta 为角 BAC。那么

sin(\theta) = BC / AC = (vDist + 2 * radiusSmall) / radiusBig.

所以你可以确定 \theta:

\theta = arcsin((vDist + radiusSmall) / radiusBig)

一旦你有了\theta,圆圈的位置就在原点

x_i = radiusBig * cos(i * \theta)
y_i = radiusBig * sin(i * \theta)

对于 i = 0, +1, -1, +2, -2, ...

编辑

好的,这里是 Java Swing 的一个快速 hack。抱歉,在原帖中我说的是 arccos,而我的意思是 arcsin。

import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Circles extends JPanel {
   public static void main(String[] a) {
      JFrame f = new JFrame();
      f.setSize(800, 800);
      f.add(new Circles());
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setVisible(true);
   }

   @Override
   public void paint(Graphics g) {
     int cx = 400, cy = 400, rBig = 200, rSmall = 40, hDist = 20, vDist = 10;
     drawCircle(g, cx, cy, rBig);  // Big circle.
     int rSmallCircleCenters = rBig + hDist + rSmall;
     double theta = Math.asin(((double) vDist + 2 * rSmall) / rSmallCircleCenters);
     int nPairs = 3;
     for (int i = 1 - nPairs; i < nPairs; ++i) {
       int dx = (int) (rSmallCircleCenters * Math.cos(i * theta));
       int dy = (int) (rSmallCircleCenters * Math.sin(i * theta));
       drawCircle(g, cx + dx, cy + dy, rSmall);
       drawCircle(g, cx - dx, cy - dy, rSmall);
     }
   }

   private void drawCircle(Graphics g, int cx, int cy, int r) {
     g.drawOval(cx - r, cy - r, 2 * r, 2 * r);
   }
}

它是这样画的:

【讨论】:

  • 讨厌成为那个人,但实施后它在所有地方都被取代了。 i=0 应该放在哪里? B点?
  • @AkakiGabisonia 您需要阅读 SO 帮助,了解如何通过最少完整的可验证示例提出问题。如果您在问题中添加了不起作用的代码,我们都可以查看它。
  • 我用代码更新了我的问题。在发布之前我对数字进行了很多实验
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多