计算圆周点

Calculating points around circle

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

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

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.

这是高中三角学。大圆心(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 的快速破解。对不起,原文中 post 我说的是 arcsin 时说的是 arccos。

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);
   }
}

这是它绘制的内容: