计算圆点

时间:2018-10-05 19:57:05

标签: algorithm math trigonometry

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

circle demo

首先,我要像这样绘制中间的小圆圈:

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

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

因此,现在小圆环的中间点平行于大圆环。

现在,我想从大圆上绘制hDist,从中小圆上绘制vDist(垂直距离)来绘制下一个小圆。

因此,hDistvDist将控制小圆圈与大圆圈的距离以及小圆圈之间的间距。

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

这是手绘的成品版 finished version

编辑:添加了@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=0i=0之间几乎有45度的距离。在实验时,我发现是否指定了vDist = 80;那看起来还好vDist越大,越接近i=0

1 个答案:

答案 0 :(得分:3)

这是高中三角学。大圆心(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中的快速技巧。抱歉,在我最初的帖子中我说的是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);
   }
}

这是绘制的内容: