Android: 如何在两点之间绘制圆形?

4

这是我的当前代码

Path path_eclipse = new Path();
float radius = (float) (Math.sqrt(Math.pow(r.stopX - r.startX, 2.0f) + Math.pow(r.stopY - r.startY, 2.0f)) / 2.0f);
path_eclipse.addCircle(r.startX, r.startY, radius, Path.Direction.CCW);
canvas.drawPath(path_eclipse, paint);

使用这段代码,我得到的输出如下:

enter image description here

但我想画出像这样的圆形:

enter image description here

更新后的源代码:这段源代码在我的情况下有效 [已解决]
[OnDraw]
@Override
protected void onDraw(Canvas canvas) {
        Path path_eclipse = new Path();
        float centerX = (r.startX + r.stopX) /2;
        float centerY = (r.startY + r.stopY) /2;
        float radius = (float)Math.sqrt((r.stopX - r.startX)*(r.stopX - r.startX)+(r.stopY - r.startY)*(r.stopY - r.startY));
        path_eclipse.addCircle(centerX, centerY, radius/2, Path.Direction.CCW);
        canvas.drawPath(path_eclipse,paint);
}

[OnTouchEvent]

@Override
public boolean onTouchEvent(MotionEvent event) {
        float eventX = event.getX();
        float eventY = event.getY();
        switch (event.getAction()) {
               case MotionEvent.ACTION_DOWN:
                    startX = eventX;
                    startY = eventY;
                    return true;
               case MotionEvent.ACTION_MOVE:
                    stopX = eventX;
                    stopY = eventY;
                    break;
               case MotionEvent.ACTION_UP:
                    stopX = eventX;
                    stopY = eventY;
                    break;
               default:
                    return false;
        }
        invalidate();
        return true;
}

将您的半径除以2,中心点是两个点之间的直线中点。 - Vladyslav Matviienko
这两个是完全相反的吗?还是它们只是圆上的两个点? - Dan
你好,这是从onTouch事件获取的两个点。 - Nicky
我想要的是你最初得到的第一个输出,而你的问题幸运地成为了我的答案 :D 谢谢 <3 - Abu bakar
4个回答

1
addCircle的前两个参数是圆心的x和y坐标。假设A和B是你想要的圆上彼此之间最远的距离,那么圆心应该是两者等距离的点,因此:
float centerX = (pointA.x + pointB.x) /2
float centerY = (pointA.y + pointB.y) /2 

你的半径应该是A和B之间的距离,因此:

float radius = (Math.sqrt(Math.pow(x2−x1, 2) + Math.pow(y2−y1, 2))) / 2

除非我知道rr.startXr.startY是什么,否则这就是我能说的。 - Mehmet K
你好,我添加了更多的源代码,已经尝试了你的解决方案,但是x,y坐标是错误的。 path_eclipse.addCircle(centerX, centerY, radius, Path.Direction.CCW); 这是结果:https://youtu.be/tT4RlQ_XWGc 谢谢。 - Nicky
1
但是Math.pow()需要2个参数?我认为您缺少了指数参数。 - Kes Walker

1
中点
 int mx=(r.stopX + r.startX)/2;
 int my= (r.stopy+r.startY)/2;

半径

float radius = Math.sqrt(Math.pow(r.stopX - my, 2)
        + Math.pow(r.stopY - my, 2));

编辑

我使用了以下代码

public class CustomView extends View {
  private Paint paint;
  private Circle circle;
  private List<Point> points;
  public final int CIRCLE_BETWEEN_TWO_POINTS = 1;
  private int viewType;

  {
    paint = new Paint();
    points = new ArrayList<>();
  }

  public CustomView(Context context) {
    super(context);
  }

  public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    switch (viewType) {
      case CIRCLE_BETWEEN_TWO_POINTS:
        drawView(canvas);
        break;
    }
  }

  private void drawView(Canvas canvas){
    for(Point point:points){
      drawCircle(canvas,new Circle(point.x,point.y,10),false);
    }
    drawCircle(canvas,circle,true);
  }

  private void drawCircle(Canvas canvas,Circle circle, boolean isStroke){
    paint.reset();
    paint.setAntiAlias(true);
    if(isStroke){
      paint.setStrokeWidth(5);
      paint.setColor(Color.BLACK);
      paint.setStyle(Paint.Style.STROKE);
    }else {
      paint.setColor(Color.RED);
      paint.setStyle(Paint.Style.FILL);
    }

    canvas.drawCircle(circle.getX(), circle.getY(), circle.getRadius(), paint);
  }

  public void drawCircleBetweenTwoPoints(int x1, int y1, int x2, int y2) {
    viewType = CIRCLE_BETWEEN_TWO_POINTS;
    points.clear();
    points.add(new Point(x1, y1));
    points.add(new Point(x2, y2));
    int mx = (x1 + x2) / 2;
    int my = (y1 + y2) / 2;
    double radius = Math.sqrt(Math.pow(x1 - mx, 2)
      + Math.pow(y1 - my, 2));
    circle=new Circle(mx,my,(int)radius);
    invalidate();
  }


} 

并将该方法称为

customView.drawCircleBetweenTwoPoints(500,200,100,600);

And its working for me(它对我有效)。

点击查看输出结果


你好,我按照你的解决方案尝试了,但还是没有生效,我觉得可能是因为这段代码有问题。 path_eclipse.addCircle(mx, my, radius, Path.Direction.CCW); 这是结果:youtu.be/tT4RlQ_XWGc 谢谢。 - Nicky

0
如果您想要画出这样的圆,您必须知道3个点,然后通过半径计算中心。因为两个点不能唯一确定一个圆。您只能找到可能中心的整条线。
另一方面,如果我们认为两个点恰好相对。那么您应该通过中点公式计算中心:
M = [(x1 + x2 / 2), (y1 + y2 / 2)]
接下来,您可以像第一种情况一样做同样的事情。首先,计算半径,然后画圆。

0

假设AB正好相对,由它们定义的线段将通过圆心(C),后者将把AB切成两半。

因此:

你计算两点之间的距离,然后除以二。这样你就得到了半径。

圆的中心将恰好位于这两者之间:x=(x1+x2)/2y=(y1+y2)/2

如果它们只是随机点,你可以使用以下技术之一:

然而,在本案例中,你的问题稍微有点棘手,因为两个点和一个半径无法明确地确定一个圆:这个问题会有两个解。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接