Это тригонометрия средней школы.Прямой треугольник, образованный центром большого круга (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, ...
Edit
Хорошо, вот быстрый взлом в Java Swing.Извините, в оригинальном посте я сказал 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);
}
}
Вот что он рисует: